| /* |
| * |
| * 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. |
| */ |
| |
| #include "ContentLauncherManager.h" |
| #include "TvApp-JNI.h" |
| #include <app-common/zap-generated/attributes/Accessors.h> |
| #include <app-common/zap-generated/ids/Clusters.h> |
| #include <app/util/config.h> |
| #include <jni.h> |
| #include <lib/core/CHIPSafeCasts.h> |
| #include <lib/support/CHIPJNIError.h> |
| #include <lib/support/JniReferences.h> |
| #include <lib/support/JniTypeWrappers.h> |
| |
| using namespace chip; |
| using namespace chip::app::DataModel; |
| using namespace chip::app::Clusters::ContentLauncher; |
| |
| void emberAfContentLauncherClusterInitCallback(EndpointId endpoint) |
| { |
| ChipLogProgress(Zcl, "TV Android App: ContentLauncher::PostClusterInit"); |
| TvAppJNIMgr().PostClusterInit(chip::app::Clusters::ContentLauncher::Id, endpoint); |
| } |
| |
| void ContentLauncherManager::NewManager(jint endpoint, jobject manager) |
| { |
| ChipLogProgress(Zcl, "TV Android App: ContentLauncher::SetDefaultDelegate"); |
| ContentLauncherManager * mgr = new ContentLauncherManager(); |
| mgr->InitializeWithObjects(manager); |
| chip::app::Clusters::ContentLauncher::SetDefaultDelegate(static_cast<EndpointId>(endpoint), mgr); |
| } |
| |
| void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper<LaunchResponseType> & helper, |
| const DecodableList<ParameterType> & parameterList, bool autoplay, |
| const chip::CharSpan & data, |
| const chip::Optional<PlaybackPreferencesType> playbackPreferences, |
| bool useCurrentContext) |
| { |
| DeviceLayer::StackUnlock unlock; |
| Commands::LauncherResponse::Type response; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::LaunchContent"); |
| VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); |
| VerifyOrExit(mLaunchContentMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| |
| env->ExceptionClear(); |
| { |
| UtfString jData(env, data); |
| |
| // Todo: make parameterList java |
| jobjectArray parameterArray = nullptr; |
| |
| jobject resp = env->CallObjectMethod(mContentLauncherManagerObject.ObjectRef(), mLaunchContentMethod, parameterArray, |
| static_cast<jboolean>(autoplay), jData.jniValue()); |
| if (env->ExceptionCheck()) |
| { |
| ChipLogError(Zcl, "Java exception in ContentLauncherManager::LaunchContent"); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| err = CHIP_ERROR_INCORRECT_STATE; |
| goto exit; |
| } |
| |
| VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT); |
| jclass respCls = env->GetObjectClass(resp); |
| jfieldID statusFid = env->GetFieldID(respCls, "status", "I"); |
| VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); |
| jint status = env->GetIntField(resp, statusFid); |
| |
| jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;"); |
| VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); |
| jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid); |
| JniUtfString dataStr(env, jdataStr); |
| |
| response.status = static_cast<chip::app::Clusters::ContentLauncher::StatusEnum>(status); |
| response.data = chip::Optional<CharSpan>(dataStr.charSpan()); |
| |
| err = helper.Success(response); |
| } |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(Zcl, "ContentLauncherManager::LaunchContent status error: %s", err.AsString()); |
| } |
| } |
| |
| void ContentLauncherManager::HandleLaunchUrl(CommandResponseHelper<LaunchResponseType> & helper, const chip::CharSpan & contentUrl, |
| const chip::CharSpan & displayString, |
| const BrandingInformationType & brandingInformation) |
| { |
| DeviceLayer::StackUnlock unlock; |
| Commands::LauncherResponse::Type response; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::LaunchContentUrl"); |
| VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); |
| VerifyOrExit(mLaunchUrlMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| |
| env->ExceptionClear(); |
| |
| { |
| UtfString jContentUrl(env, contentUrl); |
| UtfString jDisplayString(env, displayString); |
| |
| // Todo: make brandingInformation java |
| jobjectArray branding = nullptr; |
| |
| jobject resp = env->CallObjectMethod(mContentLauncherManagerObject.ObjectRef(), mLaunchUrlMethod, jContentUrl.jniValue(), |
| jDisplayString.jniValue(), branding); |
| if (env->ExceptionCheck()) |
| { |
| ChipLogError(Zcl, "Java exception in ContentLauncherManager::LaunchUrl"); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| err = CHIP_ERROR_INCORRECT_STATE; |
| goto exit; |
| } |
| |
| VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT); |
| jclass respCls = env->GetObjectClass(resp); |
| jfieldID statusFid = env->GetFieldID(respCls, "status", "I"); |
| VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); |
| jint status = env->GetIntField(resp, statusFid); |
| |
| jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;"); |
| VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); |
| jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid); |
| JniUtfString dataStr(env, jdataStr); |
| |
| response.status = static_cast<chip::app::Clusters::ContentLauncher::StatusEnum>(status); |
| response.data = chip::Optional<CharSpan>(dataStr.charSpan()); |
| |
| err = helper.Success(response); |
| } |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(Zcl, "ContentLauncherManager::LaunchUrl status error: %s", err.AsString()); |
| } |
| } |
| |
| CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder) |
| { |
| DeviceLayer::StackUnlock unlock; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| std::list<std::string> acceptedHeadersList; |
| VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NO_ENV, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::GetAcceptHeader"); |
| VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); |
| VerifyOrExit(mGetAcceptHeaderMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| |
| env->ExceptionClear(); |
| |
| return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR { |
| jobjectArray acceptedHeadersArray = |
| (jobjectArray) env->CallObjectMethod(mContentLauncherManagerObject.ObjectRef(), mGetAcceptHeaderMethod); |
| if (env->ExceptionCheck()) |
| { |
| ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptHeader"); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| return CHIP_ERROR_INCORRECT_STATE; |
| } |
| |
| jint size = env->GetArrayLength(acceptedHeadersArray); |
| for (int i = 0; i < size; i++) |
| { |
| jstring jAcceptedHeader = (jstring) env->GetObjectArrayElement(acceptedHeadersArray, i); |
| JniUtfString acceptedHeader(env, jAcceptedHeader); |
| ReturnErrorOnFailure(encoder.Encode(acceptedHeader.charSpan())); |
| } |
| |
| return CHIP_NO_ERROR; |
| }); |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(Zcl, "ContentLauncherManager::GetAcceptHeader status error: %s", err.AsString()); |
| } |
| |
| return err; |
| } |
| |
| uint32_t ContentLauncherManager::HandleGetSupportedStreamingProtocols() |
| { |
| DeviceLayer::StackUnlock unlock; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| uint32_t supportedStreamingProtocols = 0; |
| VerifyOrReturnValue(env != nullptr, 0, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::GetSupportedStreamingProtocols"); |
| VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); |
| VerifyOrExit(mGetSupportedStreamingProtocolsMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| |
| env->ExceptionClear(); |
| |
| { |
| jlong jSupportedStreamingProtocols = |
| env->CallLongMethod(mContentLauncherManagerObject.ObjectRef(), 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")); |
| |
| VerifyOrReturn(mContentLauncherManagerObject.Init(managerObject) == CHIP_NO_ERROR, |
| ChipLogError(Zcl, "Failed to init mContentLauncherManagerObject")); |
| |
| 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 ContentLauncherManager 'getInputList' method"); |
| env->ExceptionClear(); |
| } |
| |
| mGetSupportedStreamingProtocolsMethod = env->GetMethodID(ContentLauncherClass, "getSupportedStreamingProtocols", "()J"); |
| if (mGetSupportedStreamingProtocolsMethod == nullptr) |
| { |
| ChipLogError(Zcl, "Failed to access ContentLauncherManager 'getSupportedStreamingProtocols' method"); |
| env->ExceptionClear(); |
| } |
| |
| mLaunchContentMethod = env->GetMethodID(ContentLauncherClass, "launchContent", |
| "([Lcom/matter/tv/server/tvapp/ContentLaunchSearchParameter;ZLjava/lang/String;)Lcom/" |
| "matter/tv/server/tvapp/ContentLaunchResponse;"); |
| if (mLaunchContentMethod == nullptr) |
| { |
| ChipLogError(Zcl, "Failed to access ContentLauncherManager 'launchContent' method"); |
| env->ExceptionClear(); |
| } |
| |
| mLaunchUrlMethod = env->GetMethodID(ContentLauncherClass, "launchUrl", |
| "(Ljava/lang/String;Ljava/lang/String;Lcom/matter/tv/server/tvapp/" |
| "ContentLaunchBrandingInformation;)Lcom/matter/tv/server/tvapp/ContentLaunchResponse;"); |
| if (mLaunchUrlMethod == nullptr) |
| { |
| ChipLogError(AppServer, "Failed to access 'launchUrl' method"); |
| env->ExceptionClear(); |
| } |
| |
| mContentReplicationRequestMethod = |
| env->GetMethodID(ContentLauncherClass, "contentReplicationRequest", "()Lcom/matter/tv/server/tvapp/ContentLaunchResponse;"); |
| if (mContentReplicationRequestMethod == nullptr) |
| { |
| ChipLogError(AppServer, "Failed to access 'contentReplicationRequest' method"); |
| env->ExceptionClear(); |
| } |
| |
| mPlayPresetMethod = |
| env->GetMethodID(ContentLauncherClass, "playPreset", "(I)Lcom/matter/tv/server/tvapp/ContentLaunchResponse;"); |
| if (mPlayPresetMethod == nullptr) |
| { |
| ChipLogError(AppServer, "Failed to access 'playPreset' method"); |
| env->ExceptionClear(); |
| } |
| |
| mGetMovableMethod = env->GetMethodID(ContentLauncherClass, "getMovable", "()Z"); |
| if (mGetMovableMethod == nullptr) |
| { |
| ChipLogError(AppServer, "Failed to access 'getMovable' method"); |
| env->ExceptionClear(); |
| } |
| |
| mGetPresetsMethod = env->GetMethodID(ContentLauncherClass, "getPresets", "()[Lcom/matter/tv/server/tvapp/ContentLaunchPreset;"); |
| if (mGetPresetsMethod == nullptr) |
| { |
| ChipLogError(AppServer, "Failed to access 'getPresets' method"); |
| env->ExceptionClear(); |
| } |
| } |
| |
| void ContentLauncherManager::HandleContentReplicationRequest(CommandResponseHelper<ContentReplicationResponseType> & helper) |
| { |
| DeviceLayer::StackUnlock unlock; |
| Commands::ContentReplicationResponse::Type response; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::ContentReplicationRequest"); |
| VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); |
| VerifyOrExit(mContentReplicationRequestMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| |
| env->ExceptionClear(); |
| { |
| jobject resp = env->CallObjectMethod(mContentLauncherManagerObject.ObjectRef(), mContentReplicationRequestMethod); |
| if (env->ExceptionCheck()) |
| { |
| ChipLogError(Zcl, "Java exception in ContentLauncherManager::ContentReplicationRequest"); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| err = CHIP_ERROR_INCORRECT_STATE; |
| goto exit; |
| } |
| |
| jclass convergentLaunchResponseClass = env->GetObjectClass(resp); |
| jfieldID statusField = env->GetFieldID(convergentLaunchResponseClass, "status", "I"); |
| jint status = env->GetIntField(resp, statusField); |
| response.status = static_cast<chip::app::Clusters::ContentLauncher::StatusEnum>(status); |
| } |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(Zcl, "ContentLauncherManager::ContentReplicationRequest status error: %s", err.AsString()); |
| response.status = chip::app::Clusters::ContentLauncher::StatusEnum::kURLNotAvailable; |
| } |
| LogErrorOnFailure(helper.Success(response)); |
| } |
| |
| void ContentLauncherManager::HandlePlayPreset(chip::app::CommandHandler * commandObj, |
| const chip::app::ConcreteCommandPath & commandPath, uint16_t presetID) |
| { |
| DeviceLayer::StackUnlock unlock; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::PlayPreset"); |
| VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); |
| VerifyOrExit(mPlayPresetMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| |
| env->ExceptionClear(); |
| { |
| jobject resp = |
| env->CallObjectMethod(mContentLauncherManagerObject.ObjectRef(), mPlayPresetMethod, static_cast<jint>(presetID)); |
| if (env->ExceptionCheck()) |
| { |
| ChipLogError(Zcl, "Java exception in ContentLauncherManager::PlayPreset"); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| err = CHIP_ERROR_INCORRECT_STATE; |
| goto exit; |
| } |
| |
| jclass responseClass = env->GetObjectClass(resp); |
| jfieldID statusField = env->GetFieldID(responseClass, "status", "I"); |
| jint status = env->GetIntField(resp, statusField); |
| |
| if (status == 0) |
| { |
| commandObj->AddStatus(commandPath, chip::Protocols::InteractionModel::Status::Success); |
| } |
| else |
| { |
| commandObj->AddStatus(commandPath, chip::Protocols::InteractionModel::Status::Failure); |
| } |
| return; |
| } |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(Zcl, "ContentLauncherManager::PlayPreset status error: %s", err.AsString()); |
| } |
| commandObj->AddStatus(commandPath, chip::Protocols::InteractionModel::Status::Failure); |
| } |
| |
| bool ContentLauncherManager::HandleGetMovable() |
| { |
| DeviceLayer::StackUnlock unlock; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| VerifyOrReturnValue(env != nullptr, false, ChipLogError(Zcl, "Could not get JNIEnv for current thread")); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::GetMovable"); |
| VerifyOrReturnValue(mContentLauncherManagerObject.HasValidObjectRef(), false); |
| VerifyOrReturnValue(mGetMovableMethod != nullptr, false); |
| |
| env->ExceptionClear(); |
| jboolean movable = env->CallBooleanMethod(mContentLauncherManagerObject.ObjectRef(), mGetMovableMethod); |
| if (env->ExceptionCheck()) |
| { |
| ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetMovable"); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| return false; |
| } |
| return static_cast<bool>(movable); |
| } |
| |
| CHIP_ERROR ContentLauncherManager::HandleGetPresets(chip::app::AttributeValueEncoder & aEncoder) |
| { |
| DeviceLayer::StackUnlock unlock; |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); |
| VerifyOrReturnError(env != nullptr, CHIP_ERROR_INCORRECT_STATE); |
| JniLocalReferenceScope scope(env); |
| |
| ChipLogProgress(Zcl, "Received ContentLauncherManager::GetPresets"); |
| VerifyOrExit(mContentLauncherManagerObject.HasValidObjectRef(), err = CHIP_ERROR_INCORRECT_STATE); |
| VerifyOrExit(mGetPresetsMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| |
| env->ExceptionClear(); |
| |
| return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR { |
| jobjectArray presetsArray = |
| (jobjectArray) env->CallObjectMethod(mContentLauncherManagerObject.ObjectRef(), mGetPresetsMethod); |
| if (env->ExceptionCheck()) |
| { |
| ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetPresets"); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| return CHIP_ERROR_INCORRECT_STATE; |
| } |
| |
| jint size = env->GetArrayLength(presetsArray); |
| if (size > 0) |
| { |
| jobject firstObj = env->GetObjectArrayElement(presetsArray, 0); |
| jclass presetClass = env->GetObjectClass(firstObj); |
| jfieldID idField = env->GetFieldID(presetClass, "presetID", "I"); |
| jfieldID nameField = env->GetFieldID(presetClass, "presetName", "Ljava/lang/String;"); |
| |
| for (int i = 0; i < size; i++) |
| { |
| jobject presetObj = (i == 0) ? firstObj : env->GetObjectArrayElement(presetsArray, i); |
| jint presetId = env->GetIntField(presetObj, idField); |
| jstring jPresetName = (jstring) env->GetObjectField(presetObj, nameField); |
| JniUtfString presetName(env, jPresetName); |
| |
| chip::app::Clusters::ContentLauncher::Structs::ContentPresetStruct::Type preset; |
| preset.presetID = static_cast<uint8_t>(presetId); |
| preset.presetName = presetName.charSpan(); |
| ReturnErrorOnFailure(encoder.Encode(preset)); |
| } |
| } |
| |
| return CHIP_NO_ERROR; |
| }); |
| |
| exit: |
| if (err != CHIP_NO_ERROR) |
| { |
| ChipLogError(Zcl, "ContentLauncherManager::GetPresets status error: %s", err.AsString()); |
| } |
| return err; |
| } |
| |
| uint32_t ContentLauncherManager::GetFeatureMap(chip::EndpointId endpoint) |
| { |
| uint32_t featureMap = 0; |
| Attributes::FeatureMap::Get(endpoint, &featureMap); |
| return featureMap; |
| } |
| |
| uint16_t ContentLauncherManager::GetClusterRevision(chip::EndpointId endpoint) |
| { |
| if (endpoint >= MATTER_DM_CONTENT_LAUNCHER_CLUSTER_SERVER_ENDPOINT_COUNT) |
| { |
| return chip::app::Clusters::ContentLauncher::kRevision; |
| } |
| |
| uint16_t clusterRevision = 0; |
| bool success = |
| (Attributes::ClusterRevision::Get(endpoint, &clusterRevision) == chip::Protocols::InteractionModel::Status::Success); |
| if (!success) |
| { |
| ChipLogError(Zcl, "ContentLauncherManager::GetClusterRevision error reading cluster revision"); |
| } |
| return clusterRevision; |
| } |