TVApp-JNI.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * Copyright (c) 2021 Project CHIP Authors
  3. * All rights reserved.
  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. */
  18. #include "TvApp-JNI.h"
  19. #include "ChannelManager.h"
  20. #include "CommissionerMain.h"
  21. #include "ContentLauncherManager.h"
  22. #include "DeviceCallbacks.h"
  23. #include "JNIDACProvider.h"
  24. #include "KeypadInputManager.h"
  25. #include "LevelManager.h"
  26. #include "LowPowerManager.h"
  27. #include "MediaInputManager.h"
  28. #include "MediaPlaybackManager.h"
  29. #include "MyUserPrompter-JNI.h"
  30. #include "OnOffManager.h"
  31. #include "WakeOnLanManager.h"
  32. #include "credentials/DeviceAttestationCredsProvider.h"
  33. #include <app/app-platform/ContentAppPlatform.h>
  34. #include <app/server/Dnssd.h>
  35. #include <app/server/java/AndroidAppServerWrapper.h>
  36. #include <credentials/DeviceAttestationCredsProvider.h>
  37. #include <credentials/examples/DeviceAttestationCredsExample.h>
  38. #include <jni.h>
  39. #include <lib/core/CHIPError.h>
  40. #include <lib/support/CHIPJNIError.h>
  41. #include <lib/support/JniReferences.h>
  42. #include <lib/support/JniTypeWrappers.h>
  43. #include <zap-generated/CHIPClusters.h>
  44. using namespace chip;
  45. using namespace chip::app;
  46. using namespace chip::app::Clusters;
  47. using namespace chip::AppPlatform;
  48. using namespace chip::Credentials;
  49. #define JNI_METHOD(RETURN, METHOD_NAME) extern "C" JNIEXPORT RETURN JNICALL Java_com_matter_tv_server_tvapp_TvApp_##METHOD_NAME
  50. TvAppJNI TvAppJNI::sInstance;
  51. void TvAppJNI::InitializeWithObjects(jobject app)
  52. {
  53. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  54. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for TvAppJNI"));
  55. mTvAppObject = env->NewGlobalRef(app);
  56. VerifyOrReturn(mTvAppObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef TvAppJNI"));
  57. jclass managerClass = env->GetObjectClass(mTvAppObject);
  58. VerifyOrReturn(managerClass != nullptr, ChipLogError(Zcl, "Failed to get TvAppJNI Java class"));
  59. mPostClusterInitMethod = env->GetMethodID(managerClass, "postClusterInit", "(JI)V");
  60. if (mPostClusterInitMethod == nullptr)
  61. {
  62. ChipLogError(Zcl, "Failed to access ChannelManager 'postClusterInit' method");
  63. env->ExceptionClear();
  64. }
  65. }
  66. void TvAppJNI::PostClusterInit(int clusterId, int endpoint)
  67. {
  68. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  69. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for TvAppJNI::PostClusterInit"));
  70. VerifyOrReturn(mTvAppObject != nullptr, ChipLogError(Zcl, "TvAppJNI::mTvAppObject null"));
  71. VerifyOrReturn(mPostClusterInitMethod != nullptr, ChipLogError(Zcl, "TvAppJNI::mPostClusterInitMethod null"));
  72. env->CallVoidMethod(mTvAppObject, mPostClusterInitMethod, static_cast<jlong>(clusterId), static_cast<jint>(endpoint));
  73. if (env->ExceptionCheck())
  74. {
  75. ChipLogError(Zcl, "Failed to call TvAppJNI 'postClusterInit' method");
  76. env->ExceptionClear();
  77. }
  78. }
  79. jint JNI_OnLoad(JavaVM * jvm, void * reserved)
  80. {
  81. return AndroidAppServerJNI_OnLoad(jvm, reserved);
  82. }
  83. void JNI_OnUnload(JavaVM * jvm, void * reserved)
  84. {
  85. return AndroidAppServerJNI_OnUnload(jvm, reserved);
  86. }
  87. JNI_METHOD(void, nativeInit)(JNIEnv *, jobject app)
  88. {
  89. TvAppJNIMgr().InitializeWithObjects(app);
  90. }
  91. JNI_METHOD(void, initializeCommissioner)(JNIEnv *, jobject app, jobject prompter)
  92. {
  93. TvAppJNIMgr().InitializeCommissioner(new JNIMyUserPrompter(prompter));
  94. }
  95. JNI_METHOD(void, setKeypadInputManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  96. {
  97. KeypadInputManager::NewManager(endpoint, manager);
  98. }
  99. JNI_METHOD(void, setWakeOnLanManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  100. {
  101. WakeOnLanManager::NewManager(endpoint, manager);
  102. }
  103. JNI_METHOD(void, setMediaInputManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  104. {
  105. MediaInputManager::NewManager(endpoint, manager);
  106. }
  107. JNI_METHOD(void, setContentLaunchManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  108. {
  109. ContentLauncherManager::NewManager(endpoint, manager);
  110. }
  111. JNI_METHOD(void, setLowPowerManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  112. {
  113. LowPowerManager::NewManager(endpoint, manager);
  114. }
  115. JNI_METHOD(void, setMediaPlaybackManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  116. {
  117. MediaPlaybackManager::NewManager(endpoint, manager);
  118. }
  119. JNI_METHOD(void, setChannelManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  120. {
  121. ChannelManager::NewManager(endpoint, manager);
  122. }
  123. JNI_METHOD(void, setDACProvider)(JNIEnv *, jobject, jobject provider)
  124. {
  125. if (!chip::Credentials::IsDeviceAttestationCredentialsProviderSet())
  126. {
  127. JNIDACProvider * p = new JNIDACProvider(provider);
  128. chip::Credentials::SetDeviceAttestationCredentialsProvider(p);
  129. }
  130. }
  131. JNI_METHOD(void, preServerInit)(JNIEnv *, jobject app)
  132. {
  133. chip::DeviceLayer::StackLock lock;
  134. ChipLogProgress(Zcl, "TvAppJNI::preServerInit");
  135. }
  136. JNI_METHOD(void, postServerInit)(JNIEnv *, jobject app, jobject contentAppEndpointManager)
  137. {
  138. chip::DeviceLayer::StackLock lock;
  139. ChipLogProgress(Zcl, "TvAppJNI::postServerInit");
  140. }
  141. JNI_METHOD(void, setOnOffManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  142. {
  143. OnOffManager::NewManager(endpoint, manager);
  144. }
  145. JNI_METHOD(jboolean, setOnOff)(JNIEnv *, jobject, jint endpoint, jboolean value)
  146. {
  147. return OnOffManager::SetOnOff(endpoint, value);
  148. }
  149. JNI_METHOD(void, setLevelManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  150. {
  151. LevelManager::NewManager(endpoint, manager);
  152. }
  153. JNI_METHOD(jboolean, setCurrentLevel)(JNIEnv *, jobject, jint endpoint, jboolean value)
  154. {
  155. return LevelManager::SetLevel(endpoint, value);
  156. }
  157. JNI_METHOD(void, setChipDeviceEventProvider)(JNIEnv *, jobject, jobject provider)
  158. {
  159. DeviceCallbacks::NewManager(provider);
  160. }
  161. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  162. class MyPincodeService : public PincodeService
  163. {
  164. uint32_t FetchCommissionPincodeFromContentApp(uint16_t vendorId, uint16_t productId, CharSpan rotatingId) override
  165. {
  166. return ContentAppPlatform::GetInstance().GetPincodeFromContentApp(vendorId, productId, rotatingId);
  167. }
  168. };
  169. MyPincodeService gMyPincodeService;
  170. class MyPostCommissioningListener : public PostCommissioningListener
  171. {
  172. void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
  173. const SessionHandle & sessionHandle) override
  174. {
  175. // read current binding list
  176. chip::Controller::BindingCluster cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);
  177. cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);
  178. CHIP_ERROR err =
  179. cluster.ReadAttribute<Binding::Attributes::Binding::TypeInfo>(this, OnReadSuccessResponse, OnReadFailureResponse);
  180. if (err != CHIP_NO_ERROR)
  181. {
  182. ChipLogError(Controller, "Failed in reading binding. Error %s", ErrorStr(err));
  183. clearContext();
  184. }
  185. }
  186. /* Callback when command results in success */
  187. static void
  188. OnReadSuccessResponse(void * context,
  189. const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseData)
  190. {
  191. ChipLogProgress(Controller, "OnReadSuccessResponse - Binding Read Successfully");
  192. MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
  193. listener->finishTargetConfiguration(responseData);
  194. }
  195. /* Callback when command results in failure */
  196. static void OnReadFailureResponse(void * context, CHIP_ERROR error)
  197. {
  198. ChipLogProgress(Controller, "OnReadFailureResponse - Binding Read Failed");
  199. MyPostCommissioningListener * listener = static_cast<MyPostCommissioningListener *>(context);
  200. listener->clearContext();
  201. CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
  202. if (cdc != nullptr)
  203. {
  204. cdc->PostCommissioningFailed(error);
  205. }
  206. }
  207. /* Callback when command results in success */
  208. static void OnSuccessResponse(void * context)
  209. {
  210. ChipLogProgress(Controller, "OnSuccessResponse - Binding Add Successfully");
  211. CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
  212. if (cdc != nullptr)
  213. {
  214. cdc->PostCommissioningSucceeded();
  215. }
  216. }
  217. /* Callback when command results in failure */
  218. static void OnFailureResponse(void * context, CHIP_ERROR error)
  219. {
  220. ChipLogProgress(Controller, "OnFailureResponse - Binding Add Failed");
  221. CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
  222. if (cdc != nullptr)
  223. {
  224. cdc->PostCommissioningFailed(error);
  225. }
  226. }
  227. void
  228. finishTargetConfiguration(const app::DataModel::DecodableList<Binding::Structs::TargetStruct::DecodableType> & responseList)
  229. {
  230. std::vector<app::Clusters::Binding::Structs::TargetStruct::Type> bindings;
  231. NodeId localNodeId = GetDeviceCommissioner()->GetNodeId();
  232. auto iter = responseList.begin();
  233. while (iter.Next())
  234. {
  235. auto & binding = iter.GetValue();
  236. ChipLogProgress(Controller, "Binding found nodeId=0x" ChipLogFormatX64 " my nodeId=0x" ChipLogFormatX64,
  237. ChipLogValueX64(binding.node.ValueOr(0)), ChipLogValueX64(localNodeId));
  238. if (binding.node.ValueOr(0) != localNodeId)
  239. {
  240. ChipLogProgress(Controller, "Found a binding for a different node, preserving");
  241. bindings.push_back(binding);
  242. }
  243. else
  244. {
  245. ChipLogProgress(Controller, "Found a binding for a matching node, dropping");
  246. }
  247. }
  248. Optional<SessionHandle> opt = mSecureSession.Get();
  249. SessionHandle & sessionHandle = opt.Value();
  250. ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId,
  251. bindings, OnSuccessResponse, OnFailureResponse);
  252. clearContext();
  253. }
  254. void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
  255. const SessionHandle & sessionHandle)
  256. {
  257. mVendorId = vendorId;
  258. mProductId = productId;
  259. mNodeId = nodeId;
  260. mExchangeMgr = &exchangeMgr;
  261. mSecureSession.ShiftToSession(sessionHandle);
  262. }
  263. void clearContext()
  264. {
  265. mVendorId = 0;
  266. mProductId = 0;
  267. mNodeId = 0;
  268. mExchangeMgr = nullptr;
  269. mSecureSession.SessionReleased();
  270. }
  271. uint16_t mVendorId = 0;
  272. uint16_t mProductId = 0;
  273. NodeId mNodeId = 0;
  274. Messaging::ExchangeManager * mExchangeMgr = nullptr;
  275. SessionHolder mSecureSession;
  276. };
  277. MyPostCommissioningListener gMyPostCommissioningListener;
  278. void TvAppJNI::InitializeCommissioner(JNIMyUserPrompter * userPrompter)
  279. {
  280. #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
  281. chip::DeviceLayer::StackLock lock;
  282. CommissionerDiscoveryController * cdc = GetCommissionerDiscoveryController();
  283. if (cdc != nullptr && userPrompter != nullptr)
  284. {
  285. cdc->SetPincodeService(&gMyPincodeService);
  286. cdc->SetUserPrompter(userPrompter);
  287. cdc->SetPostCommissioningListener(&gMyPostCommissioningListener);
  288. }
  289. ChipLogProgress(AppServer, "Starting commissioner");
  290. InitCommissioner(CHIP_PORT + 2 + 10, CHIP_UDC_PORT);
  291. ChipLogProgress(AppServer, "Started commissioner");
  292. #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
  293. }
  294. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED