DeviceApp-JNI.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (c) 2023 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 "DeviceApp-JNI.h"
  19. #include "AppImpl.h"
  20. #include "JNIDACProvider.h"
  21. #include "ColorControlManager.h"
  22. #include "DoorLockManager.h"
  23. #include "OnOffManager.h"
  24. #include "PowerSourceManager.h"
  25. #include "credentials/DeviceAttestationCredsProvider.h"
  26. #include <app/app-platform/ContentAppPlatform.h>
  27. #include <app/server/Dnssd.h>
  28. #include <app/server/java/AndroidAppServerWrapper.h>
  29. #include <credentials/examples/DeviceAttestationCredsExample.h>
  30. #include <jni.h>
  31. #include <lib/core/CHIPError.h>
  32. #include <lib/support/CHIPJNIError.h>
  33. #include <lib/support/JniReferences.h>
  34. #include <lib/support/JniTypeWrappers.h>
  35. #include <zap-generated/CHIPClusters.h>
  36. using namespace chip;
  37. using namespace chip::app;
  38. using namespace chip::app::Clusters;
  39. using namespace chip::AppPlatform;
  40. using namespace chip::Credentials;
  41. using namespace chip::DeviceLayer;
  42. #define JNI_METHOD(RETURN, METHOD_NAME) \
  43. extern "C" JNIEXPORT RETURN JNICALL Java_com_matter_virtual_device_app_DeviceApp_##METHOD_NAME
  44. #define DEVICE_VERSION_DEFAULT 1
  45. EmberAfDeviceType gDeviceTypeIds[] = { { 0, DEVICE_VERSION_DEFAULT } };
  46. DeviceAppJNI DeviceAppJNI::sInstance;
  47. void DeviceAppJNI::InitializeWithObjects(jobject app)
  48. {
  49. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  50. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for DeviceAppJNI"));
  51. mDeviceAppObject = env->NewGlobalRef(app);
  52. VerifyOrReturn(mDeviceAppObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef DeviceAppJNI"));
  53. jclass managerClass = env->GetObjectClass(mDeviceAppObject);
  54. VerifyOrReturn(managerClass != nullptr, ChipLogError(Zcl, "Failed to get DeviceAppJNI Java class"));
  55. mPostClusterInitMethod = env->GetMethodID(managerClass, "postClusterInit", "(JI)V");
  56. if (mPostClusterInitMethod == nullptr)
  57. {
  58. ChipLogError(Zcl, "Failed to access DeviceApp 'postClusterInit' method");
  59. env->ExceptionClear();
  60. }
  61. mPostEventMethod = env->GetMethodID(managerClass, "postEvent", "(J)V");
  62. if (mPostEventMethod == nullptr)
  63. {
  64. ChipLogError(Zcl, "Failed to access DeviceApp 'postEvent' method");
  65. env->ExceptionClear();
  66. }
  67. }
  68. void DeviceAppJNI::PostClusterInit(int clusterId, int endpoint)
  69. {
  70. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  71. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for DeviceAppJNI::PostClusterInit"));
  72. VerifyOrReturn(mDeviceAppObject != nullptr, ChipLogError(Zcl, "DeviceAppJNI::mDeviceAppObject null"));
  73. VerifyOrReturn(mPostClusterInitMethod != nullptr, ChipLogError(Zcl, "DeviceAppJNI::mPostClusterInitMethod null"));
  74. env->CallVoidMethod(mDeviceAppObject, mPostClusterInitMethod, static_cast<jlong>(clusterId), static_cast<jint>(endpoint));
  75. if (env->ExceptionCheck())
  76. {
  77. ChipLogError(Zcl, "Failed to call DeviceAppJNI 'postClusterInit' method");
  78. env->ExceptionClear();
  79. }
  80. }
  81. void DeviceAppJNI::PostEvent(int event)
  82. {
  83. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  84. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for DeviceAppJNI::PostEvent"));
  85. VerifyOrReturn(mDeviceAppObject != nullptr, ChipLogError(Zcl, "DeviceAppJNI::mDeviceAppObject null"));
  86. VerifyOrReturn(mPostEventMethod != nullptr, ChipLogError(Zcl, "DeviceAppJNI::mPostEventMethod null"));
  87. env->CallVoidMethod(mDeviceAppObject, mPostEventMethod, static_cast<jlong>(event));
  88. if (env->ExceptionCheck())
  89. {
  90. ChipLogError(Zcl, "Failed to call DeviceAppJNI 'postEventMethod' method");
  91. env->ExceptionClear();
  92. }
  93. }
  94. jint JNI_OnLoad(JavaVM * jvm, void * reserved)
  95. {
  96. return AndroidAppServerJNI_OnLoad(jvm, reserved);
  97. }
  98. void JNI_OnUnload(JavaVM * jvm, void * reserved)
  99. {
  100. return AndroidAppServerJNI_OnUnload(jvm, reserved);
  101. }
  102. JNI_METHOD(void, nativeInit)(JNIEnv *, jobject app)
  103. {
  104. DeviceAppJNIMgr().InitializeWithObjects(app);
  105. }
  106. JNI_METHOD(void, preServerInit)(JNIEnv *, jobject app)
  107. {
  108. chip::DeviceLayer::StackLock lock;
  109. ChipLogProgress(Zcl, "DeviceAppJNI::preServerInit");
  110. PreServerInit();
  111. }
  112. JNI_METHOD(void, postServerInit)(JNIEnv *, jobject app, jint deviceTypeId)
  113. {
  114. chip::DeviceLayer::StackLock lock;
  115. ChipLogProgress(Zcl, "DeviceAppJNI::postServerInit");
  116. gDeviceTypeIds[0].deviceId = static_cast<uint16_t>(deviceTypeId);
  117. emberAfSetDeviceTypeList(1, Span<const EmberAfDeviceType>(gDeviceTypeIds));
  118. }
  119. JNI_METHOD(void, setDACProvider)(JNIEnv *, jobject, jobject provider)
  120. {
  121. if (!chip::Credentials::IsDeviceAttestationCredentialsProviderSet())
  122. {
  123. chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());
  124. }
  125. }
  126. /*
  127. * On Off Manager
  128. */
  129. JNI_METHOD(void, setOnOffManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  130. {
  131. OnOffManager::NewManager(endpoint, manager);
  132. }
  133. JNI_METHOD(jboolean, setOnOff)(JNIEnv *, jobject, jint endpoint, jboolean value)
  134. {
  135. return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { OnOffManager::SetOnOff(endpoint, value); }) ==
  136. CHIP_NO_ERROR;
  137. }
  138. /*
  139. * Color Control Manager
  140. */
  141. JNI_METHOD(void, setColorControlManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  142. {
  143. ColorControlManager::NewManager(endpoint, manager);
  144. }
  145. /*
  146. * Door Lock Manager
  147. */
  148. JNI_METHOD(void, setDoorLockManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  149. {
  150. DoorLockManager::NewManager(endpoint, manager);
  151. }
  152. JNI_METHOD(jboolean, setLockType)(JNIEnv *, jobject, jint endpoint, jint value)
  153. {
  154. return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetLockType(endpoint, value); }) ==
  155. CHIP_NO_ERROR;
  156. }
  157. JNI_METHOD(jboolean, setLockState)(JNIEnv *, jobject, jint endpoint, jint value)
  158. {
  159. return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetLockState(endpoint, value); }) ==
  160. CHIP_NO_ERROR;
  161. }
  162. JNI_METHOD(jboolean, setActuatorEnabled)(JNIEnv *, jobject, jint endpoint, jboolean value)
  163. {
  164. return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetActuatorEnabled(endpoint, value); }) ==
  165. CHIP_NO_ERROR;
  166. }
  167. JNI_METHOD(jboolean, setAutoRelockTime)(JNIEnv *, jobject, jint endpoint, jint value)
  168. {
  169. return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetAutoRelockTime(endpoint, value); }) ==
  170. CHIP_NO_ERROR;
  171. }
  172. JNI_METHOD(jboolean, setOperatingMode)(JNIEnv *, jobject, jint endpoint, jint value)
  173. {
  174. return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { DoorLockManager::SetOperatingMode(endpoint, value); }) ==
  175. CHIP_NO_ERROR;
  176. }
  177. JNI_METHOD(jboolean, setSupportedOperatingModes)(JNIEnv *, jobject, jint endpoint, jint value)
  178. {
  179. return DeviceLayer::SystemLayer().ScheduleLambda(
  180. [endpoint, value] { DoorLockManager::SetSupportedOperatingModes(endpoint, value); }) == CHIP_NO_ERROR;
  181. }
  182. JNI_METHOD(jboolean, sendLockAlarmEvent)(JNIEnv *, jobject, jint endpoint)
  183. {
  184. return DeviceLayer::SystemLayer().ScheduleLambda([endpoint] { DoorLockManager::SendLockAlarmEvent(endpoint); }) ==
  185. CHIP_NO_ERROR;
  186. }
  187. /*
  188. * Power Source Manager
  189. */
  190. JNI_METHOD(void, setPowerSourceManager)(JNIEnv *, jobject, jint endpoint, jobject manager)
  191. {
  192. PowerSourceManager::NewManager(endpoint, manager);
  193. }
  194. JNI_METHOD(jboolean, setBatPercentRemaining)(JNIEnv *, jobject, jint endpoint, jint value)
  195. {
  196. return DeviceLayer::SystemLayer().ScheduleLambda(
  197. [endpoint, value] { PowerSourceManager::SetBatPercentRemaining(endpoint, value); }) == CHIP_NO_ERROR;
  198. }