Skip to content

Commit

Permalink
[Chef] BasicVideoPlayer: Fix MediaInput and MediaPlayback not reporti…
Browse files Browse the repository at this point in the history
…ng attribute changes due to using AttributeAccessInterface (#35122)

* Fix media-input accessinterface

1. SelectInput command won't call reportData since
   MatterReportingAttributeChangeCallback isn't called

2. PW RPC Writing CurrentInput attribute of MediaInput cluster through won't reportData. The
   value is also mismatch with PW RPC Read. (But this is still under WIP
and not working)

* Not writing the MediaInput cluster through RPC

* Remove unused function HandleSetCurrentInput

* Move all attributes logic to Chef application

* Fix typo

* Fix CurrentState(Playback Cluster) not report data

* Restyled by whitespace

* Restyled by clang-format

* Set CurrentState & PlaybackSpeed in MediaPlayback cluster

* Set some attributes to persist (NVM)

* Remove mPlaybackSpeed/mCurrentState/mCurrentInput

* modify playSpeed from 1.0 to 1

* Restyled by clang-format

* Fix type in error messages

* Restyled by clang-format

---------

Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
erwinpan1 and restyled-commits authored Aug 27, 2024
1 parent 82ef12b commit 0944982
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 84 deletions.
51 changes: 39 additions & 12 deletions examples/chef/common/clusters/media-input/MediaInputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,26 @@
* limitations under the License.
*/

#include <app-common/zap-generated/attributes/Accessors.h>
#include <app/util/config.h>
#include <map>

#ifdef MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER
#include "MediaInputManager.h"

using namespace std;
using namespace chip;
using namespace chip::app::Clusters::MediaInput;
using Protocols::InteractionModel::Status;

MediaInputManager::MediaInputManager()
MediaInputManager::MediaInputManager(chip::EndpointId endpoint) : mEndpoint(endpoint)
{
struct InputData inputData1(1, chip::app::Clusters::MediaInput::InputTypeEnum::kHdmi, "HDMI 1",
"High-Definition Multimedia Interface");
struct InputData inputData1(1, InputTypeEnum::kHdmi, "HDMI 1", "High-Definition Multimedia Interface");
mInputs.push_back(inputData1);
struct InputData inputData2(2, chip::app::Clusters::MediaInput::InputTypeEnum::kHdmi, "HDMI 2",
"High-Definition Multimedia Interface");
struct InputData inputData2(2, InputTypeEnum::kHdmi, "HDMI 2", "High-Definition Multimedia Interface");
mInputs.push_back(inputData2);
struct InputData inputData3(3, chip::app::Clusters::MediaInput::InputTypeEnum::kHdmi, "HDMI 3",
"High-Definition Multimedia Interface");
struct InputData inputData3(3, InputTypeEnum::kHdmi, "HDMI 3", "High-Definition Multimedia Interface");
mInputs.push_back(inputData3);

mCurrentInput = 1;
}

CHIP_ERROR MediaInputManager::HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder)
Expand All @@ -51,16 +50,32 @@ CHIP_ERROR MediaInputManager::HandleGetInputList(chip::app::AttributeValueEncode

uint8_t MediaInputManager::HandleGetCurrentInput()
{
return mCurrentInput;
uint8_t currentInput = 1;
Status status = Attributes::CurrentInput::Get(mEndpoint, &currentInput);
if (Status::Success != status)
{
ChipLogError(Zcl, "Unable to get CurrentInput attribute, err:0x%x", to_underlying(status));
}
return currentInput;
}

bool MediaInputManager::HandleSelectInput(const uint8_t index)
{
if (HandleGetCurrentInput() == index)
{
ChipLogProgress(Zcl, "CurrentInput is same as new value: %u", index);
return true;
}
for (auto const & inputData : mInputs)
{
if (inputData.index == index)
{
mCurrentInput = index;
// Sync the CurrentInput to attribute storage while reporting changes
Status status = Attributes::CurrentInput::Set(mEndpoint, index);
if (Status::Success != status)
{
ChipLogError(Zcl, "CurrentInput is not stored successfully, err:0x%x", to_underlying(status));
}
return true;
}
}
Expand All @@ -70,11 +85,12 @@ bool MediaInputManager::HandleSelectInput(const uint8_t index)

bool MediaInputManager::HandleShowInputStatus()
{
uint8_t currentInput = HandleGetCurrentInput();
ChipLogProgress(Zcl, " MediaInputManager::HandleShowInputStatus()");
for (auto const & inputData : mInputs)
{
ChipLogProgress(Zcl, " [%d] type=%d selected=%d name=%s desc=%s", inputData.index,
static_cast<uint16_t>(inputData.inputType), (mCurrentInput == inputData.index ? 1 : 0),
static_cast<uint16_t>(inputData.inputType), (currentInput == inputData.index ? 1 : 0),
inputData.name.c_str(), inputData.description.c_str());
}
return true;
Expand All @@ -99,4 +115,15 @@ bool MediaInputManager::HandleRenameInput(const uint8_t index, const chip::CharS

return false;
}

static std::map<chip::EndpointId, std::unique_ptr<MediaInputManager>> gMediaInputManagerInstance{};

void emberAfMediaInputClusterInitCallback(EndpointId endpoint)
{
ChipLogProgress(Zcl, "TV Linux App: MediaInput::SetDefaultDelegate, endpoint=%x", endpoint);

gMediaInputManagerInstance[endpoint] = std::make_unique<MediaInputManager>(endpoint);

SetDefaultDelegate(endpoint, gMediaInputManagerInstance[endpoint].get());
}
#endif // MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER
4 changes: 2 additions & 2 deletions examples/chef/common/clusters/media-input/MediaInputManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class MediaInputManager : public chip::app::Clusters::MediaInput::Delegate
using InputInfoType = chip::app::Clusters::MediaInput::Structs::InputInfoStruct::Type;

public:
MediaInputManager();
MediaInputManager(chip::EndpointId endpoint);

CHIP_ERROR HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder) override;
uint8_t HandleGetCurrentInput() override;
Expand Down Expand Up @@ -63,7 +63,7 @@ class MediaInputManager : public chip::app::Clusters::MediaInput::Delegate
};

protected:
uint8_t mCurrentInput;
chip::EndpointId mEndpoint;
std::vector<InputData> mInputs;

private:
Expand Down
114 changes: 85 additions & 29 deletions examples/chef/common/clusters/media-playback/MediaPlaybackManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,34 @@
* limitations under the License.
*/

#include <app/util/config.h>
#ifdef MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER
#include "MediaPlaybackManager.h"
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app/util/config.h>

#include <map>
#include <string>
#ifdef MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER
#include "MediaPlaybackManager.h"

using namespace std;
using namespace chip;
using namespace chip::app;
using namespace chip::app::DataModel;
using namespace chip::app::Clusters::MediaPlayback;
using namespace chip::Uint8;

using chip::CharSpan;
using chip::app::AttributeValueEncoder;
using chip::app::CommandResponseHelper;
using chip::Protocols::InteractionModel::Status;

PlaybackStateEnum MediaPlaybackManager::HandleGetCurrentState()
{
return mCurrentState;
PlaybackStateEnum currentState = PlaybackStateEnum::kPlaying;

Status status = Attributes::CurrentState::Get(mEndpoint, &currentState);
if (Status::Success != status)
{
ChipLogError(Zcl, "Unable to get CurrentStage attribute, err:0x%x", to_underlying(status));
}
return currentState;
}

uint64_t MediaPlaybackManager::HandleGetStartTime()
Expand All @@ -54,7 +62,14 @@ CHIP_ERROR MediaPlaybackManager::HandleGetSampledPosition(AttributeValueEncoder

float MediaPlaybackManager::HandleGetPlaybackSpeed()
{
return mPlaybackSpeed;
float playbackSpeed = 1.0;

Status status = Attributes::PlaybackSpeed::Get(mEndpoint, &playbackSpeed);
if (Status::Success != status)
{
ChipLogError(Zcl, "Unable to get PlaybackSpeed attribute, err:0x%x", to_underlying(status));
}
return playbackSpeed;
}

uint64_t MediaPlaybackManager::HandleGetSeekRangeStart()
Expand Down Expand Up @@ -99,10 +114,34 @@ CHIP_ERROR MediaPlaybackManager::HandleGetAvailableTextTracks(AttributeValueEnco
});
}

CHIP_ERROR MediaPlaybackManager::HandleSetCurrentState(PlaybackStateEnum currentState)
{
Status status = Attributes::CurrentState::Set(mEndpoint, currentState);

if (Status::Success != status)
{
ChipLogError(Zcl, "Unable to set CurrentState attribute, 0x%x", to_underlying(status));
}

return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status);
}

CHIP_ERROR MediaPlaybackManager::HandleSetPlaybackSpeed(float playbackSpeed)
{
Status status = Attributes::PlaybackSpeed::Set(mEndpoint, playbackSpeed);

if (Status::Success != status)
{
ChipLogError(Zcl, "Unable to set PlaybackSpeed attribute, 0x%x", to_underlying(status));
}

return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status);
}

void MediaPlaybackManager::HandlePlay(CommandResponseHelper<Commands::PlaybackResponse::Type> & helper)
{
mCurrentState = PlaybackStateEnum::kPlaying;
mPlaybackSpeed = 1;
HandleSetCurrentState(PlaybackStateEnum::kPlaying);
HandleSetPlaybackSpeed(1);

Commands::PlaybackResponse::Type response;
response.data = chip::MakeOptional(CharSpan::fromCharString("data response"));
Expand All @@ -112,8 +151,8 @@ void MediaPlaybackManager::HandlePlay(CommandResponseHelper<Commands::PlaybackRe

void MediaPlaybackManager::HandlePause(CommandResponseHelper<Commands::PlaybackResponse::Type> & helper)
{
mCurrentState = PlaybackStateEnum::kPaused;
mPlaybackSpeed = 0;
HandleSetCurrentState(PlaybackStateEnum::kPaused);
HandleSetPlaybackSpeed(0);

Commands::PlaybackResponse::Type response;
response.data = chip::MakeOptional(CharSpan::fromCharString("data response"));
Expand All @@ -123,8 +162,8 @@ void MediaPlaybackManager::HandlePause(CommandResponseHelper<Commands::PlaybackR

void MediaPlaybackManager::HandleStop(CommandResponseHelper<Commands::PlaybackResponse::Type> & helper)
{
mCurrentState = PlaybackStateEnum::kNotPlaying;
mPlaybackSpeed = 0;
HandleSetCurrentState(PlaybackStateEnum::kNotPlaying);
HandleSetPlaybackSpeed(0);
mPlaybackPosition = { 0, chip::app::DataModel::Nullable<uint64_t>(0) };

Commands::PlaybackResponse::Type response;
Expand All @@ -136,7 +175,9 @@ void MediaPlaybackManager::HandleStop(CommandResponseHelper<Commands::PlaybackRe
void MediaPlaybackManager::HandleFastForward(CommandResponseHelper<Commands::PlaybackResponse::Type> & helper,
const chip::Optional<bool> & audioAdvanceUnmuted)
{
if (mPlaybackSpeed == kPlaybackMaxForwardSpeed)
float playbackSpeed = HandleGetPlaybackSpeed();

if (playbackSpeed == kPlaybackMaxForwardSpeed)
{
// if already at max speed, return error
Commands::PlaybackResponse::Type response;
Expand All @@ -146,13 +187,14 @@ void MediaPlaybackManager::HandleFastForward(CommandResponseHelper<Commands::Pla
return;
}

mCurrentState = PlaybackStateEnum::kPlaying;
mPlaybackSpeed = (mPlaybackSpeed <= 0 ? 1 : mPlaybackSpeed * 2);
if (mPlaybackSpeed > kPlaybackMaxForwardSpeed)
HandleSetCurrentState(PlaybackStateEnum::kPlaying);
// Normalize to correct range
playbackSpeed = (playbackSpeed <= 0 ? 1 : playbackSpeed * 2);
if (playbackSpeed > kPlaybackMaxForwardSpeed)
{
// don't exceed max speed
mPlaybackSpeed = kPlaybackMaxForwardSpeed;
playbackSpeed = kPlaybackMaxForwardSpeed;
}
HandleSetPlaybackSpeed(playbackSpeed);

Commands::PlaybackResponse::Type response;
response.data = chip::MakeOptional(CharSpan::fromCharString("data response"));
Expand All @@ -162,8 +204,8 @@ void MediaPlaybackManager::HandleFastForward(CommandResponseHelper<Commands::Pla

void MediaPlaybackManager::HandlePrevious(CommandResponseHelper<Commands::PlaybackResponse::Type> & helper)
{
mCurrentState = PlaybackStateEnum::kPlaying;
mPlaybackSpeed = 1;
HandleSetCurrentState(PlaybackStateEnum::kPlaying);
HandleSetPlaybackSpeed(1);
mPlaybackPosition = { 0, chip::app::DataModel::Nullable<uint64_t>(0) };

Commands::PlaybackResponse::Type response;
Expand All @@ -175,7 +217,9 @@ void MediaPlaybackManager::HandlePrevious(CommandResponseHelper<Commands::Playba
void MediaPlaybackManager::HandleRewind(CommandResponseHelper<Commands::PlaybackResponse::Type> & helper,
const chip::Optional<bool> & audioAdvanceUnmuted)
{
if (mPlaybackSpeed == kPlaybackMaxRewindSpeed)
float playbackSpeed = HandleGetPlaybackSpeed();

if (playbackSpeed == kPlaybackMaxRewindSpeed)
{
// if already at max speed in reverse, return error
Commands::PlaybackResponse::Type response;
Expand All @@ -185,13 +229,14 @@ void MediaPlaybackManager::HandleRewind(CommandResponseHelper<Commands::Playback
return;
}

mCurrentState = PlaybackStateEnum::kPlaying;
mPlaybackSpeed = (mPlaybackSpeed >= 0 ? -1 : mPlaybackSpeed * 2);
if (mPlaybackSpeed < kPlaybackMaxRewindSpeed)
HandleSetCurrentState(PlaybackStateEnum::kPlaying);
// Normalize to correct range
playbackSpeed = (playbackSpeed >= 0 ? -1 : playbackSpeed * 2);
if (playbackSpeed < kPlaybackMaxRewindSpeed)
{
// don't exceed max rewind speed
mPlaybackSpeed = kPlaybackMaxRewindSpeed;
playbackSpeed = kPlaybackMaxRewindSpeed;
}
HandleSetPlaybackSpeed(playbackSpeed);

Commands::PlaybackResponse::Type response;
response.data = chip::MakeOptional(CharSpan::fromCharString("data response"));
Expand Down Expand Up @@ -249,8 +294,8 @@ void MediaPlaybackManager::HandleSeek(CommandResponseHelper<Commands::PlaybackRe

void MediaPlaybackManager::HandleNext(CommandResponseHelper<Commands::PlaybackResponse::Type> & helper)
{
mCurrentState = PlaybackStateEnum::kPlaying;
mPlaybackSpeed = 1;
HandleSetCurrentState(PlaybackStateEnum::kPlaying);
HandleSetPlaybackSpeed(1);
mPlaybackPosition = { 0, chip::app::DataModel::Nullable<uint64_t>(0) };

Commands::PlaybackResponse::Type response;
Expand Down Expand Up @@ -338,4 +383,15 @@ uint16_t MediaPlaybackManager::GetClusterRevision(chip::EndpointId endpoint)
return clusterRevision;
}

static std::map<chip::EndpointId, std::unique_ptr<MediaPlaybackManager>> gMediaPlaybackManagerInstance{};

void emberAfMediaPlaybackClusterInitCallback(EndpointId endpoint)
{
ChipLogProgress(Zcl, "TV Linux App: MediaPlayback::SetDefaultDelegate, endpoint=%x", endpoint);

gMediaPlaybackManagerInstance[endpoint] = std::make_unique<MediaPlaybackManager>(endpoint);

SetDefaultDelegate(endpoint, gMediaPlaybackManagerInstance[endpoint].get());
}

#endif /// MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate
using Feature = chip::app::Clusters::MediaPlayback::Feature;

public:
MediaPlaybackManager(chip::EndpointId endpoint) : mEndpoint(endpoint){};

chip::app::Clusters::MediaPlayback::PlaybackStateEnum HandleGetCurrentState() override;
uint64_t HandleGetStartTime() override;
uint64_t HandleGetDuration() override;
Expand All @@ -42,6 +44,9 @@ class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate
CHIP_ERROR HandleGetActiveTextTrack(chip::app::AttributeValueEncoder & aEncoder) override;
CHIP_ERROR HandleGetAvailableTextTracks(chip::app::AttributeValueEncoder & aEncoder) override;

CHIP_ERROR HandleSetCurrentState(chip::app::Clusters::MediaPlayback::PlaybackStateEnum currentState);
CHIP_ERROR HandleSetPlaybackSpeed(float playbackSpeed);

void HandlePlay(chip::app::CommandResponseHelper<PlaybackResponseType> & helper) override;
void HandlePause(chip::app::CommandResponseHelper<PlaybackResponseType> & helper) override;
void HandleStop(chip::app::CommandResponseHelper<PlaybackResponseType> & helper) override;
Expand All @@ -66,10 +71,9 @@ class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate
uint16_t GetClusterRevision(chip::EndpointId endpoint) override;

protected:
chip::EndpointId mEndpoint;
// NOTE: it does not make sense to have default state of playing with a speed of 0, but
// the CI test cases expect these values, and need to be fixed.
chip::app::Clusters::MediaPlayback::PlaybackStateEnum mCurrentState =
chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kPlaying;
PlaybackPositionType mPlaybackPosition = { 0, chip::app::DataModel::Nullable<uint64_t>(0) };
TrackType mActiveAudioTrack = { chip::CharSpan("activeAudioTrackId_0", 20),
chip::app::DataModel::Nullable<TrackAttributesType>(
Expand Down Expand Up @@ -101,8 +105,7 @@ class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate
chip::Optional<chip::app::DataModel::Nullable<chip::CharSpan>>(
{ chip::app::DataModel::MakeNullable(chip::CharSpan("displayName2", 12)) }) }) }
};
float mPlaybackSpeed = 1.0;
uint64_t mStartTime = 0;
uint64_t mStartTime = 0;
// Magic number for testing.
uint64_t mDuration = 80000;
bool mAudioAdvanceMuted = false;
Expand Down
Loading

0 comments on commit 0944982

Please sign in to comment.