Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restyle Enable content launcher test for tv app #13035

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14476,7 +14476,7 @@
],
"attributes": [
{
"name": "accepts header list",
"name": "accept header list",
"code": 0,
"mfgCode": null,
"side": "server",
Expand Down
3 changes: 3 additions & 0 deletions examples/all-clusters-app/linux/include/tv-callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
*******************************************************************************
******************************************************************************/

#include <list>
#include <string>

bool lowPowerClusterSleep()
{
return true;
Expand Down
1 change: 1 addition & 0 deletions examples/chip-tool/templates/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ function getTests()
'TV_MediaPlaybackCluster',
'TV_TvChannelCluster',
'TV_LowPowerCluster',
'TV_ContentLauncherCluster',
'TV_MediaInputCluster',
];

Expand Down
2 changes: 1 addition & 1 deletion examples/thermostat/thermostat-common/thermostat.zap
Original file line number Diff line number Diff line change
Expand Up @@ -13136,7 +13136,7 @@
],
"attributes": [
{
"name": "accepts header list",
"name": "accept header list",
"code": 0,
"mfgCode": null,
"side": "server",
Expand Down
329 changes: 127 additions & 202 deletions examples/tv-app/android/java/ContentLauncherManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,206 +45,9 @@ using namespace chip;

ContentLauncherManager ContentLauncherManager::sInstance;

namespace {

class ContentLauncherAttrAccess : public app::AttributeAccessInterface
{
public:
ContentLauncherAttrAccess() : app::AttributeAccessInterface(Optional<EndpointId>::Missing(), app::Clusters::ContentLauncher::Id)
{}

CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override
{
if (aPath.mAttributeId == app::Clusters::ContentLauncher::Attributes::AcceptsHeaderList::Id)
{
return ContentLauncherMgr().GetAcceptsHeader(aEncoder);
}
else if (aPath.mAttributeId == app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id)
{
return ContentLauncherMgr().GetSupportedStreamingTypes(aEncoder);
}

return CHIP_NO_ERROR;
}
};

ContentLauncherAttrAccess gContentLauncherAttrAccess;

} // anonymous namespace

/** @brief Content Launch Cluster Init
*
* This function is called when a specific cluster is initialized. It gives the
* application an opportunity to take care of cluster initialization procedures.
* It is called exactly once for each endpoint where cluster is present.
*
* @param endpoint Ver.: always
*
*/
void emberAfContentLauncherClusterInitCallback(EndpointId endpoint)
{
static bool attrAccessRegistered = false;
if (!attrAccessRegistered)
{
registerAttributeAccessOverride(&gContentLauncherAttrAccess);
attrAccessRegistered = true;
}
}

ContentLaunchResponse contentLauncherClusterLaunchContent(chip::EndpointId endpointId,
std::list<ContentLaunchParamater> parameterList, bool autoplay,
const chip::CharSpan & data)
{
return ContentLauncherMgr().LaunchContent(endpointId, parameterList, autoplay, data);
}

ContentLaunchResponse contentLauncherClusterLaunchUrl(const chip::CharSpan & contentUrl, const chip::CharSpan & displayString,
ContentLaunchBrandingInformation & brandingInformation)
{
return ContentLauncherMgr().LaunchUrl(contentUrl, displayString, brandingInformation);
}

void ContentLauncherManager::InitializeWithObjects(jobject managerObject)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for ContentLauncherManager"));

mContentLauncherManagerObject = env->NewGlobalRef(managerObject);
VerifyOrReturn(mContentLauncherManagerObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef ContentLauncherManager"));

jclass ContentLauncherClass = env->GetObjectClass(managerObject);
VerifyOrReturn(ContentLauncherClass != nullptr, ChipLogError(Zcl, "Failed to get ContentLauncherManager Java class"));

mGetAcceptsHeaderMethod = env->GetMethodID(ContentLauncherClass, "getAcceptsHeader", "()[Ljava/lang/String;");
if (mGetAcceptsHeaderMethod == nullptr)
{
ChipLogError(Zcl, "Failed to access MediaInputManager 'getInputList' method");
env->ExceptionClear();
}

mGetSupportedStreamingTypesMethod = env->GetMethodID(ContentLauncherClass, "getSupportedStreamingTypes", "()[I");
if (mGetSupportedStreamingTypesMethod == nullptr)
{
ChipLogError(Zcl, "Failed to access MediaInputManager 'getSupportedStreamingTypes' method");
env->ExceptionClear();
}

mLaunchContentMethod = env->GetMethodID(
ContentLauncherClass, "launchContent",
"([Lcom/tcl/chip/tvapp/ContentLaunchSearchParameter;ZLjava/lang/String;)Lcom/tcl/chip/tvapp/ContentLaunchResponse;");
if (mLaunchContentMethod == nullptr)
{
ChipLogError(Zcl, "Failed to access MediaInputManager 'launchContent' method");
env->ExceptionClear();
}

mLaunchUrlMethod = env->GetMethodID(ContentLauncherClass, "launchUrl",
"(Ljava/lang/String;Ljava/lang/String;Lcom/tcl/chip/tvapp/"
"ContentLaunchBrandingInformation;)Lcom/tcl/chip/tvapp/ContentLaunchResponse;");
if (mLaunchUrlMethod == nullptr)
{
ChipLogError(AppServer, "Failed to access 'launchUrl' method");
env->ExceptionClear();
}
}

CHIP_ERROR ContentLauncherManager::GetAcceptsHeader(chip::app::AttributeValueEncoder & aEncoder)
{
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

ChipLogProgress(Zcl, "Received ContentLauncherManager::GetAcceptsHeader");
VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(mGetAcceptsHeaderMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);

return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR {
jobjectArray headersArray = (jobjectArray) env->CallObjectMethod(mContentLauncherManagerObject, mGetAcceptsHeaderMethod);
if (env->ExceptionCheck())
{
ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptsHeader");
env->ExceptionDescribe();
env->ExceptionClear();
return CHIP_ERROR_INCORRECT_STATE;
}

jint size = env->GetArrayLength(headersArray);
for (int i = 0; i < size; i++)
{
jstring acceptsheader = (jstring) env->GetObjectArrayElement(headersArray, i);
if (acceptsheader != nullptr)
{
JniUtfString header(env, acceptsheader);

chip::ByteSpan bHeader((const uint8_t *) (header.c_str()), (size_t)(header.size()));
ReturnErrorOnFailure(encoder.Encode(bHeader));

// Todo: should be chanSpan?
// ReturnErrorOnFailure(encoder.Encode(header.charSpan()));
}
}

return CHIP_NO_ERROR;
});

exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "ContentLauncherManager::GetAcceptsHeader status error: %s", err.AsString());
}

return err;
}

CHIP_ERROR ContentLauncherManager::GetSupportedStreamingTypes(chip::app::AttributeValueEncoder & aEncoder)
{
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

ChipLogProgress(Zcl, "Received ContentLauncherManager::GetSupportedStreamingTypes");
VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(mGetSupportedStreamingTypesMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);

return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR {
jintArray typesArray = (jintArray) env->CallObjectMethod(mContentLauncherManagerObject, mGetSupportedStreamingTypesMethod);
if (env->ExceptionCheck())
{
ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetSupportedStreamingTypes");
env->ExceptionDescribe();
env->ExceptionClear();
return CHIP_ERROR_INCORRECT_STATE;
}

jboolean isCopy = JNI_FALSE;
jint * ptypes = env->GetIntArrayElements(typesArray, &isCopy);
jint size = env->GetArrayLength(typesArray);

CHIP_ERROR err = CHIP_NO_ERROR;
for (int i = 0; i < size; i++)
{
err = encoder.Encode(static_cast<uint8_t>(ptypes[i]));
if (err != CHIP_NO_ERROR)
{
break;
}
}
env->ReleaseIntArrayElements(typesArray, ptypes, 0);
return err;
});

exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "ContentLauncherManager::GetAcceptsHeader status error: %s", err.AsString());
}

return err;
}

ContentLaunchResponse ContentLauncherManager::LaunchContent(chip::EndpointId endpointId,
std::list<ContentLaunchParamater> parameterList, bool autoplay,
const chip::CharSpan & data)
ContentLaunchResponse ContentLauncherManager::HandleLaunchContent(chip::EndpointId endpointId,
const std::list<ContentLaunchParamater> & parameterList,
bool autoplay, const chip::CharSpan & data)
{
ContentLaunchResponse response;
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down Expand Up @@ -297,8 +100,9 @@ ContentLaunchResponse ContentLauncherManager::LaunchContent(chip::EndpointId end
return response;
}

ContentLaunchResponse ContentLauncherManager::LaunchUrl(const chip::CharSpan & contentUrl, const chip::CharSpan & displayString,
ContentLaunchBrandingInformation & brandingInformation)
ContentLaunchResponse
ContentLauncherManager::HandleLaunchUrl(const chip::CharSpan & contentUrl, const chip::CharSpan & displayString,
const std::list<ContentLaunchBrandingInformation> & brandingInformation)
{
ContentLaunchResponse response;
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down Expand Up @@ -351,3 +155,124 @@ ContentLaunchResponse ContentLauncherManager::LaunchUrl(const chip::CharSpan & c

return response;
}

std::list<std::string> ContentLauncherManager::HandleGetAcceptHeaderList()
{
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
std::list<std::string> acceptedHeadersList;

ChipLogProgress(Zcl, "Received ContentLauncherManager::GetAcceptHeader");
VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(mGetAcceptHeaderMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);

{
jobjectArray acceptedHeadersArray =
(jobjectArray) env->CallObjectMethod(mContentLauncherManagerObject, mGetAcceptHeaderMethod);
if (env->ExceptionCheck())
{
ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptHeader");
env->ExceptionDescribe();
env->ExceptionClear();
err = CHIP_ERROR_INCORRECT_STATE;
goto exit;
}

jint size = env->GetArrayLength(acceptedHeadersArray);
for (int i = 0; i < size; i++)
{

jstring jAcceptedHeader = (jstring) env->GetObjectArrayElement(acceptedHeadersArray, i);
const char * convertedValue = (env)->GetStringUTFChars(jAcceptedHeader, JNI_FALSE);
std::string acceptedHeader = std::string(convertedValue, strlen(convertedValue));
acceptedHeadersList.push_front(acceptedHeader);
}
}

exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "ContentLauncherManager::GetAcceptHeader status error: %s", err.AsString());
}

return acceptedHeadersList;
}

uint32_t ContentLauncherManager::HandleGetSupportedStreamingProtocols()
{
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
uint32_t supportedStreamingProtocols = 0;

ChipLogProgress(Zcl, "Received ContentLauncherManager::GetSupportedStreamingProtocols");
VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(mGetSupportedStreamingProtocolsMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);

{
jint jSupportedStreamingProtocols =
env->CallIntMethod(mContentLauncherManagerObject, mGetSupportedStreamingProtocolsMethod);
supportedStreamingProtocols = (uint32_t) jSupportedStreamingProtocols;
if (env->ExceptionCheck())
{
ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptHeader");
env->ExceptionDescribe();
env->ExceptionClear();
err = CHIP_ERROR_INCORRECT_STATE;
goto exit;
}
}

exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "ContentLauncherManager::GetSupportedStreamingProtocols status error: %s", err.AsString());
}

return supportedStreamingProtocols;
}

void ContentLauncherManager::InitializeWithObjects(jobject managerObject)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for ContentLauncherManager"));

mContentLauncherManagerObject = env->NewGlobalRef(managerObject);
VerifyOrReturn(mContentLauncherManagerObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef ContentLauncherManager"));

jclass ContentLauncherClass = env->GetObjectClass(managerObject);
VerifyOrReturn(ContentLauncherClass != nullptr, ChipLogError(Zcl, "Failed to get ContentLauncherManager Java class"));

mGetAcceptHeaderMethod = env->GetMethodID(ContentLauncherClass, "getAcceptHeader", "()[Ljava/lang/String;");
if (mGetAcceptHeaderMethod == nullptr)
{
ChipLogError(Zcl, "Failed to access MediaInputManager 'getInputList' method");
env->ExceptionClear();
}

mGetSupportedStreamingProtocolsMethod = env->GetMethodID(ContentLauncherClass, "getSupportedStreamingProtocols", "()[I");
if (mGetSupportedStreamingProtocolsMethod == nullptr)
{
ChipLogError(Zcl, "Failed to access MediaInputManager 'getSupportedStreamingProtocols' method");
env->ExceptionClear();
}

mLaunchContentMethod = env->GetMethodID(
ContentLauncherClass, "launchContent",
"([Lcom/tcl/chip/tvapp/ContentLaunchSearchParameter;ZLjava/lang/String;)Lcom/tcl/chip/tvapp/ContentLaunchResponse;");
if (mLaunchContentMethod == nullptr)
{
ChipLogError(Zcl, "Failed to access MediaInputManager 'launchContent' method");
env->ExceptionClear();
}

mLaunchUrlMethod = env->GetMethodID(ContentLauncherClass, "launchUrl",
"(Ljava/lang/String;Ljava/lang/String;Lcom/tcl/chip/tvapp/"
"ContentLaunchBrandingInformation;)Lcom/tcl/chip/tvapp/ContentLaunchResponse;");
if (mLaunchUrlMethod == nullptr)
{
ChipLogError(AppServer, "Failed to access 'launchUrl' method");
env->ExceptionClear();
}
}
Loading