ContentLauncherManager.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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/ids/Clusters.h>
  21. #include <jni.h>
  22. #include <lib/core/CHIPSafeCasts.h>
  23. #include <lib/support/CHIPJNIError.h>
  24. #include <lib/support/JniReferences.h>
  25. #include <lib/support/JniTypeWrappers.h>
  26. using namespace std;
  27. using namespace chip;
  28. using namespace chip::app::DataModel;
  29. using namespace chip::app::Clusters::ContentLauncher;
  30. void emberAfContentLauncherClusterInitCallback(EndpointId endpoint)
  31. {
  32. ChipLogProgress(Zcl, "TV Android App: ContentLauncher::PostClusterInit");
  33. TvAppJNIMgr().PostClusterInit(chip::app::Clusters::ContentLauncher::Id, endpoint);
  34. }
  35. void ContentLauncherManager::NewManager(jint endpoint, jobject manager)
  36. {
  37. ChipLogProgress(Zcl, "TV Android App: ContentLauncher::SetDefaultDelegate");
  38. ContentLauncherManager * mgr = new ContentLauncherManager();
  39. mgr->InitializeWithObjects(manager);
  40. chip::app::Clusters::ContentLauncher::SetDefaultDelegate(static_cast<EndpointId>(endpoint), mgr);
  41. }
  42. void ContentLauncherManager::HandleLaunchContent(CommandResponseHelper<LaunchResponseType> & helper,
  43. const DecodableList<ParameterType> & parameterList, bool autoplay,
  44. const chip::CharSpan & data)
  45. {
  46. Commands::LaunchResponse::Type response;
  47. CHIP_ERROR err = CHIP_NO_ERROR;
  48. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  49. ChipLogProgress(Zcl, "Received ContentLauncherManager::LaunchContent");
  50. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  51. VerifyOrExit(mLaunchContentMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  52. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  53. {
  54. UtfString jData(env, data);
  55. // Todo: make parameterList java
  56. jobjectArray parameterArray = nullptr;
  57. jobject resp = env->CallObjectMethod(mContentLauncherManagerObject, mLaunchContentMethod, parameterArray,
  58. static_cast<jboolean>(autoplay), jData.jniValue());
  59. if (env->ExceptionCheck())
  60. {
  61. ChipLogError(Zcl, "Java exception in ContentLauncherManager::LaunchContent");
  62. env->ExceptionDescribe();
  63. env->ExceptionClear();
  64. err = CHIP_ERROR_INCORRECT_STATE;
  65. goto exit;
  66. }
  67. VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
  68. jclass respCls = env->GetObjectClass(resp);
  69. jfieldID statusFid = env->GetFieldID(respCls, "status", "I");
  70. VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  71. jint status = env->GetIntField(resp, statusFid);
  72. jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;");
  73. VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  74. jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid);
  75. JniUtfString dataStr(env, jdataStr);
  76. response.status = static_cast<chip::app::Clusters::ContentLauncher::ContentLaunchStatusEnum>(status);
  77. response.data = chip::Optional<CharSpan>(dataStr.charSpan());
  78. err = helper.Success(response);
  79. }
  80. exit:
  81. if (err != CHIP_NO_ERROR)
  82. {
  83. ChipLogError(Zcl, "ContentLauncherManager::LaunchContent status error: %s", err.AsString());
  84. }
  85. }
  86. void ContentLauncherManager::HandleLaunchUrl(CommandResponseHelper<LaunchResponseType> & helper, const chip::CharSpan & contentUrl,
  87. const chip::CharSpan & displayString,
  88. const BrandingInformationType & brandingInformation)
  89. {
  90. Commands::LaunchResponse::Type response;
  91. CHIP_ERROR err = CHIP_NO_ERROR;
  92. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  93. ChipLogProgress(Zcl, "Received ContentLauncherManager::LaunchContentUrl");
  94. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  95. VerifyOrExit(mLaunchUrlMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  96. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  97. {
  98. UtfString jContentUrl(env, contentUrl);
  99. UtfString jDisplayString(env, displayString);
  100. // Todo: make brandingInformation java
  101. jobjectArray branding = nullptr;
  102. jobject resp = env->CallObjectMethod(mContentLauncherManagerObject, mLaunchUrlMethod, jContentUrl.jniValue(),
  103. jDisplayString.jniValue(), branding);
  104. if (env->ExceptionCheck())
  105. {
  106. ChipLogError(Zcl, "Java exception in ContentLauncherManager::LaunchUrl");
  107. env->ExceptionDescribe();
  108. env->ExceptionClear();
  109. err = CHIP_ERROR_INCORRECT_STATE;
  110. goto exit;
  111. }
  112. VerifyOrExit(resp != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT);
  113. jclass respCls = env->GetObjectClass(resp);
  114. jfieldID statusFid = env->GetFieldID(respCls, "status", "I");
  115. VerifyOrExit(statusFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  116. jint status = env->GetIntField(resp, statusFid);
  117. jfieldID dataFid = env->GetFieldID(respCls, "data", "Ljava/lang/String;");
  118. VerifyOrExit(dataFid != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND);
  119. jstring jdataStr = (jstring) env->GetObjectField(resp, dataFid);
  120. JniUtfString dataStr(env, jdataStr);
  121. response.status = static_cast<chip::app::Clusters::ContentLauncher::ContentLaunchStatusEnum>(status);
  122. response.data = chip::Optional<CharSpan>(dataStr.charSpan());
  123. err = helper.Success(response);
  124. }
  125. exit:
  126. if (err != CHIP_NO_ERROR)
  127. {
  128. ChipLogError(Zcl, "ContentLauncherManager::LaunchUrl status error: %s", err.AsString());
  129. }
  130. }
  131. CHIP_ERROR ContentLauncherManager::HandleGetAcceptHeaderList(AttributeValueEncoder & aEncoder)
  132. {
  133. CHIP_ERROR err = CHIP_NO_ERROR;
  134. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  135. std::list<std::string> acceptedHeadersList;
  136. ChipLogProgress(Zcl, "Received ContentLauncherManager::GetAcceptHeader");
  137. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  138. VerifyOrExit(mGetAcceptHeaderMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  139. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  140. return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR {
  141. jobjectArray acceptedHeadersArray =
  142. (jobjectArray) env->CallObjectMethod(mContentLauncherManagerObject, mGetAcceptHeaderMethod);
  143. if (env->ExceptionCheck())
  144. {
  145. ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptHeader");
  146. env->ExceptionDescribe();
  147. env->ExceptionClear();
  148. return CHIP_ERROR_INCORRECT_STATE;
  149. }
  150. jint size = env->GetArrayLength(acceptedHeadersArray);
  151. for (int i = 0; i < size; i++)
  152. {
  153. jstring jAcceptedHeader = (jstring) env->GetObjectArrayElement(acceptedHeadersArray, i);
  154. JniUtfString acceptedHeader(env, jAcceptedHeader);
  155. ReturnErrorOnFailure(encoder.Encode(acceptedHeader.charSpan()));
  156. }
  157. return CHIP_NO_ERROR;
  158. });
  159. exit:
  160. if (err != CHIP_NO_ERROR)
  161. {
  162. ChipLogError(Zcl, "ContentLauncherManager::GetAcceptHeader status error: %s", err.AsString());
  163. }
  164. return err;
  165. }
  166. uint32_t ContentLauncherManager::HandleGetSupportedStreamingProtocols()
  167. {
  168. CHIP_ERROR err = CHIP_NO_ERROR;
  169. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  170. uint32_t supportedStreamingProtocols = 0;
  171. ChipLogProgress(Zcl, "Received ContentLauncherManager::GetSupportedStreamingProtocols");
  172. VerifyOrExit(mContentLauncherManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  173. VerifyOrExit(mGetSupportedStreamingProtocolsMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  174. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  175. {
  176. jlong jSupportedStreamingProtocols =
  177. env->CallLongMethod(mContentLauncherManagerObject, mGetSupportedStreamingProtocolsMethod);
  178. supportedStreamingProtocols = (uint32_t) jSupportedStreamingProtocols;
  179. if (env->ExceptionCheck())
  180. {
  181. ChipLogError(Zcl, "Java exception in ContentLauncherManager::GetAcceptHeader");
  182. env->ExceptionDescribe();
  183. env->ExceptionClear();
  184. err = CHIP_ERROR_INCORRECT_STATE;
  185. goto exit;
  186. }
  187. }
  188. exit:
  189. if (err != CHIP_NO_ERROR)
  190. {
  191. ChipLogError(Zcl, "ContentLauncherManager::GetSupportedStreamingProtocols status error: %s", err.AsString());
  192. }
  193. return supportedStreamingProtocols;
  194. }
  195. void ContentLauncherManager::InitializeWithObjects(jobject managerObject)
  196. {
  197. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  198. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for ContentLauncherManager"));
  199. mContentLauncherManagerObject = env->NewGlobalRef(managerObject);
  200. VerifyOrReturn(mContentLauncherManagerObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef ContentLauncherManager"));
  201. jclass ContentLauncherClass = env->GetObjectClass(managerObject);
  202. VerifyOrReturn(ContentLauncherClass != nullptr, ChipLogError(Zcl, "Failed to get ContentLauncherManager Java class"));
  203. mGetAcceptHeaderMethod = env->GetMethodID(ContentLauncherClass, "getAcceptHeader", "()[Ljava/lang/String;");
  204. if (mGetAcceptHeaderMethod == nullptr)
  205. {
  206. ChipLogError(Zcl, "Failed to access ContentLauncherManager 'getInputList' method");
  207. env->ExceptionClear();
  208. }
  209. mGetSupportedStreamingProtocolsMethod = env->GetMethodID(ContentLauncherClass, "getSupportedStreamingProtocols", "()J");
  210. if (mGetSupportedStreamingProtocolsMethod == nullptr)
  211. {
  212. ChipLogError(Zcl, "Failed to access ContentLauncherManager 'getSupportedStreamingProtocols' method");
  213. env->ExceptionClear();
  214. }
  215. mLaunchContentMethod = env->GetMethodID(
  216. ContentLauncherClass, "launchContent",
  217. "([Lcom/tcl/chip/tvapp/ContentLaunchSearchParameter;ZLjava/lang/String;)Lcom/tcl/chip/tvapp/ContentLaunchResponse;");
  218. if (mLaunchContentMethod == nullptr)
  219. {
  220. ChipLogError(Zcl, "Failed to access ContentLauncherManager 'launchContent' method");
  221. env->ExceptionClear();
  222. }
  223. mLaunchUrlMethod = env->GetMethodID(ContentLauncherClass, "launchUrl",
  224. "(Ljava/lang/String;Ljava/lang/String;Lcom/tcl/chip/tvapp/"
  225. "ContentLaunchBrandingInformation;)Lcom/tcl/chip/tvapp/ContentLaunchResponse;");
  226. if (mLaunchUrlMethod == nullptr)
  227. {
  228. ChipLogError(AppServer, "Failed to access 'launchUrl' method");
  229. env->ExceptionClear();
  230. }
  231. }