ContentLauncherManager.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. *
  3. * Copyright (c) 2021 Project CHIP Authors
  4. * All rights reserved.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "ContentLauncherManager.h"
  19. #include "TvApp-JNI.h"
  20. #include <app-common/zap-generated/attributes/Accessors.h>
  21. #include <app-common/zap-generated/ids/Clusters.h>
  22. #include <jni.h>
  23. #include <lib/core/CHIPSafeCasts.h>
  24. #include <lib/support/CHIPJNIError.h>
  25. #include <lib/support/JniReferences.h>
  26. #include <lib/support/JniTypeWrappers.h>
  27. using namespace std;
  28. using namespace chip;
  29. using namespace chip::app::DataModel;
  30. using namespace chip::app::Clusters::ContentLauncher;
  31. void emberAfContentLauncherClusterInitCallback(EndpointId endpoint)
  32. {
  33. ChipLogProgress(Zcl, "TV Android App: ContentLauncher::PostClusterInit");
  34. TvAppJNIMgr().PostClusterInit(chip::app::Clusters::ContentLauncher::Id, endpoint);
  35. }
  36. void ContentLauncherManager::NewManager(jint endpoint, jobject manager)
  37. {
  38. ChipLogProgress(Zcl, "TV Android App: ContentLauncher::SetDefaultDelegate");
  39. ContentLauncherManager * mgr = new ContentLauncherManager();
  40. mgr->InitializeWithObjects(manager);
  41. chip::app::Clusters::ContentLauncher::SetDefaultDelegate(static_cast<EndpointId>(endpoint), mgr);
  42. }
  43. void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper<LaunchResponseType> & helper,
  44. const DecodableList<ParameterType> & parameterList, bool autoplay,
  45. const chip::CharSpan & data)
  46. {
  47. Commands::LauncherResponse::Type response;
  48. CHIP_ERROR err = CHIP_NO_ERROR;
  49. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  50. ChipLogProgress(Zcl, "Received ContentLauncherManager::LaunchContent");
  51. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  52. VerifyOrExit(mLaunchContentMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  53. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  54. {
  55. UtfString jData(env, data);
  56. // Todo: make parameterList java
  57. jobjectArray parameterArray = nullptr;
  58. jobject resp = env->CallObjectMethod(mContentLauncherManagerObject, mLaunchContentMethod, parameterArray,
  59. static_cast<jboolean>(autoplay), jData.jniValue());
  60. if (env->ExceptionCheck())
  61. {
  62. ChipLogError(Zcl, "Java exception in ContentLauncherManager::LaunchContent");
  63. env->ExceptionDescribe();
  64. env->ExceptionClear();
  65. err = CHIP_ERROR_INCORRECT_STATE;
  66. goto exit;
  67. }
  68. VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
  69. jclass respCls = env->GetObjectClass(resp);
  70. jfieldID statusFid = env->GetFieldID(respCls, "status", "I");
  71. VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  72. jint status = env->GetIntField(resp, statusFid);
  73. jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;");
  74. VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  75. jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid);
  76. JniUtfString dataStr(env, jdataStr);
  77. response.status = static_cast<chip::app::Clusters::ContentLauncher::ContentLaunchStatusEnum>(status);
  78. response.data = chip::Optional<CharSpan>(dataStr.charSpan());
  79. err = helper.Success(response);
  80. }
  81. exit:
  82. if (err != CHIP_NO_ERROR)
  83. {
  84. ChipLogError(Zcl, "ContentLauncherManager::LaunchContent status error: %s", err.AsString());
  85. }
  86. }
  87. void ContentLauncherManager::HandleLaunchUrl(CommandResponseHelper<LaunchResponseType> & helper, const chip::CharSpan & contentUrl,
  88. const chip::CharSpan & displayString,
  89. const BrandingInformationType & brandingInformation)
  90. {
  91. Commands::LauncherResponse::Type response;
  92. CHIP_ERROR err = CHIP_NO_ERROR;
  93. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  94. ChipLogProgress(Zcl, "Received ContentLauncherManager::LaunchContentUrl");
  95. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  96. VerifyOrExit(mLaunchUrlMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  97. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  98. {
  99. UtfString jContentUrl(env, contentUrl);
  100. UtfString jDisplayString(env, displayString);
  101. // Todo: make brandingInformation java
  102. jobjectArray branding = nullptr;
  103. jobject resp = env->CallObjectMethod(mContentLauncherManagerObject, mLaunchUrlMethod, jContentUrl.jniValue(),
  104. jDisplayString.jniValue(), branding);
  105. if (env->ExceptionCheck())
  106. {
  107. ChipLogError(Zcl, "Java exception in ContentLauncherManager::LaunchUrl");
  108. env->ExceptionDescribe();
  109. env->ExceptionClear();
  110. err = CHIP_ERROR_INCORRECT_STATE;
  111. goto exit;
  112. }
  113. VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
  114. jclass respCls = env->GetObjectClass(resp);
  115. jfieldID statusFid = env->GetFieldID(respCls, "status", "I");
  116. VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  117. jint status = env->GetIntField(resp, statusFid);
  118. jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;");
  119. VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  120. jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid);
  121. JniUtfString dataStr(env, jdataStr);
  122. response.status = static_cast<chip::app::Clusters::ContentLauncher::ContentLaunchStatusEnum>(status);
  123. response.data = chip::Optional<CharSpan>(dataStr.charSpan());
  124. err = helper.Success(response);
  125. }
  126. exit:
  127. if (err != CHIP_NO_ERROR)
  128. {
  129. ChipLogError(Zcl, "ContentLauncherManager::LaunchUrl status error: %s", err.AsString());
  130. }
  131. }
  132. CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder)
  133. {
  134. CHIP_ERROR err = CHIP_NO_ERROR;
  135. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  136. std::list<std::string> acceptedHeadersList;
  137. ChipLogProgress(Zcl, "Received ContentLauncherManager::GetAcceptHeader");
  138. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  139. VerifyOrExit(mGetAcceptHeaderMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  140. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  141. return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR {
  142. jobjectArray acceptedHeadersArray =
  143. (jobjectArray) env->CallObjectMethod(mContentLauncherManagerObject, mGetAcceptHeaderMethod);
  144. if (env->ExceptionCheck())
  145. {
  146. ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptHeader");
  147. env->ExceptionDescribe();
  148. env->ExceptionClear();
  149. return CHIP_ERROR_INCORRECT_STATE;
  150. }
  151. jint size = env->GetArrayLength(acceptedHeadersArray);
  152. for (int i = 0; i < size; i++)
  153. {
  154. jstring jAcceptedHeader = (jstring) env->GetObjectArrayElement(acceptedHeadersArray, i);
  155. JniUtfString acceptedHeader(env, jAcceptedHeader);
  156. ReturnErrorOnFailure(encoder.Encode(acceptedHeader.charSpan()));
  157. }
  158. return CHIP_NO_ERROR;
  159. });
  160. exit:
  161. if (err != CHIP_NO_ERROR)
  162. {
  163. ChipLogError(Zcl, "ContentLauncherManager::GetAcceptHeader status error: %s", err.AsString());
  164. }
  165. return err;
  166. }
  167. uint32_t ContentLauncherManager::HandleGetSupportedStreamingProtocols()
  168. {
  169. CHIP_ERROR err = CHIP_NO_ERROR;
  170. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  171. uint32_t supportedStreamingProtocols = 0;
  172. ChipLogProgress(Zcl, "Received ContentLauncherManager::GetSupportedStreamingProtocols");
  173. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  174. VerifyOrExit(mGetSupportedStreamingProtocolsMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  175. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  176. {
  177. jlong jSupportedStreamingProtocols =
  178. env->CallLongMethod(mContentLauncherManagerObject, mGetSupportedStreamingProtocolsMethod);
  179. supportedStreamingProtocols = (uint32_t) jSupportedStreamingProtocols;
  180. if (env->ExceptionCheck())
  181. {
  182. ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptHeader");
  183. env->ExceptionDescribe();
  184. env->ExceptionClear();
  185. err = CHIP_ERROR_INCORRECT_STATE;
  186. goto exit;
  187. }
  188. }
  189. exit:
  190. if (err != CHIP_NO_ERROR)
  191. {
  192. ChipLogError(Zcl, "ContentLauncherManager::GetSupportedStreamingProtocols status error: %s", err.AsString());
  193. }
  194. return supportedStreamingProtocols;
  195. }
  196. void ContentLauncherManager::InitializeWithObjects(jobject managerObject)
  197. {
  198. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  199. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for ContentLauncherManager"));
  200. mContentLauncherManagerObject = env->NewGlobalRef(managerObject);
  201. VerifyOrReturn(mContentLauncherManagerObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef ContentLauncherManager"));
  202. jclass ContentLauncherClass = env->GetObjectClass(managerObject);
  203. VerifyOrReturn(ContentLauncherClass != nullptr, ChipLogError(Zcl, "Failed to get ContentLauncherManager Java class"));
  204. mGetAcceptHeaderMethod = env->GetMethodID(ContentLauncherClass, "getAcceptHeader", "()[Ljava/lang/String;");
  205. if (mGetAcceptHeaderMethod == nullptr)
  206. {
  207. ChipLogError(Zcl, "Failed to access ContentLauncherManager 'getInputList' method");
  208. env->ExceptionClear();
  209. }
  210. mGetSupportedStreamingProtocolsMethod = env->GetMethodID(ContentLauncherClass, "getSupportedStreamingProtocols", "()J");
  211. if (mGetSupportedStreamingProtocolsMethod == nullptr)
  212. {
  213. ChipLogError(Zcl, "Failed to access ContentLauncherManager 'getSupportedStreamingProtocols' method");
  214. env->ExceptionClear();
  215. }
  216. mLaunchContentMethod = env->GetMethodID(ContentLauncherClass, "launchContent",
  217. "([Lcom/matter/tv/server/tvapp/ContentLaunchSearchParameter;ZLjava/lang/String;)Lcom/"
  218. "matter/tv/server/tvapp/ContentLaunchResponse;");
  219. if (mLaunchContentMethod == nullptr)
  220. {
  221. ChipLogError(Zcl, "Failed to access ContentLauncherManager 'launchContent' method");
  222. env->ExceptionClear();
  223. }
  224. mLaunchUrlMethod = env->GetMethodID(ContentLauncherClass, "launchUrl",
  225. "(Ljava/lang/String;Ljava/lang/String;Lcom/matter/tv/server/tvapp/"
  226. "ContentLaunchBrandingInformation;)Lcom/matter/tv/server/tvapp/ContentLaunchResponse;");
  227. if (mLaunchUrlMethod == nullptr)
  228. {
  229. ChipLogError(AppServer, "Failed to access 'launchUrl' method");
  230. env->ExceptionClear();
  231. }
  232. }
  233. uint32_t ContentLauncherManager::GetFeatureMap(chip::EndpointId endpoint)
  234. {
  235. uint32_t featureMap = 0;
  236. Attributes::FeatureMap::Get(endpoint, &featureMap);
  237. return featureMap;
  238. }