Skip to content

Commit

Permalink
Adding Media subscriptions support to Linux tv-casting-app
Browse files Browse the repository at this point in the history
  • Loading branch information
sharadb-amazon committed Sep 18, 2022
1 parent 6df6e98 commit e9fa4cc
Show file tree
Hide file tree
Showing 12 changed files with 574 additions and 32 deletions.
62 changes: 59 additions & 3 deletions examples/tv-casting-app/linux/CastingUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ using namespace chip::Dnssd;
// TODO: Accept these values over CLI
const char * kContentUrl = "https://www.test.com/videoid";
const char * kContentDisplayStr = "Test video";
int kInitialContextVal = 121212;

CHIP_ERROR DiscoverCommissioners()
{
Expand Down Expand Up @@ -114,14 +115,69 @@ void LaunchURLResponseCallback(CHIP_ERROR err)
ChipLogProgress(AppServer, "LaunchURLResponseCallback called with %" CHIP_ERROR_FORMAT, err.Format());
}

void OnCurrentStateReadResponseSuccess(
void * context, chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType responseData)
{
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess called");
switch (responseData)
{
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kPlaying:
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Playing");
break;
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kPaused:
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Paused");
break;
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kNotPlaying:
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Not Playing");
break;
case chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kBuffering:
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess CurrentState: Buffering");
break;
default:
ChipLogError(AppServer, "OnCurrentStateReadResponseSuccess Invalid CurrentState!");
break;
}

if (context != nullptr)
{
ChipLogProgress(AppServer, "OnCurrentStateReadResponseSuccess context value: %d", *(static_cast<int *>(context)));
}
}

void OnCurrentStateReadResponseFailure(void * context, CHIP_ERROR err)
{
ChipLogProgress(AppServer, "OnCurrentStateReadResponseFailure called with %" CHIP_ERROR_FORMAT, err.Format());
}

void OnCurrentStateSubscriptionEstablished(void * context)
{
ChipLogProgress(AppServer, "OnCurrentStateSubscriptionEstablished called");
if (context != nullptr)
{
ChipLogProgress(AppServer, "OnCurrentStateSubscriptionEstablished context value: %d", *(static_cast<int *>(context)));
}
}

void HandleCommissioningCompleteCallback(CHIP_ERROR err)
{
ChipLogProgress(AppServer, "HandleCommissioningCompleteCallback called with %" CHIP_ERROR_FORMAT, err.Format());
if (err == CHIP_NO_ERROR)
{
ReturnOnFailure(
CastingServer::GetInstance()->ContentLauncherLaunchURL(kContentUrl, kContentDisplayStr, LaunchURLResponseCallback));
ChipLogProgress(AppServer, "ContentLauncherLaunchURL called successfully");
// Subscribe to a media attribute
err = CastingServer::GetInstance()->MediaPlayback_SubscribeToCurrentState(
static_cast<void *>(&kInitialContextVal), OnCurrentStateReadResponseSuccess, OnCurrentStateReadResponseFailure, 0, 4000,
OnCurrentStateSubscriptionEstablished);
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "MediaPlayback_SubscribeToCurrentState call failed!");
}

// Send a media command
err = CastingServer::GetInstance()->ContentLauncherLaunchURL(kContentUrl, kContentDisplayStr, LaunchURLResponseCallback);
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "ContentLauncherLaunchURL call failed!");
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions examples/tv-casting-app/linux/CastingUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ void HandleCommissioningCompleteCallback(CHIP_ERROR err);

void LaunchURLResponseCallback(CHIP_ERROR err);

void OnCurrentStateReadResponseSuccess(
void * context, chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType responseData);

void OnCurrentStateReadResponseFailure(void * context, CHIP_ERROR err);

void OnCurrentStateSubscriptionEstablished(void * context);

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
void HandleUDCSendExpiration(chip::System::Layer * aSystemLayer, void * context);
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
Expand Down
2 changes: 2 additions & 0 deletions examples/tv-casting-app/tv-casting-common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ chip_data_model("tv-casting-common") {
"include/ContentLauncher.h",
"include/KeypadInput.h",
"include/LevelControl.h",
"include/MediaBase.h",
"include/MediaCommandBase.h",
"include/MediaPlayback.h",
"include/MediaSubscriptionBase.h",
"include/TargetEndpointInfo.h",
"include/TargetNavigator.h",
"include/TargetVideoPlayerInfo.h",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
*/

#include "MediaCommandBase.h"
#include "MediaSubscriptionBase.h"

#include <functional>
#include <zap-generated/CHIPClusters.h>

// COMMAND CLASSES
class LaunchAppCommand
: public MediaCommandBase<chip::app::Clusters::ApplicationLauncher::Commands::LaunchApp::Type,
chip::app::Clusters::ApplicationLauncher::Commands::LauncherResponse::DecodableType>
Expand Down Expand Up @@ -51,3 +53,11 @@ class HideAppCommand : public MediaCommandBase<chip::app::Clusters::ApplicationL
CHIP_ERROR Invoke(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
std::function<void(CHIP_ERROR)> responseCallback);
};

// SUBSCRIBER CLASSES
class CurrentAppSubscriber
: public MediaSubscriptionBase<chip::app::Clusters::ApplicationLauncher::Attributes::CurrentApp::TypeInfo>
{
public:
CurrentAppSubscriber() : MediaSubscriptionBase(chip::app::Clusters::ApplicationLauncher::Id) {}
};
143 changes: 143 additions & 0 deletions examples/tv-casting-app/tv-casting-common/include/CastingServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
#include "TargetNavigator.h"
#include "TargetVideoPlayerInfo.h"

#include <app-common/zap-generated/cluster-objects.h>
#include <app/server/Server.h>
#include <controller/CHIPCommissionableNodeController.h>
#include <functional>
#include <tv-casting-app/zap-generated/CHIPClientCallbacks.h>
#include <zap-generated/CHIPClusters.h>

constexpr chip::System::Clock::Seconds16 kCommissioningWindowTimeout = chip::System::Clock::Seconds16(3 * 60);
Expand Down Expand Up @@ -73,32 +75,156 @@ class CastingServer
chip::FabricIndex CurrentFabricIndex() { return mTargetVideoPlayerInfo.GetFabricIndex(); }
void SetDefaultFabricIndex();

/**
* @brief Content Launcher cluster
*/
CHIP_ERROR ContentLauncher_LaunchURL(
const char * contentUrl, const char * contentDisplayStr,
chip::Optional<chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type> brandingInformation,
std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR ContentLauncher_LaunchContent(chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type search,
bool autoPlay, chip::Optional<chip::CharSpan> data,
std::function<void(CHIP_ERROR)> responseCallback);

/**
* @brief Level Control cluster
*/
CHIP_ERROR LevelControl_Step(chip::app::Clusters::LevelControl::StepMode stepMode, uint8_t stepSize, uint16_t transitionTime,
uint8_t optionMask, uint8_t optionOverride, std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR LevelControl_MoveToLevel(uint8_t level, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride,
std::function<void(CHIP_ERROR)> responseCallback);

CHIP_ERROR
LevelControl_SubscribeToCurrentLevel(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::LevelControl::Attributes::CurrentLevel::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR
LevelControl_SubscribeToMinLevel(void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::LevelControl::Attributes::MinLevel::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR
LevelControl_SubscribeToMaxLevel(void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::LevelControl::Attributes::MaxLevel::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);

/**
* @brief Media Playback cluster
*/
CHIP_ERROR MediaPlayback_Play(std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR MediaPlayback_Pause(std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR MediaPlayback_StopPlayback(std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR MediaPlayback_Next(std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR MediaPlayback_Seek(uint64_t position, std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR MediaPlayback_SkipForward(uint64_t deltaPositionMilliseconds, std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR MediaPlayback_SkipBackward(uint64_t deltaPositionMilliseconds, std::function<void(CHIP_ERROR)> responseCallback);

CHIP_ERROR MediaPlayback_SubscribeToCurrentState(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR
MediaPlayback_SubscribeToStartTime(void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::MediaPlayback::Attributes::StartTime::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR
MediaPlayback_SubscribeToDuration(void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::MediaPlayback::Attributes::Duration::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval,
uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR MediaPlayback_SubscribeToSampledPosition(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::MediaPlayback::Attributes::SampledPosition::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR MediaPlayback_SubscribeToPlaybackSpeed(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR MediaPlayback_SubscribeToSeekRangeEnd(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR MediaPlayback_SubscribeToSeekRangeStart(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::MediaPlayback::Attributes::SeekRangeStart::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);

/**
* @brief Application Launcher cluster
*/
CHIP_ERROR ApplicationLauncher_LaunchApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
chip::Optional<chip::ByteSpan> data, std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR ApplicationLauncher_StopApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
std::function<void(CHIP_ERROR)> responseCallback);
CHIP_ERROR ApplicationLauncher_HideApp(chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application,
std::function<void(CHIP_ERROR)> responseCallback);

CHIP_ERROR
ApplicationLauncher_SubscribeToCurrentApp(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::ApplicationLauncher::Attributes::CurrentApp::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);

/**
* @brief Target Navigator cluster
*/
CHIP_ERROR TargetNavigator_NavigateTarget(const uint8_t target, const chip::Optional<chip::CharSpan> data,
std::function<void(CHIP_ERROR)> responseCallback);

CHIP_ERROR TargetNavigator_SubscribeToTargetList(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::TargetNavigator::Attributes::TargetList::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);
CHIP_ERROR TargetNavigator_SubscribeToCurrentTarget(
void * context,
chip::Controller::ReadResponseSuccessCallback<
chip::app::Clusters::TargetNavigator::Attributes::CurrentTarget::TypeInfo::DecodableArgType>
successFn,
chip::Controller::ReadResponseFailureCallback failureFn, uint16_t minInterval, uint16_t maxInterval,
chip::Controller::SubscriptionEstablishedCallback onSubscriptionEstablished);

/**
* @brief Keypad Input cluster
*/
CHIP_ERROR KeypadInput_SendKey(const chip::app::Clusters::KeypadInput::CecKeyCode keyCode,
std::function<void(CHIP_ERROR)> responseCallback);

Expand Down Expand Up @@ -127,6 +253,10 @@ class CastingServer
StepCommand mStepCommand;
MoveToLevelCommand mMoveToLevelCommand;

CurrentLevelSubscriber mCurrentLevelSubscriber;
MinLevelSubscriber mMinLevelSubscriber;
MaxLevelSubscriber mMaxLevelSubscriber;

/**
* @brief Media Playback cluster
*/
Expand All @@ -138,18 +268,31 @@ class CastingServer
SkipForwardCommand mSkipForwardCommand;
SkipBackwardCommand mSkipBackwardCommand;

CurrentStateSubscriber mCurrentStateSubscriber;
StartTimeSubscriber mStartTimeSubscriber;
DurationSubscriber mDurationSubscriber;
SampledPositionSubscriber mSampledPositionSubscriber;
PlaybackSpeedSubscriber mPlaybackSpeedSubscriber;
SeekRangeEndSubscriber mSeekRangeEndSubscriber;
SeekRangeStartSubscriber mSeekRangeStartSubscriber;

/**
* @brief Application Launcher cluster
*/
LaunchAppCommand mLaunchAppCommand;
StopAppCommand mStopAppCommand;
HideAppCommand mHideAppCommand;

CurrentAppSubscriber mCurrentAppSubscriber;

/**
* @brief Target Navigator cluster
*/
NavigateTargetCommand mNavigateTargetCommand;

TargetListSubscriber mTargetListSubscriber;
CurrentTargetSubscriber mCurrentTargetSubscriber;

/**
* @brief Keypad Input cluster
*/
Expand Down
21 changes: 21 additions & 0 deletions examples/tv-casting-app/tv-casting-common/include/LevelControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
*/

#include "MediaCommandBase.h"
#include "MediaSubscriptionBase.h"

#include <functional>
#include <zap-generated/CHIPClusters.h>

// COMMAND CLASSES
class StepCommand
: public MediaCommandBase<chip::app::Clusters::LevelControl::Commands::Step::Type, chip::app::DataModel::NullObjectType>
{
Expand All @@ -41,3 +43,22 @@ class MoveToLevelCommand
CHIP_ERROR Invoke(uint8_t level, chip::app::DataModel::Nullable<uint16_t> transitionTime, uint8_t optionMask,
uint8_t optionOverride, std::function<void(CHIP_ERROR)> responseCallback);
};

// SUBSCRIBER CLASSES
class CurrentLevelSubscriber : public MediaSubscriptionBase<chip::app::Clusters::LevelControl::Attributes::CurrentLevel::TypeInfo>
{
public:
CurrentLevelSubscriber() : MediaSubscriptionBase(chip::app::Clusters::LevelControl::Id) {}
};

class MinLevelSubscriber : public MediaSubscriptionBase<chip::app::Clusters::LevelControl::Attributes::MinLevel::TypeInfo>
{
public:
MinLevelSubscriber() : MediaSubscriptionBase(chip::app::Clusters::LevelControl::Id) {}
};

class MaxLevelSubscriber : public MediaSubscriptionBase<chip::app::Clusters::LevelControl::Attributes::MaxLevel::TypeInfo>
{
public:
MaxLevelSubscriber() : MediaSubscriptionBase(chip::app::Clusters::LevelControl::Id) {}
};
Loading

0 comments on commit e9fa4cc

Please sign in to comment.