Skip to content

Commit

Permalink
Update TV linux app according to the submitted issues (#15326)
Browse files Browse the repository at this point in the history
* Update code

* Update tests

* Run zap regen script

* Restyle commit

* Fix failing test

* Update examples/tv-app/linux/include/media-input/MediaInputManager.cpp

Co-authored-by: Boris Zbarsky <[email protected]>

* Update examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp

Co-authored-by: Boris Zbarsky <[email protected]>

* Update code per comments

Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Aug 21, 2023
1 parent 4a87042 commit b19f141
Show file tree
Hide file tree
Showing 16 changed files with 669 additions and 159 deletions.
10 changes: 10 additions & 0 deletions examples/tv-app/android/App/.idea/runConfigurations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ CHIP_ERROR ApplicationLauncherManager::HandleGetCatalogList(AttributeValueEncode
void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper<LauncherResponseType> & helper, const ByteSpan & data,
const ApplicationType & application)
{
ChipLogError(Zcl, "ApplicationLauncherManager::HandleLaunchApp");
ChipLogProgress(Zcl, "ApplicationLauncherManager::HandleLaunchApp");

// TODO: Insert code here
LauncherResponseType response;
Expand All @@ -52,7 +52,7 @@ void ApplicationLauncherManager::HandleLaunchApp(CommandResponseHelper<LauncherR
void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper<LauncherResponseType> & helper,
const ApplicationType & application)
{
ChipLogError(Zcl, "ApplicationLauncherManager::HandleStopApp");
ChipLogProgress(Zcl, "ApplicationLauncherManager::HandleStopApp");

// TODO: Insert code here
LauncherResponseType response;
Expand All @@ -65,7 +65,7 @@ void ApplicationLauncherManager::HandleStopApp(CommandResponseHelper<LauncherRes
void ApplicationLauncherManager::HandleHideApp(CommandResponseHelper<LauncherResponseType> & helper,
const ApplicationType & application)
{
ChipLogError(Zcl, "ApplicationLauncherManager::HandleHideApp");
ChipLogProgress(Zcl, "ApplicationLauncherManager::HandleHideApp");

// TODO: Insert code here
LauncherResponseType response;
Expand Down
52 changes: 42 additions & 10 deletions examples/tv-app/linux/include/audio-output/AudioOutputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,32 @@ using namespace std;
using namespace chip::app;
using namespace chip::app::Clusters::AudioOutput;

AudioOutputManager::AudioOutputManager()
{
mCurrentOutput = 1;

for (int i = 1; i < 4; ++i)
{
OutputInfoType outputInfo;
outputInfo.outputType = chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi;
// note: safe only because of use of string literal
outputInfo.name = chip::CharSpan::fromCharString("HDMI");
outputInfo.index = static_cast<uint8_t>(i);
mOutputs.push_back(outputInfo);
}
}

uint8_t AudioOutputManager::HandleGetCurrentOutput()
{
return 0;
return mCurrentOutput;
}

CHIP_ERROR AudioOutputManager::HandleGetOutputList(AttributeValueEncoder & aEncoder)
{
// TODO: Insert code here
return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR {
int maximumVectorSize = 3;
for (int i = 0; i < maximumVectorSize; ++i)
return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR {
for (auto const & outputInfo : this->mOutputs)
{
chip::app::Clusters::AudioOutput::Structs::OutputInfo::Type outputInfo;
outputInfo.outputType = chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi;
outputInfo.name = chip::CharSpan::fromCharString("exampleName");
outputInfo.index = static_cast<uint8_t>(1 + i);
ReturnErrorOnFailure(encoder.Encode(outputInfo));
}
return CHIP_NO_ERROR;
Expand All @@ -47,11 +57,33 @@ CHIP_ERROR AudioOutputManager::HandleGetOutputList(AttributeValueEncoder & aEnco
bool AudioOutputManager::HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name)
{
// TODO: Insert code here
return true;
bool audioOutputRenamed = false;

for (OutputInfoType & output : mOutputs)
{
if (output.index == index)
{
audioOutputRenamed = true;
memcpy(this->Data(index), name.data(), name.size());
output.name = chip::CharSpan(this->Data(index), name.size());
}
}

return audioOutputRenamed;
}

bool AudioOutputManager::HandleSelectOutput(const uint8_t & index)
{
// TODO: Insert code here
return true;
bool audioOutputSelected = false;
for (OutputInfoType & output : mOutputs)
{
if (output.index == index)
{
audioOutputSelected = true;
mCurrentOutput = index;
}
}

return audioOutputSelected;
}
11 changes: 11 additions & 0 deletions examples/tv-app/linux/include/audio-output/AudioOutputManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,26 @@
#pragma once

#include <app/clusters/audio-output-server/audio-output-server.h>
#include <vector>

using chip::app::AttributeValueEncoder;
using AudioOutputDelegate = chip::app::Clusters::AudioOutput::Delegate;
using OutputInfoType = chip::app::Clusters::AudioOutput::Structs::OutputInfo::Type;

class AudioOutputManager : public AudioOutputDelegate
{
public:
AudioOutputManager();

uint8_t HandleGetCurrentOutput() override;
CHIP_ERROR HandleGetOutputList(AttributeValueEncoder & aEncoder) override;
bool HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name) override;
bool HandleSelectOutput(const uint8_t & index) override;
char * Data(uint8_t index) { return mCharDataBuffer[index]; }

protected:
uint8_t mCurrentOutput;
std::vector<OutputInfoType> mOutputs;
// Magic numbers are here on purpose, please allocate memory
char mCharDataBuffer[10][32];
};
147 changes: 114 additions & 33 deletions examples/tv-app/linux/include/channel/ChannelManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,76 +16,157 @@
*/

#include "ChannelManager.h"
#include <vector>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters::Channel;

ChannelManager::ChannelManager()
{
ChannelInfoType abc;
abc.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KAAL"));
abc.callSign = MakeOptional(chip::CharSpan::fromCharString("KAAL-TV"));
abc.name = MakeOptional(chip::CharSpan::fromCharString("ABC"));
abc.majorNumber = static_cast<uint8_t>(6);
abc.minorNumber = static_cast<uint16_t>(0);
mChannels.push_back(abc);

ChannelInfoType pbs;
pbs.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS"));
pbs.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV"));
pbs.name = MakeOptional(chip::CharSpan::fromCharString("PBS"));
pbs.majorNumber = static_cast<uint8_t>(9);
pbs.minorNumber = static_cast<uint16_t>(1);
mChannels.push_back(pbs);

ChannelInfoType pbsKids;
pbsKids.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS"));
pbsKids.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV"));
pbsKids.name = MakeOptional(chip::CharSpan::fromCharString("PBS Kids"));
pbsKids.majorNumber = static_cast<uint8_t>(9);
pbsKids.minorNumber = static_cast<uint16_t>(2);
mChannels.push_back(pbsKids);

ChannelInfoType worldChannel;
worldChannel.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS"));
worldChannel.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV"));
worldChannel.name = MakeOptional(chip::CharSpan::fromCharString("World Channel"));
worldChannel.majorNumber = static_cast<uint8_t>(9);
worldChannel.minorNumber = static_cast<uint16_t>(3);
mChannels.push_back(worldChannel);

mCurrentChannelIndex = 0;
mCurrentChannel = mChannels[mCurrentChannelIndex];
}

CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder)
{
// TODO: Insert code here
return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR {
int maximumVectorSize = 2;

for (int i = 0; i < maximumVectorSize; ++i)
for (auto const & channel : ChannelManager().mChannels)
{
chip::app::Clusters::Channel::Structs::ChannelInfo::Type channelInfo;
channelInfo.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("exampleASign"));
channelInfo.callSign = MakeOptional(chip::CharSpan::fromCharString("exampleCSign"));
channelInfo.name = MakeOptional(chip::CharSpan::fromCharString("exampleName"));
channelInfo.majorNumber = static_cast<uint8_t>(1 + i);
channelInfo.minorNumber = static_cast<uint16_t>(2 + i);

ReturnErrorOnFailure(encoder.Encode(channelInfo));
ReturnErrorOnFailure(encoder.Encode(channel));
}

return CHIP_NO_ERROR;
});
}

CHIP_ERROR ChannelManager::HandleGetLineup(AttributeValueEncoder & aEncoder)
{
chip::app::Clusters::Channel::Structs::LineupInfo::Type lineup;
lineup.operatorName = chip::CharSpan::fromCharString("operatorName");
lineup.lineupName = MakeOptional(chip::CharSpan::fromCharString("lineupName"));
lineup.postalCode = MakeOptional(chip::CharSpan::fromCharString("postalCode"));
LineupInfoType lineup;
lineup.operatorName = chip::CharSpan::fromCharString("Comcast");
lineup.lineupName = MakeOptional(chip::CharSpan::fromCharString("Comcast King County"));
lineup.postalCode = MakeOptional(chip::CharSpan::fromCharString("98052"));
lineup.lineupInfoType = chip::app::Clusters::Channel::LineupInfoTypeEnum::kMso;

return aEncoder.Encode(lineup);
}

CHIP_ERROR ChannelManager::HandleGetCurrentChannel(AttributeValueEncoder & aEncoder)
{
chip::app::Clusters::Channel::Structs::ChannelInfo::Type currentChannel;
currentChannel.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("exampleASign"));
currentChannel.callSign = MakeOptional(chip::CharSpan::fromCharString("exampleCSign"));
currentChannel.name = MakeOptional(chip::CharSpan::fromCharString("exampleName"));
currentChannel.majorNumber = 1;
currentChannel.minorNumber = 0;

return aEncoder.Encode(currentChannel);
return aEncoder.Encode(mCurrentChannel);
}

bool isChannelMatched(const ChannelInfoType & channel, const CharSpan & match)
{
char number[32];
sprintf(number, "%d.%d", channel.majorNumber, channel.minorNumber);
bool nameMatch = channel.name.HasValue() ? channel.name.Value().data_equal(match) : false;
bool affiliateCallSignMatch =
channel.affiliateCallSign.HasValue() ? channel.affiliateCallSign.Value().data_equal(match) : false;
bool callSignMatch = channel.callSign.HasValue() ? channel.callSign.Value().data_equal(match) : false;
bool numberMatch = match.data_equal(chip::CharSpan::fromCharString(number));

return affiliateCallSignMatch || callSignMatch || nameMatch || numberMatch;
}

void ChannelManager::HandleChangeChannel(CommandResponseHelper<ChangeChannelResponseType> & helper, const CharSpan & match)
{
std::vector<ChannelInfoType> matchedChannels;
uint16_t index = 0;
for (auto const & channel : mChannels)
{
index++;
// verify if CharSpan matches channel name
// or callSign or affiliateCallSign or majorNumber.minorNumber
if (isChannelMatched(channel, match))
{
matchedChannels.push_back(channel);
}
}

ChangeChannelResponseType response;
response.channelMatch.majorNumber = 1;
response.channelMatch.minorNumber = 0;
response.channelMatch.name = MakeOptional(chip::CharSpan::fromCharString("name"));
response.channelMatch.callSign = MakeOptional(chip::CharSpan::fromCharString("callSign"));
response.channelMatch.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("affiliateCallSign"));
response.errorType = chip::app::Clusters::Channel::ErrorTypeEnum::kMultipleMatches;

helper.Success(response);

// Error: Found multiple matches
if (matchedChannels.size() > 1)
{
response.errorType = chip::app::Clusters::Channel::ErrorTypeEnum::kMultipleMatches;
helper.Success(response);
}
else if (matchedChannels.size() == 0)
{
// Error: Found no match
response.errorType = chip::app::Clusters::Channel::ErrorTypeEnum::kNoMatches;
helper.Success(response);
}
else
{
response.channelMatch = matchedChannels[0];
mCurrentChannel = matchedChannels[0];
mCurrentChannelIndex = index;
helper.Success(response);
}
}

bool ChannelManager::HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber)
{
// TODO: Insert code here
return true;
bool channelChanged = false;
uint16_t index = 0;
for (auto const & channel : mChannels)
{
index++;
// verify if major & minor matches one of the channel from the list
if (channel.minorNumber == minorNumber && channel.majorNumber == majorNumber)
{
// verify if channel changed by comparing values of current channel with the requested channel
if (channel.minorNumber != mCurrentChannel.minorNumber || channel.majorNumber != mCurrentChannel.majorNumber)
{
channelChanged = true;
mCurrentChannelIndex = index;
mCurrentChannel = channel;
}
}
}
return channelChanged;
}

bool ChannelManager::HandleSkipChannel(const uint16_t & count)
{
// TODO: Insert code here
uint16_t newChannelIndex = static_cast<uint16_t>((count + mCurrentChannelIndex) % mChannels.size());
mCurrentChannelIndex = newChannelIndex;
mCurrentChannel = mChannels[mCurrentChannelIndex];
return true;
}
10 changes: 10 additions & 0 deletions examples/tv-app/linux/include/channel/ChannelManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,31 @@
#pragma once

#include <app/clusters/channel-server/channel-server.h>
#include <vector>

using chip::CharSpan;
using chip::app::AttributeValueEncoder;
using chip::app::CommandResponseHelper;
using ChannelDelegate = chip::app::Clusters::Channel::Delegate;
using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type;
using ChannelInfoType = chip::app::Clusters::Channel::Structs::ChannelInfo::Type;
using LineupInfoType = chip::app::Clusters::Channel::Structs::LineupInfo::Type;

class ChannelManager : public ChannelDelegate
{
public:
ChannelManager();

CHIP_ERROR HandleGetChannelList(AttributeValueEncoder & aEncoder) override;
CHIP_ERROR HandleGetLineup(AttributeValueEncoder & aEncoder) override;
CHIP_ERROR HandleGetCurrentChannel(AttributeValueEncoder & aEncoder) override;

void HandleChangeChannel(CommandResponseHelper<ChangeChannelResponseType> & helper, const CharSpan & match) override;
bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) override;
bool HandleSkipChannel(const uint16_t & count) override;

protected:
uint16_t mCurrentChannelIndex;
ChannelInfoType mCurrentChannel;
std::vector<ChannelInfoType> mChannels;
};
Loading

0 comments on commit b19f141

Please sign in to comment.