MediaInputManager.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /**
  2. *
  3. * Copyright (c) 2021 Project CHIP Authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "MediaInputManager.h"
  18. #include "TvApp-JNI.h"
  19. #include <app-common/zap-generated/ids/Clusters.h>
  20. #include <lib/core/CHIPError.h>
  21. #include <lib/support/CHIPJNIError.h>
  22. #include <lib/support/JniReferences.h>
  23. #include <lib/support/JniTypeWrappers.h>
  24. using namespace chip;
  25. using namespace chip::app::Clusters::MediaInput;
  26. /** @brief Media Input Cluster Init
  27. *
  28. * This function is called when a specific cluster is initialized. It gives the
  29. * application an opportunity to take care of cluster initialization procedures.
  30. * It is called exactly once for each endpoint where cluster is present.
  31. *
  32. * @param endpoint Ver: always
  33. *
  34. */
  35. void emberAfMediaInputClusterInitCallback(EndpointId endpoint)
  36. {
  37. ChipLogProgress(Zcl, "TV Android App: MediaInput::PostClusterInit");
  38. TvAppJNIMgr().PostClusterInit(chip::app::Clusters::MediaInput::Id, endpoint);
  39. }
  40. void MediaInputManager::NewManager(jint endpoint, jobject manager)
  41. {
  42. ChipLogProgress(Zcl, "TV Android App: MediaInput::SetDefaultDelegate");
  43. MediaInputManager * mgr = new MediaInputManager();
  44. mgr->InitializeWithObjects(manager);
  45. chip::app::Clusters::MediaInput::SetDefaultDelegate(static_cast<EndpointId>(endpoint), mgr);
  46. }
  47. CHIP_ERROR MediaInputManager::HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder)
  48. {
  49. CHIP_ERROR err = CHIP_NO_ERROR;
  50. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  51. ChipLogProgress(Zcl, "Received MediaInputManager::HandleGetInputList");
  52. VerifyOrExit(mMediaInputManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  53. VerifyOrExit(mGetInputListMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  54. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  55. return aEncoder.EncodeList([this, env](const auto & encoder) -> CHIP_ERROR {
  56. jobjectArray inputArray = (jobjectArray) env->CallObjectMethod(mMediaInputManagerObject, mGetInputListMethod);
  57. if (env->ExceptionCheck())
  58. {
  59. ChipLogError(AppServer, "Java exception in MediaInputManager::HandleGetInputList");
  60. env->ExceptionDescribe();
  61. env->ExceptionClear();
  62. return CHIP_ERROR_INCORRECT_STATE;
  63. }
  64. jint size = env->GetArrayLength(inputArray);
  65. for (int i = 0; i < size; i++)
  66. {
  67. app::Clusters::MediaInput::Structs::InputInfoStruct::Type mediaInput;
  68. jobject inputObj = env->GetObjectArrayElement(inputArray, i);
  69. jclass inputClass = env->GetObjectClass(inputObj);
  70. jfieldID indexId = env->GetFieldID(inputClass, "index", "I");
  71. jint index = env->GetIntField(inputObj, indexId);
  72. mediaInput.index = static_cast<uint8_t>(index);
  73. jfieldID typeId = env->GetFieldID(inputClass, "type", "I");
  74. jint type = env->GetIntField(inputObj, typeId);
  75. mediaInput.inputType = static_cast<app::Clusters::MediaInput::InputTypeEnum>(type);
  76. jfieldID nameId = env->GetFieldID(inputClass, "name", "Ljava/lang/String;");
  77. jstring jname = static_cast<jstring>(env->GetObjectField(inputObj, nameId));
  78. JniUtfString name(env, jname);
  79. if (jname != NULL)
  80. {
  81. mediaInput.name = name.charSpan();
  82. }
  83. jfieldID descriptionId = env->GetFieldID(inputClass, "description", "Ljava/lang/String;");
  84. jstring jdescription = static_cast<jstring>(env->GetObjectField(inputObj, descriptionId));
  85. JniUtfString description(env, jdescription);
  86. if (jdescription != NULL)
  87. {
  88. mediaInput.description = description.charSpan();
  89. }
  90. ReturnErrorOnFailure(encoder.Encode(mediaInput));
  91. }
  92. return CHIP_NO_ERROR;
  93. });
  94. exit:
  95. if (err != CHIP_NO_ERROR)
  96. {
  97. ChipLogError(Zcl, "MediaInputManager::GetInputList status error: %s", err.AsString());
  98. }
  99. return err;
  100. }
  101. uint8_t MediaInputManager::HandleGetCurrentInput()
  102. {
  103. CHIP_ERROR err = CHIP_NO_ERROR;
  104. jint index = -1;
  105. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  106. ChipLogProgress(Zcl, "Received MediaInputManager::HandleGetCurrentInput");
  107. VerifyOrExit(mMediaInputManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  108. VerifyOrExit(mGetCurrentInputMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  109. VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV);
  110. {
  111. index = env->CallIntMethod(mMediaInputManagerObject, mGetCurrentInputMethod);
  112. if (env->ExceptionCheck())
  113. {
  114. ChipLogError(AppServer, "Java exception in MediaInputManager::HandleGetCurrentInput");
  115. env->ExceptionDescribe();
  116. env->ExceptionClear();
  117. err = CHIP_ERROR_INCORRECT_STATE;
  118. }
  119. }
  120. exit:
  121. if (err != CHIP_NO_ERROR)
  122. {
  123. ChipLogError(Zcl, "MediaInputManager::HandleGetCurrentInput status error: %s", err.AsString());
  124. }
  125. return uint8_t(index);
  126. }
  127. bool MediaInputManager::HandleSelectInput(const uint8_t index)
  128. {
  129. jboolean ret = JNI_FALSE;
  130. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  131. ChipLogProgress(Zcl, "Received MediaInputManager::HandleSelectInput %d", index);
  132. VerifyOrExit(mMediaInputManagerObject != nullptr, ChipLogError(Zcl, "mMediaInputManagerObject null"));
  133. VerifyOrExit(mSelectInputMethod != nullptr, ChipLogError(Zcl, "mSelectInputMethod null"));
  134. VerifyOrExit(env != NULL, ChipLogError(Zcl, "env null"));
  135. env->ExceptionClear();
  136. ret = env->CallBooleanMethod(mMediaInputManagerObject, mSelectInputMethod, static_cast<jint>(index));
  137. if (env->ExceptionCheck())
  138. {
  139. ChipLogError(DeviceLayer, "Java exception in MediaInputManager::HandleSelectInput");
  140. env->ExceptionDescribe();
  141. env->ExceptionClear();
  142. return false;
  143. }
  144. exit:
  145. return static_cast<bool>(ret);
  146. }
  147. bool MediaInputManager::HandleShowInputStatus()
  148. {
  149. jboolean ret = JNI_FALSE;
  150. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  151. ChipLogProgress(Zcl, "Received MediaInputManager::HandleShowInputStatus");
  152. VerifyOrExit(mMediaInputManagerObject != nullptr, ChipLogError(Zcl, "mMediaInputManagerObject null"));
  153. VerifyOrExit(mShowInputStatusMethod != nullptr, ChipLogError(Zcl, "mShowInputStatusMethod null"));
  154. VerifyOrExit(env != NULL, ChipLogError(Zcl, "env null"));
  155. env->ExceptionClear();
  156. ret = env->CallBooleanMethod(mMediaInputManagerObject, mShowInputStatusMethod);
  157. if (env->ExceptionCheck())
  158. {
  159. ChipLogError(DeviceLayer, "Java exception in MediaInputManager::HandleShowInputStatus");
  160. env->ExceptionDescribe();
  161. env->ExceptionClear();
  162. return false;
  163. }
  164. exit:
  165. return static_cast<bool>(ret);
  166. }
  167. bool MediaInputManager::HandleHideInputStatus()
  168. {
  169. jboolean ret = JNI_FALSE;
  170. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  171. ChipLogProgress(Zcl, "Received MediaInputManager::HandleHideInputStatus");
  172. VerifyOrExit(mMediaInputManagerObject != nullptr, ChipLogError(Zcl, "mMediaInputManagerObject null"));
  173. VerifyOrExit(mHideInputStatusMethod != nullptr, ChipLogError(Zcl, "mHideInputStatusMethod null"));
  174. VerifyOrExit(env != NULL, ChipLogError(Zcl, "env null"));
  175. env->ExceptionClear();
  176. ret = env->CallBooleanMethod(mMediaInputManagerObject, mHideInputStatusMethod);
  177. if (env->ExceptionCheck())
  178. {
  179. ChipLogError(DeviceLayer, "Java exception in MediaInputManager::HandleHideInputStatus");
  180. env->ExceptionDescribe();
  181. env->ExceptionClear();
  182. return false;
  183. }
  184. exit:
  185. return static_cast<bool>(ret);
  186. }
  187. bool MediaInputManager::HandleRenameInput(const uint8_t index, const chip::CharSpan & name)
  188. {
  189. std::string inputname(name.data(), name.size());
  190. jboolean ret = JNI_FALSE;
  191. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  192. ChipLogProgress(Zcl, "Received MediaInputManager::HandleRenameInput %d to %s", index, name.data());
  193. VerifyOrExit(mMediaInputManagerObject != nullptr, ChipLogError(Zcl, "mMediaInputManagerObject null"));
  194. VerifyOrExit(mRenameInputMethod != nullptr, ChipLogError(Zcl, "mHideInputStatusMethod null"));
  195. VerifyOrExit(env != NULL, ChipLogError(Zcl, "env null"));
  196. {
  197. UtfString jniInputname(env, inputname.data());
  198. env->ExceptionClear();
  199. ret =
  200. env->CallBooleanMethod(mMediaInputManagerObject, mRenameInputMethod, static_cast<jint>(index), jniInputname.jniValue());
  201. if (env->ExceptionCheck())
  202. {
  203. ChipLogError(DeviceLayer, "Java exception in MediaInputManager::HandleRenameInput");
  204. env->ExceptionDescribe();
  205. env->ExceptionClear();
  206. return false;
  207. }
  208. }
  209. exit:
  210. return static_cast<bool>(ret);
  211. }
  212. void MediaInputManager::InitializeWithObjects(jobject managerObject)
  213. {
  214. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  215. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for MediaInputManager"));
  216. mMediaInputManagerObject = env->NewGlobalRef(managerObject);
  217. VerifyOrReturn(mMediaInputManagerObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef MediaInputManager"));
  218. jclass MediaInputManagerClass = env->GetObjectClass(managerObject);
  219. VerifyOrReturn(MediaInputManagerClass != nullptr, ChipLogError(Zcl, "Failed to get MediaInputManager Java class"));
  220. mGetInputListMethod =
  221. env->GetMethodID(MediaInputManagerClass, "getInputList", "()[Lcom/matter/tv/server/tvapp/MediaInputInfo;");
  222. if (mGetInputListMethod == nullptr)
  223. {
  224. ChipLogError(Zcl, "Failed to access MediaInputManager 'getInputList' method");
  225. env->ExceptionClear();
  226. }
  227. mGetCurrentInputMethod = env->GetMethodID(MediaInputManagerClass, "getCurrentInput", "()I");
  228. if (mGetCurrentInputMethod == nullptr)
  229. {
  230. ChipLogError(Zcl, "Failed to access MediaInputManager 'getCurrentInput' method");
  231. env->ExceptionClear();
  232. }
  233. mSelectInputMethod = env->GetMethodID(MediaInputManagerClass, "selectInput", "(I)Z");
  234. if (mSelectInputMethod == nullptr)
  235. {
  236. ChipLogError(Zcl, "Failed to access MediaInputManager 'selectInput' method");
  237. env->ExceptionClear();
  238. }
  239. mShowInputStatusMethod = env->GetMethodID(MediaInputManagerClass, "showInputStatus", "()Z");
  240. if (mShowInputStatusMethod == nullptr)
  241. {
  242. ChipLogError(Zcl, "Failed to access MediaInputManager 'showInputStatus' method");
  243. env->ExceptionClear();
  244. }
  245. mHideInputStatusMethod = env->GetMethodID(MediaInputManagerClass, "hideInputStatus", "()Z");
  246. if (mHideInputStatusMethod == nullptr)
  247. {
  248. ChipLogError(Zcl, "Failed to access MediaInputManager 'hideInputStatus' method");
  249. env->ExceptionClear();
  250. }
  251. mRenameInputMethod = env->GetMethodID(MediaInputManagerClass, "renameInput", "(ILjava/lang/String;)Z");
  252. if (mRenameInputMethod == nullptr)
  253. {
  254. ChipLogError(Zcl, "Failed to access MediaInputManager 'renameInput' method");
  255. env->ExceptionClear();
  256. }
  257. }