From d7e9495345f9f37d16802bc86ba6601a13d77cce Mon Sep 17 00:00:00 2001 From: Amit Jain Date: Thu, 23 Jun 2022 14:50:58 -0700 Subject: [PATCH 1/6] Add functionality to read attributes from content apps --- .../tv/app/api/MatterIntentConstants.java | 5 + .../receiver/MatterCommandReceiver.java | 83 +++++++---- .../ContentAppEndpointManagerImpl.java | 20 +++ .../service/ContentAppAgentService.java | 27 ++++ examples/tv-app/android/BUILD.gn | 2 + .../AppContentLauncherManager.cpp | 60 ++++++-- .../AppContentLauncherManager.h | 17 ++- examples/tv-app/android/java/AppImpl.cpp | 4 +- examples/tv-app/android/java/AppImpl.h | 13 +- .../java/ContentAppAttributeDelegate.cpp | 139 ++++++++++++++++++ .../java/ContentAppAttributeDelegate.h | 80 ++++++++++ .../java/ContentAppCommandDelegate.cpp | 10 +- .../tvapp/ContentAppEndpointManager.java | 2 + 13 files changed, 404 insertions(+), 58 deletions(-) create mode 100644 examples/tv-app/android/java/ContentAppAttributeDelegate.cpp create mode 100644 examples/tv-app/android/java/ContentAppAttributeDelegate.h diff --git a/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java b/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java index d5e95061b6f6c5..60fa854790000f 100644 --- a/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java +++ b/examples/tv-app/android/App/common-api/src/main/java/com/matter/tv/app/api/MatterIntentConstants.java @@ -15,9 +15,14 @@ public class MatterIntentConstants { public static final String EXTRA_RESPONSE_PAYLOAD = "EXTRA_RESPONSE_PAYLOAD"; + public static final String EXTRA_ATTRIBUTE_ACTION = "EXTRA_ATTRIBUTE_ACTION"; + + public static final String ATTRIBUTE_ACTION_READ = "ATTRIBUTE_ACTION_READ"; + public static final String EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT = "EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT"; public static final String EXTRA_COMMAND_ID = "EXTRA_COMMAND_ID"; public static final String EXTRA_CLUSTER_ID = "EXTRA_CLUSTER_ID"; + public static final String EXTRA_ATTRIBUTE_ID = "EXTRA_ATTRIBUTE_ID"; } diff --git a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java index 5ac11d4b741dae..fc2e1271e61ad6 100644 --- a/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java +++ b/examples/tv-app/android/App/content-app/src/main/java/com/example/contentapp/receiver/MatterCommandReceiver.java @@ -9,6 +9,8 @@ public class MatterCommandReceiver extends BroadcastReceiver { private static final String TAG = "MatterCommandReceiver"; + private static final int ACCEPT_HEADER = 0; + private static final int SUPPORTED_STREAMING_PROTOCOLS = 1; @Override public void onReceive(Context context, Intent intent) { @@ -21,37 +23,48 @@ public void onReceive(Context context, Intent intent) { switch (intentAction) { case MatterIntentConstants.ACTION_MATTER_COMMAND: - byte[] commandPayload = - intent.getByteArrayExtra(MatterIntentConstants.EXTRA_COMMAND_PAYLOAD); int commandId = intent.getIntExtra(MatterIntentConstants.EXTRA_COMMAND_ID, -1); - int clusterId = intent.getIntExtra(MatterIntentConstants.EXTRA_CLUSTER_ID, -1); - Log.d( - TAG, - new StringBuilder() - .append("Received matter command ") - .append(commandId) - .append(" on cluster ") - .append(clusterId) - .append(" with payload : ") - .append(new String(commandPayload)) - .toString()); - - PendingIntent pendingIntent = - intent.getParcelableExtra( - MatterIntentConstants.EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT); - if (pendingIntent != null) { - final Intent responseIntent = - new Intent() - .putExtra( - MatterIntentConstants.EXTRA_RESPONSE_PAYLOAD, - "{\"value\":{\"0\":1, \"1\":\"custom response from content app\"}}" - .getBytes()); - try { - pendingIntent.send(context, 0, responseIntent); - } catch (final PendingIntent.CanceledException ex) { - Log.e(TAG, "Error sending pending intent to the Matter agent", ex); + if (commandId != -1) { + int clusterId = intent.getIntExtra(MatterIntentConstants.EXTRA_CLUSTER_ID, -1); + byte[] commandPayload = + intent.getByteArrayExtra(MatterIntentConstants.EXTRA_COMMAND_PAYLOAD); + Log.d( + TAG, + new StringBuilder() + .append("Received matter command ") + .append(commandId) + .append(" on cluster ") + .append(clusterId) + .append(" with payload : ") + .append(new String(commandPayload)) + .toString()); + String response = "{\"0\":1, \"1\":\"custom response from content app\"}"; + sendResponseViaPendingIntent(context, intent, response); + } else { + int attributeId = intent.getIntExtra(MatterIntentConstants.EXTRA_ATTRIBUTE_ID, -1); + String attributeAction = + intent.getStringExtra(MatterIntentConstants.EXTRA_ATTRIBUTE_ACTION); + if (attributeAction.equals(MatterIntentConstants.ATTRIBUTE_ACTION_READ)) { + String response; + if (attributeId == ACCEPT_HEADER) { + response = + "{\"0\": [\"video/mp4\", \"application/x-mpegURL\", \"application/dash+xml\"] }"; + } else if (attributeId == SUPPORTED_STREAMING_PROTOCOLS) { + response = "{\"1\":3}"; + } else { + response = ""; + } + sendResponseViaPendingIntent(context, intent, response); + } else { + Log.e( + TAG, + new StringBuilder() + .append("Received unknown Attribute Action: ") + .append(intent.getAction()) + .toString()); } } + break; default: Log.e( @@ -62,4 +75,18 @@ public void onReceive(Context context, Intent intent) { .toString()); } } + + private void sendResponseViaPendingIntent(Context context, Intent intent, String response) { + PendingIntent pendingIntent = + intent.getParcelableExtra(MatterIntentConstants.EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT); + if (pendingIntent != null) { + final Intent responseIntent = + new Intent().putExtra(MatterIntentConstants.EXTRA_RESPONSE_PAYLOAD, response.getBytes()); + try { + pendingIntent.send(context, 0, responseIntent); + } catch (final PendingIntent.CanceledException ex) { + Log.e(TAG, "Error sending pending intent to the Matter agent", ex); + } + } + } } diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java index 789089b0964271..0b9ea344b161ad 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/handlers/ContentAppEndpointManagerImpl.java @@ -29,4 +29,24 @@ public String sendCommand(int endpointId, int clusterId, int commandId, String c } return "Success"; } + + public String readAttribute(int endpointId, int clusterId, int attributeId) { + Log.d( + TAG, + "Received a attribute read request for endpointId " + + endpointId + + "clusterId" + + clusterId + + " attributeId " + + attributeId); + for (ContentApp app : + ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values()) { + if (app.getEndpointId() == endpointId) { + Log.d(TAG, "Sending attribute read request for endpointId " + endpointId); + return ContentAppAgentService.sendAttributeReadRequest( + context, app.getAppName(), clusterId, attributeId); + } + } + return ""; + } } diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java index ccc72e4a9221b2..d68758b1152816 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/ContentAppAgentService.java @@ -80,6 +80,33 @@ public static String sendCommand( return response; } + public static String sendAttributeReadRequest( + Context context, String packageName, int clusterId, int attributeId) { + Intent in = new Intent(MatterIntentConstants.ACTION_MATTER_COMMAND); + Bundle extras = new Bundle(); + extras.putString( + MatterIntentConstants.EXTRA_ATTRIBUTE_ACTION, MatterIntentConstants.ATTRIBUTE_ACTION_READ); + extras.putInt(MatterIntentConstants.EXTRA_ATTRIBUTE_ID, attributeId); + extras.putInt(MatterIntentConstants.EXTRA_CLUSTER_ID, clusterId); + in.putExtras(extras); + in.setPackage(packageName); + int flags = Intent.FLAG_INCLUDE_STOPPED_PACKAGES; + flags |= Intent.FLAG_RECEIVER_FOREGROUND; + in.setFlags(flags); + int messageId = responseRegistry.getNextMessageCounter(); + in.putExtra( + MatterIntentConstants.EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT, + getPendingIntentForResponse(context, packageName, messageId)); + context.sendBroadcast(in); + responseRegistry.waitForMessage(messageId, 10, TimeUnit.SECONDS); + String response = responseRegistry.readAndRemoveResponse(messageId); + if (response == null) { + response = ""; + } + Log.d(TAG, "Response " + response + " being returned for message " + messageId); + return response; + } + private static PendingIntent getPendingIntentForResponse( final Context context, final String targetPackage, final int responseId) { Intent ackBackIntent = new Intent(ACTION_MATTER_RESPONSE); diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn index a616671f049cb6..17abcc4948802c 100644 --- a/examples/tv-app/android/BUILD.gn +++ b/examples/tv-app/android/BUILD.gn @@ -44,6 +44,8 @@ shared_library("jni") { "java/ChannelManager.cpp", "java/ChannelManager.h", "java/ClusterChangeAttribute.cpp", + "java/ContentAppAttributeDelegate.cpp", + "java/ContentAppAttributeDelegate.h", "java/ContentAppCommandDelegate.cpp", "java/ContentAppCommandDelegate.h", "java/ContentLauncherManager.cpp", diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp index 6dc80c5b164f5a..5210ac127818fc 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp @@ -17,18 +17,19 @@ */ #include "AppContentLauncherManager.h" -#include "../../java/ContentAppCommandDelegate.h" +#include "../../java/ContentAppAttributeDelegate.h" +#include using namespace std; using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::DataModel; using namespace chip::app::Clusters::ContentLauncher; -using ContentAppCommandDelegate = chip::AppPlatform::ContentAppCommandDelegate; +using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; -AppContentLauncherManager::AppContentLauncherManager(ContentAppCommandDelegate commandDelegate, list acceptHeaderList, - uint32_t supportedStreamingProtocols) : - mCommandDelegate(commandDelegate) +AppContentLauncherManager::AppContentLauncherManager(ContentAppAttributeDelegate * attributeDelegate, + list acceptHeaderList, uint32_t supportedStreamingProtocols) : + mAttributeDelegate(attributeDelegate) { mAcceptHeaderList = acceptHeaderList; mSupportedStreamingProtocols = supportedStreamingProtocols; @@ -73,11 +74,8 @@ void AppContentLauncherManager::HandleLaunchUrl(CommandResponseHelperRead(aPath); + ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response %s", resStr); + + if (resStr != nullptr && *resStr != 0) + { + Json::Reader reader; + Json::Value value; + reader.parse(resStr, value); + const char * attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::AcceptHeader::Id).c_str(); + ChipLogProgress( + Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", attrId); + if (value[attrId].isArray()) + { + mAcceptHeaderList.clear(); + for (Json::Value & entry : value[attrId]) + { + mAcceptHeaderList.push_back(entry.asString()); + } + } + } + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { for (std::string & entry : mAcceptHeaderList) { @@ -98,6 +119,27 @@ CHIP_ERROR AppContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEn uint32_t AppContentLauncherManager::HandleGetSupportedStreamingProtocols() { ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols"); + chip::app::ConcreteReadAttributePath aPath(mEndpointId, chip::app::Clusters::ContentLauncher::Id, + chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id); + const char * resStr = mAttributeDelegate->Read(aPath); + ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response %s", resStr); + + if (resStr == nullptr || *resStr == 0) + { + return mSupportedStreamingProtocols; + } + + Json::Reader reader; + Json::Value value; + reader.parse(resStr, value); + const char * attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id).c_str(); + ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", + attrId); + if (!value[attrId].empty()) + { + uint32_t supportedStreamingProtocols = static_cast(value[attrId].asInt()); + mSupportedStreamingProtocols = supportedStreamingProtocols; + } return mSupportedStreamingProtocols; } diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h index b5b8f7a533c4e2..cce275315ae1ad 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h @@ -18,24 +18,24 @@ #pragma once -#include "../../java/ContentAppCommandDelegate.h" #include +#include "../../java/ContentAppAttributeDelegate.h" #include using chip::CharSpan; using chip::EndpointId; using chip::app::AttributeValueEncoder; using chip::app::CommandResponseHelper; -using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; -using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; -using ParameterType = chip::app::Clusters::ContentLauncher::Structs::Parameter::DecodableType; -using BrandingInformationType = chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type; -using ContentAppCommandDelegate = chip::AppPlatform::ContentAppCommandDelegate; +using ContentLauncherDelegate = chip::app::Clusters::ContentLauncher::Delegate; +using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; +using ParameterType = chip::app::Clusters::ContentLauncher::Structs::Parameter::DecodableType; +using BrandingInformationType = chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type; +using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; class AppContentLauncherManager : public ContentLauncherDelegate { public: - AppContentLauncherManager(ContentAppCommandDelegate commandDelegate, std::list acceptHeaderList, + AppContentLauncherManager(ContentAppAttributeDelegate * attributeDelegate, std::list acceptHeaderList, uint32_t supportedStreamingProtocols); void HandleLaunchContent(CommandResponseHelper & helper, @@ -56,8 +56,9 @@ class AppContentLauncherManager : public ContentLauncherDelegate private: EndpointId mEndpointId; - ContentAppCommandDelegate mCommandDelegate; // TODO: set this based upon meta data from app uint32_t mDynamicEndpointFeatureMap = 3; + + ContentAppAttributeDelegate * mAttributeDelegate; }; diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp index 063a2be2528354..90e88c86f3cd09 100644 --- a/examples/tv-app/android/java/AppImpl.cpp +++ b/examples/tv-app/android/java/AppImpl.cpp @@ -357,7 +357,7 @@ ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vend return nullptr; } -EndpointId ContentAppFactoryImpl::AddContentApp(ContentAppImpl * app) +EndpointId ContentAppFactoryImpl::AddContentApp(ContentAppImpl * app, jobject contentAppEndpointManager) { DataVersion dataVersionBuf[ArraySize(contentAppClusters)]; EndpointId epId = ContentAppPlatform::GetInstance().AddContentApp(app, &contentAppEndpoint, Span(dataVersionBuf), @@ -471,7 +471,7 @@ EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const cha ContentAppImpl * app = new ContentAppImpl(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, "20202021", manager); ChipLogProgress(DeviceLayer, "AppImpl: AddContentApp vendorId=%d applicationName=%s ", vendorId, szApplicationName); - return gFactory.AddContentApp(app); + return gFactory.AddContentApp(app, manager); #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED return 0; } diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h index 98a6d61798bc07..c221c05e8917a3 100644 --- a/examples/tv-app/android/java/AppImpl.h +++ b/examples/tv-app/android/java/AppImpl.h @@ -39,7 +39,7 @@ #include "../include/target-navigator/TargetNavigatorManager.h" #include "ChannelManager.h" #include "CommissionerMain.h" -#include "ContentAppCommandDelegate.h" +#include "ContentAppAttributeDelegate.h" #include "KeypadInputManager.h" #include "MediaPlaybackManager.h" #include "MyUserPrompter-JNI.h" @@ -72,7 +72,7 @@ using KeypadInputDelegate = app::Clusters::KeypadInput::Delegate; using MediaPlaybackDelegate = app::Clusters::MediaPlayback::Delegate; using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate; using SupportedStreamingProtocol = app::Clusters::ContentLauncher::SupportedStreamingProtocol; -using ContentAppCommandDelegate = chip::AppPlatform::ContentAppCommandDelegate; +using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; static const int kCatalogVendorId = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; @@ -86,9 +86,10 @@ class DLL_EXPORT ContentAppImpl : public ContentApp const char * szApplicationVersion, const char * setupPIN, jobject manager) : mApplicationBasicDelegate(kCatalogVendorId, BuildAppId(vendorId), szVendorName, vendorId, szApplicationName, productId, szApplicationVersion), - mAccountLoginDelegate(setupPIN), mContentLauncherDelegate(ContentAppCommandDelegate(manager), { "image/*", "video/*" }, - to_underlying(SupportedStreamingProtocol::kDash) | - to_underlying(SupportedStreamingProtocol::kHls)), + mAccountLoginDelegate(setupPIN), + mContentLauncherDelegate( + new ContentAppAttributeDelegate(manager, app::Clusters::ContentLauncher::Id), { "image/*", "video/*" }, + to_underlying(SupportedStreamingProtocol::kDash) | to_underlying(SupportedStreamingProtocol::kHls)), mTargetNavigatorDelegate({ "home", "search", "info", "guide", "menu" }, 0){}; virtual ~ContentAppImpl() {} @@ -131,7 +132,7 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory // Lookup ContentApp for this catalog id / app id and load it ContentApp * LoadContentApp(const CatalogVendorApp & vendorApp) override; - EndpointId AddContentApp(ContentAppImpl * app); + EndpointId AddContentApp(ContentAppImpl * app, jobject contentAppEndpointManager); void SendTestMessage(EndpointId epID, const char * message); diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp new file mode 100644 index 00000000000000..52fddc2c549ebc --- /dev/null +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp @@ -0,0 +1,139 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @brief Contains Implementation of the ContentAppAttributeDelegate + */ + +#include "ContentAppAttributeDelegate.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace AppPlatform { + +using AttributeAccessInterface = app::AttributeAccessInterface; +using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; + +const char * ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttributePath & aPath) +{ + if (aPath.mEndpointId >= FIXED_ENDPOINT_COUNT) + { + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read being called for endpoint %d cluster %d attribute %d", + aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); + + jstring resp = + (jstring) env->CallObjectMethod(mContentAppEndpointManager, mReadAttributeMethod, static_cast(aPath.mEndpointId), + static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); + if (env->ExceptionCheck()) + { + ChipLogError(Zcl, "Java exception in ContentAppAttributeDelegate::Read"); + env->ExceptionDescribe(); + env->ExceptionClear(); + // FormatResponseData(handlerContext, "{\"value\":{}}"); + return ""; + } + const char * respStr = env->GetStringUTFChars(resp, 0); + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read got response %s", respStr); + // FormatResponseData(handlerContext, respStr); + return respStr; + } + return ""; +} + +CHIP_ERROR ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttributePath & aPath, + chip::app::AttributeValueEncoder & aEncoder) +{ + if (aPath.mEndpointId >= FIXED_ENDPOINT_COUNT) + { + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read being called for endpoint %d cluster %d attribute %d", + aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); + + jstring resp = + (jstring) env->CallObjectMethod(mContentAppEndpointManager, mReadAttributeMethod, static_cast(aPath.mEndpointId), + static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); + if (env->ExceptionCheck()) + { + ChipLogError(Zcl, "Java exception in ContentAppAttributeDelegate::Read"); + env->ExceptionDescribe(); + env->ExceptionClear(); + // FormatResponseData(handlerContext, "{\"value\":{}}"); + return CHIP_NO_ERROR; + } + const char * respStr = env->GetStringUTFChars(resp, 0); + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read got response %s", respStr); + // FormatResponseData(handlerContext, respStr); + return CHIP_NO_ERROR; + } + return CHIP_NO_ERROR; +} + +/* +void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::HandlerContext & handlerContext, const char * response) +{ + Json::Reader reader; + Json::Value value; + reader.parse(response, value); + + switch (handlerContext.mRequestPath.mClusterId) + { + case app::Clusters::ContentLauncher::Id: { + LaunchResponseType launchResponse; + if (value["0"].empty()) + { + launchResponse.status = chip::app::Clusters::ContentLauncher::ContentLaunchStatusEnum::kAuthFailed; + } + else + { + launchResponse.status = static_cast(value["0"].asInt()); + if (!value["1"].empty()) + { + launchResponse.data = chip::MakeOptional(CharSpan::fromCharString(value["1"].asCString())); + } + } + handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, launchResponse); + handlerContext.SetCommandHandled(); + break; + } + + // case app::Clusters::TargetNavigator::Id: + // break; + + // case app::Clusters::MediaPlayback::Id: + // break; + + // case app::Clusters::AccountLogin::Id: + // break; + default: + handlerContext.SetCommandNotHandled(); + } +} +*/ + +} // namespace AppPlatform +} // namespace chip diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.h b/examples/tv-app/android/java/ContentAppAttributeDelegate.h new file mode 100644 index 00000000000000..d44973763b6ca8 --- /dev/null +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @brief Facilitates communication with the application handlers in Java + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace AppPlatform { + +using AttributeAccessInterface = app::AttributeAccessInterface; + +class ContentAppAttributeDelegate : public AttributeAccessInterface +{ +public: + ContentAppAttributeDelegate(jobject manager, ClusterId aClusterId) : + AttributeAccessInterface(Optional::Missing(), aClusterId) + { + if (manager == nullptr) + { + // To support the existing hardcoded sample apps. + return; + } + InitializeJNIObjects(manager); + } + + CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & aPath, chip::app::AttributeValueEncoder & aEncoder) override; + const char * Read(const chip::app::ConcreteReadAttributePath & aPath); + +private: + void InitializeJNIObjects(jobject manager) + { + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for ContentAppEndpointManager")); + + mContentAppEndpointManager = env->NewGlobalRef(manager); + VerifyOrReturn(mContentAppEndpointManager != nullptr, + ChipLogError(Zcl, "Failed to NewGlobalRef ContentAppEndpointManager")); + + jclass ContentAppEndpointManagerClass = env->GetObjectClass(manager); + VerifyOrReturn(ContentAppEndpointManagerClass != nullptr, + ChipLogError(Zcl, "Failed to get ContentAppEndpointManager Java class")); + + mReadAttributeMethod = env->GetMethodID(ContentAppEndpointManagerClass, "readAttribute", "(III)Ljava/lang/String;"); + if (mReadAttributeMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access ContentAppEndpointManager 'readAttribute' method"); + env->ExceptionClear(); + } + } + + jobject mContentAppEndpointManager = nullptr; + jmethodID mReadAttributeMethod = nullptr; +}; + +} // namespace AppPlatform +} // namespace chip diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index 1cc25f57ee6098..200c2cacb0f93c 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -79,8 +79,9 @@ void ContentAppCommandDelegate::InvokeCommand(CommandHandlerInterface::HandlerCo return; } - JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - UtfString jsonString(env, JsonToString(json).c_str()); + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + Json::Value value = json["value"]; + UtfString jsonString(env, JsonToString(value).c_str()); ChipLogProgress(Zcl, "ContentAppCommandDelegate::InvokeCommand send command being called with payload %s", JsonToString(json).c_str()); @@ -110,9 +111,8 @@ void ContentAppCommandDelegate::InvokeCommand(CommandHandlerInterface::HandlerCo void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::HandlerContext & handlerContext, const char * response) { Json::Reader reader; - Json::Value resJson; - reader.parse(response, resJson); - Json::Value value = resJson["value"]; + Json::Value value; + reader.parse(response, value); switch (handlerContext.mRequestPath.mClusterId) { diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java index 69a0eac364daa1..92c5e5243b85ad 100644 --- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java @@ -3,4 +3,6 @@ public interface ContentAppEndpointManager { public String sendCommand(int endpointId, int clusterId, int commandId, String commandPayload); + + public String readAttribute(int endpointId, int clusterId, int attributeId); } From 7b06ab4a70fa914b66b8cd156c42c8885953b871 Mon Sep 17 00:00:00 2001 From: Amit Jain Date: Fri, 24 Jun 2022 09:18:53 -0700 Subject: [PATCH 2/6] Remove unused code --- examples/tv-app/android/java/AppImpl.h | 6 +- .../java/ContentAppAttributeDelegate.cpp | 77 +------------------ .../java/ContentAppAttributeDelegate.h | 8 +- 3 files changed, 6 insertions(+), 85 deletions(-) diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h index c221c05e8917a3..e8321825db6cec 100644 --- a/examples/tv-app/android/java/AppImpl.h +++ b/examples/tv-app/android/java/AppImpl.h @@ -87,9 +87,9 @@ class DLL_EXPORT ContentAppImpl : public ContentApp mApplicationBasicDelegate(kCatalogVendorId, BuildAppId(vendorId), szVendorName, vendorId, szApplicationName, productId, szApplicationVersion), mAccountLoginDelegate(setupPIN), - mContentLauncherDelegate( - new ContentAppAttributeDelegate(manager, app::Clusters::ContentLauncher::Id), { "image/*", "video/*" }, - to_underlying(SupportedStreamingProtocol::kDash) | to_underlying(SupportedStreamingProtocol::kHls)), + mContentLauncherDelegate(new ContentAppAttributeDelegate(manager), { "image/*", "video/*" }, + to_underlying(SupportedStreamingProtocol::kDash) | + to_underlying(SupportedStreamingProtocol::kHls)), mTargetNavigatorDelegate({ "home", "search", "info", "guide", "menu" }, 0){}; virtual ~ContentAppImpl() {} diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp index 52fddc2c549ebc..3a133ddde19942 100644 --- a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp @@ -21,7 +21,6 @@ */ #include "ContentAppAttributeDelegate.h" - #include #include #include @@ -33,8 +32,7 @@ namespace chip { namespace AppPlatform { -using AttributeAccessInterface = app::AttributeAccessInterface; -using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; +using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; const char * ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttributePath & aPath) { @@ -53,87 +51,14 @@ const char * ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttr ChipLogError(Zcl, "Java exception in ContentAppAttributeDelegate::Read"); env->ExceptionDescribe(); env->ExceptionClear(); - // FormatResponseData(handlerContext, "{\"value\":{}}"); return ""; } const char * respStr = env->GetStringUTFChars(resp, 0); ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read got response %s", respStr); - // FormatResponseData(handlerContext, respStr); return respStr; } return ""; } -CHIP_ERROR ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttributePath & aPath, - chip::app::AttributeValueEncoder & aEncoder) -{ - if (aPath.mEndpointId >= FIXED_ENDPOINT_COUNT) - { - JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - - ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read being called for endpoint %d cluster %d attribute %d", - aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); - - jstring resp = - (jstring) env->CallObjectMethod(mContentAppEndpointManager, mReadAttributeMethod, static_cast(aPath.mEndpointId), - static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); - if (env->ExceptionCheck()) - { - ChipLogError(Zcl, "Java exception in ContentAppAttributeDelegate::Read"); - env->ExceptionDescribe(); - env->ExceptionClear(); - // FormatResponseData(handlerContext, "{\"value\":{}}"); - return CHIP_NO_ERROR; - } - const char * respStr = env->GetStringUTFChars(resp, 0); - ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read got response %s", respStr); - // FormatResponseData(handlerContext, respStr); - return CHIP_NO_ERROR; - } - return CHIP_NO_ERROR; -} - -/* -void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::HandlerContext & handlerContext, const char * response) -{ - Json::Reader reader; - Json::Value value; - reader.parse(response, value); - - switch (handlerContext.mRequestPath.mClusterId) - { - case app::Clusters::ContentLauncher::Id: { - LaunchResponseType launchResponse; - if (value["0"].empty()) - { - launchResponse.status = chip::app::Clusters::ContentLauncher::ContentLaunchStatusEnum::kAuthFailed; - } - else - { - launchResponse.status = static_cast(value["0"].asInt()); - if (!value["1"].empty()) - { - launchResponse.data = chip::MakeOptional(CharSpan::fromCharString(value["1"].asCString())); - } - } - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, launchResponse); - handlerContext.SetCommandHandled(); - break; - } - - // case app::Clusters::TargetNavigator::Id: - // break; - - // case app::Clusters::MediaPlayback::Id: - // break; - - // case app::Clusters::AccountLogin::Id: - // break; - default: - handlerContext.SetCommandNotHandled(); - } -} -*/ - } // namespace AppPlatform } // namespace chip diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.h b/examples/tv-app/android/java/ContentAppAttributeDelegate.h index d44973763b6ca8..592971de5ee60a 100644 --- a/examples/tv-app/android/java/ContentAppAttributeDelegate.h +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.h @@ -31,13 +31,10 @@ namespace chip { namespace AppPlatform { -using AttributeAccessInterface = app::AttributeAccessInterface; - -class ContentAppAttributeDelegate : public AttributeAccessInterface +class ContentAppAttributeDelegate { public: - ContentAppAttributeDelegate(jobject manager, ClusterId aClusterId) : - AttributeAccessInterface(Optional::Missing(), aClusterId) + ContentAppAttributeDelegate(jobject manager) { if (manager == nullptr) { @@ -47,7 +44,6 @@ class ContentAppAttributeDelegate : public AttributeAccessInterface InitializeJNIObjects(manager); } - CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & aPath, chip::app::AttributeValueEncoder & aEncoder) override; const char * Read(const chip::app::ConcreteReadAttributePath & aPath); private: From c6073c83da81d2bb2722f9b122adec098525702f Mon Sep 17 00:00:00 2001 From: Amit Jain Date: Fri, 24 Jun 2022 12:48:02 -0700 Subject: [PATCH 3/6] Fixed issues identified during review --- .../AppContentLauncherManager.cpp | 17 ++++----- .../AppContentLauncherManager.h | 4 +-- examples/tv-app/android/java/AppImpl.h | 7 ++-- .../java/ContentAppAttributeDelegate.cpp | 36 +++++++++---------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp index 5210ac127818fc..122442e5d6f8a0 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp @@ -27,7 +27,7 @@ using namespace chip::app::DataModel; using namespace chip::app::Clusters::ContentLauncher; using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate; -AppContentLauncherManager::AppContentLauncherManager(ContentAppAttributeDelegate * attributeDelegate, +AppContentLauncherManager::AppContentLauncherManager(ContentAppAttributeDelegate attributeDelegate, list acceptHeaderList, uint32_t supportedStreamingProtocols) : mAttributeDelegate(attributeDelegate) { @@ -85,7 +85,7 @@ CHIP_ERROR AppContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEn ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetAcceptHeaderList"); chip::app::ConcreteReadAttributePath aPath(mEndpointId, chip::app::Clusters::ContentLauncher::Id, chip::app::Clusters::ContentLauncher::Attributes::AcceptHeader::Id); - const char * resStr = mAttributeDelegate->Read(aPath); + const char * resStr = mAttributeDelegate.Read(aPath); ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response %s", resStr); if (resStr != nullptr && *resStr != 0) @@ -93,9 +93,10 @@ CHIP_ERROR AppContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEn Json::Reader reader; Json::Value value; reader.parse(resStr, value); - const char * attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::AcceptHeader::Id).c_str(); - ChipLogProgress( - Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", attrId); + std::string attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::AcceptHeader::Id).c_str(); + ChipLogProgress(Zcl, + "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", + attrId.c_str()); if (value[attrId].isArray()) { mAcceptHeaderList.clear(); @@ -121,7 +122,7 @@ uint32_t AppContentLauncherManager::HandleGetSupportedStreamingProtocols() ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols"); chip::app::ConcreteReadAttributePath aPath(mEndpointId, chip::app::Clusters::ContentLauncher::Id, chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id); - const char * resStr = mAttributeDelegate->Read(aPath); + const char * resStr = mAttributeDelegate.Read(aPath); ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response %s", resStr); if (resStr == nullptr || *resStr == 0) @@ -132,9 +133,9 @@ uint32_t AppContentLauncherManager::HandleGetSupportedStreamingProtocols() Json::Reader reader; Json::Value value; reader.parse(resStr, value); - const char * attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id).c_str(); + std::string attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id); ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", - attrId); + attrId.c_str()); if (!value[attrId].empty()) { uint32_t supportedStreamingProtocols = static_cast(value[attrId].asInt()); diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h index cce275315ae1ad..968dde81ff1eca 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h @@ -35,7 +35,7 @@ using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelega class AppContentLauncherManager : public ContentLauncherDelegate { public: - AppContentLauncherManager(ContentAppAttributeDelegate * attributeDelegate, std::list acceptHeaderList, + AppContentLauncherManager(ContentAppAttributeDelegate attributeDelegate, std::list acceptHeaderList, uint32_t supportedStreamingProtocols); void HandleLaunchContent(CommandResponseHelper & helper, @@ -60,5 +60,5 @@ class AppContentLauncherManager : public ContentLauncherDelegate // TODO: set this based upon meta data from app uint32_t mDynamicEndpointFeatureMap = 3; - ContentAppAttributeDelegate * mAttributeDelegate; + ContentAppAttributeDelegate mAttributeDelegate; }; diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h index e8321825db6cec..6a5f919224ef0d 100644 --- a/examples/tv-app/android/java/AppImpl.h +++ b/examples/tv-app/android/java/AppImpl.h @@ -86,10 +86,9 @@ class DLL_EXPORT ContentAppImpl : public ContentApp const char * szApplicationVersion, const char * setupPIN, jobject manager) : mApplicationBasicDelegate(kCatalogVendorId, BuildAppId(vendorId), szVendorName, vendorId, szApplicationName, productId, szApplicationVersion), - mAccountLoginDelegate(setupPIN), - mContentLauncherDelegate(new ContentAppAttributeDelegate(manager), { "image/*", "video/*" }, - to_underlying(SupportedStreamingProtocol::kDash) | - to_underlying(SupportedStreamingProtocol::kHls)), + mAccountLoginDelegate(setupPIN), mContentLauncherDelegate(ContentAppAttributeDelegate(manager), { "image/*", "video/*" }, + to_underlying(SupportedStreamingProtocol::kDash) | + to_underlying(SupportedStreamingProtocol::kHls)), mTargetNavigatorDelegate({ "home", "search", "info", "guide", "menu" }, 0){}; virtual ~ContentAppImpl() {} diff --git a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp index 3a133ddde19942..7fcf0b313a62a5 100644 --- a/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppAttributeDelegate.cpp @@ -36,28 +36,28 @@ using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::Launc const char * ContentAppAttributeDelegate::Read(const chip::app::ConcreteReadAttributePath & aPath) { - if (aPath.mEndpointId >= FIXED_ENDPOINT_COUNT) + if (aPath.mEndpointId < FIXED_ENDPOINT_COUNT) { - JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + return ""; + } + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read being called for endpoint %d cluster %d attribute %d", - aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read being called for endpoint %d cluster %d attribute %d", + aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); - jstring resp = - (jstring) env->CallObjectMethod(mContentAppEndpointManager, mReadAttributeMethod, static_cast(aPath.mEndpointId), - static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); - if (env->ExceptionCheck()) - { - ChipLogError(Zcl, "Java exception in ContentAppAttributeDelegate::Read"); - env->ExceptionDescribe(); - env->ExceptionClear(); - return ""; - } - const char * respStr = env->GetStringUTFChars(resp, 0); - ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read got response %s", respStr); - return respStr; + jstring resp = + (jstring) env->CallObjectMethod(mContentAppEndpointManager, mReadAttributeMethod, static_cast(aPath.mEndpointId), + static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); + if (env->ExceptionCheck()) + { + ChipLogError(Zcl, "Java exception in ContentAppAttributeDelegate::Read"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return ""; } - return ""; + const char * respStr = env->GetStringUTFChars(resp, 0); + ChipLogProgress(Zcl, "ContentAppAttributeDelegate::Read got response %s", respStr); + return respStr; } } // namespace AppPlatform From 3f4303db8139538c034e7be281ed252774d44cbc Mon Sep 17 00:00:00 2001 From: Amit Jain Date: Fri, 24 Jun 2022 23:22:18 -0700 Subject: [PATCH 4/6] restyle --- .../include/content-launcher/AppContentLauncherManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h index 968dde81ff1eca..bcce3add47f4a7 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.h @@ -18,8 +18,8 @@ #pragma once -#include #include "../../java/ContentAppAttributeDelegate.h" +#include #include using chip::CharSpan; From 75f1528f21ddee9357807d57f373eeff53968e49 Mon Sep 17 00:00:00 2001 From: Amit Jain Date: Tue, 28 Jun 2022 10:11:51 -0700 Subject: [PATCH 5/6] Failure handling and fixed typo --- .../AppContentLauncherManager.cpp | 25 +++++++++++-------- .../java/ContentAppCommandDelegate.cpp | 6 ++++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp index 122442e5d6f8a0..0f8486466c92aa 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp @@ -92,17 +92,19 @@ CHIP_ERROR AppContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEn { Json::Reader reader; Json::Value value; - reader.parse(resStr, value); - std::string attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::AcceptHeader::Id).c_str(); - ChipLogProgress(Zcl, - "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", - attrId.c_str()); - if (value[attrId].isArray()) + if (reader.parse(resStr, value)) { - mAcceptHeaderList.clear(); - for (Json::Value & entry : value[attrId]) + std::string attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::AcceptHeader::Id); + ChipLogProgress(Zcl, + "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", + attrId.c_str()); + if (value[attrId].isArray()) { - mAcceptHeaderList.push_back(entry.asString()); + mAcceptHeaderList.clear(); + for (Json::Value & entry : value[attrId]) + { + mAcceptHeaderList.push_back(entry.asString()); + } } } } @@ -132,7 +134,10 @@ uint32_t AppContentLauncherManager::HandleGetSupportedStreamingProtocols() Json::Reader reader; Json::Value value; - reader.parse(resStr, value); + if (!reader.parse(resStr, value)) + { + return mSupportedStreamingProtocols; + } std::string attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::Id); ChipLogProgress(Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", attrId.c_str()); diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index 200c2cacb0f93c..966f532ecd18ac 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -112,7 +112,11 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand { Json::Reader reader; Json::Value value; - reader.parse(response, value); + if (!reader.parse(response, value)) + { + handlerContext.SetCommandNotHandled(); + return; + } switch (handlerContext.mRequestPath.mClusterId) { From b4cde44fc181634635b788a80168b02a9e25752c Mon Sep 17 00:00:00 2001 From: Amit Jain Date: Tue, 28 Jun 2022 10:16:39 -0700 Subject: [PATCH 6/6] restyle fixes. --- .../include/content-launcher/AppContentLauncherManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp index 0f8486466c92aa..d898612977983a 100644 --- a/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp +++ b/examples/tv-app/android/include/content-launcher/AppContentLauncherManager.cpp @@ -95,9 +95,9 @@ CHIP_ERROR AppContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEn if (reader.parse(resStr, value)) { std::string attrId = to_string(chip::app::Clusters::ContentLauncher::Attributes::AcceptHeader::Id); - ChipLogProgress(Zcl, - "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", - attrId.c_str()); + ChipLogProgress( + Zcl, "AppContentLauncherManager::HandleGetSupportedStreamingProtocols response parsing done. reading attr %s", + attrId.c_str()); if (value[attrId].isArray()) { mAcceptHeaderList.clear();