MyUserPrompter-JNI.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. *
  3. * Copyright (c) 2022 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 "MyUserPrompter-JNI.h"
  18. #include <jni.h>
  19. #include <lib/core/CHIPError.h>
  20. #include <lib/support/CHIPJNIError.h>
  21. #include <lib/support/JniReferences.h>
  22. #include <lib/support/JniTypeWrappers.h>
  23. using namespace chip;
  24. JNIMyUserPrompter::JNIMyUserPrompter(jobject provider)
  25. {
  26. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  27. VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Failed to GetEnvForCurrentThread for JNIMyUserPrompter"));
  28. mJNIMyUserPrompterObject = env->NewGlobalRef(provider);
  29. VerifyOrReturn(mJNIMyUserPrompterObject != nullptr, ChipLogError(Zcl, "Failed to NewGlobalRef JNIMyUserPrompter"));
  30. jclass JNIMyUserPrompterClass = env->GetObjectClass(provider);
  31. VerifyOrReturn(JNIMyUserPrompterClass != nullptr, ChipLogError(Zcl, "Failed to get JNIMyUserPrompter Java class"));
  32. mPromptForCommissionOKPermissionMethod =
  33. env->GetMethodID(JNIMyUserPrompterClass, "promptForCommissionOkPermission", "(IILjava/lang/String;)V");
  34. if (mPromptForCommissionOKPermissionMethod == nullptr)
  35. {
  36. ChipLogError(Zcl, "Failed to access JNIMyUserPrompter 'promptForCommissionOkPermission' method");
  37. env->ExceptionClear();
  38. }
  39. mPromptForCommissionPincodeMethod =
  40. env->GetMethodID(JNIMyUserPrompterClass, "promptForCommissionPinCode", "(IILjava/lang/String;)V");
  41. if (mPromptForCommissionPincodeMethod == nullptr)
  42. {
  43. ChipLogError(Zcl, "Failed to access JNIMyUserPrompter 'promptForCommissionPinCode' method");
  44. env->ExceptionClear();
  45. }
  46. mPromptCommissioningSucceededMethod =
  47. env->GetMethodID(JNIMyUserPrompterClass, "promptCommissioningSucceeded", "(IILjava/lang/String;)V");
  48. if (mPromptCommissioningSucceededMethod == nullptr)
  49. {
  50. ChipLogError(Zcl, "Failed to access JNIMyUserPrompter 'promptCommissioningSucceeded' method");
  51. env->ExceptionClear();
  52. }
  53. mPromptCommissioningFailedMethod =
  54. env->GetMethodID(JNIMyUserPrompterClass, "promptCommissioningFailed", "(Ljava/lang/String;Ljava/lang/String;)V");
  55. if (mPromptCommissioningFailedMethod == nullptr)
  56. {
  57. ChipLogError(Zcl, "Failed to access JNIMyUserPrompter 'promptCommissioningFailed' method");
  58. env->ExceptionClear();
  59. }
  60. }
  61. /*
  62. * Called to prompt the user for consent to allow the given commissioneeName/vendorId/productId to be commissioned.
  63. * For example "[commissioneeName] is requesting permission to cast to this TV, approve?"
  64. *
  65. * If user responds with OK then implementor calls UserPrompterResolver.OnPromptAccepted;
  66. * If user responds with Cancel then implementor calls calls UserPrompterResolver.OnPromptDeclined();
  67. *
  68. */
  69. void JNIMyUserPrompter::PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName)
  70. {
  71. CHIP_ERROR err = CHIP_NO_ERROR;
  72. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  73. std::string stringCommissioneeName(commissioneeName);
  74. VerifyOrExit(mJNIMyUserPrompterObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  75. VerifyOrExit(mPromptForCommissionOKPermissionMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  76. VerifyOrExit(env != nullptr, err = CHIP_JNI_ERROR_NO_ENV);
  77. {
  78. UtfString jniCommissioneeName(env, stringCommissioneeName.data());
  79. env->ExceptionClear();
  80. env->CallVoidMethod(mJNIMyUserPrompterObject, mPromptForCommissionOKPermissionMethod, static_cast<jint>(vendorId),
  81. static_cast<jint>(productId), jniCommissioneeName.jniValue());
  82. if (env->ExceptionCheck())
  83. {
  84. ChipLogError(DeviceLayer, "Java exception in PromptForCommissionOKPermission");
  85. env->ExceptionDescribe();
  86. env->ExceptionClear();
  87. err = CHIP_ERROR_INCORRECT_STATE;
  88. goto exit;
  89. }
  90. }
  91. exit:
  92. if (err != CHIP_NO_ERROR)
  93. {
  94. ChipLogError(Zcl, "PromptForCommissionOKPermission error: %s", err.AsString());
  95. }
  96. }
  97. /*
  98. * Called to prompt the user to enter the setup pincode displayed by the given commissioneeName/vendorId/productId to be
  99. * commissioned. For example "Please enter pin displayed in casting app."
  100. *
  101. * If user responds with OK then implementor calls UserPrompterResolver.OnPinCodeEntered();
  102. * If user responds with Cancel then implementor calls UserPrompterResolver.OnPinCodeDeclined();
  103. *
  104. */
  105. void JNIMyUserPrompter::PromptForCommissionPincode(uint16_t vendorId, uint16_t productId, const char * commissioneeName)
  106. {
  107. CHIP_ERROR err = CHIP_NO_ERROR;
  108. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  109. std::string stringCommissioneeName(commissioneeName);
  110. VerifyOrExit(mJNIMyUserPrompterObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  111. VerifyOrExit(mPromptForCommissionPincodeMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  112. VerifyOrExit(env != nullptr, err = CHIP_JNI_ERROR_NO_ENV);
  113. {
  114. UtfString jniCommissioneeName(env, stringCommissioneeName.data());
  115. env->ExceptionClear();
  116. env->CallVoidMethod(mJNIMyUserPrompterObject, mPromptForCommissionPincodeMethod, static_cast<jint>(vendorId),
  117. static_cast<jint>(productId), jniCommissioneeName.jniValue());
  118. if (env->ExceptionCheck())
  119. {
  120. ChipLogError(Zcl, "Java exception in PromptForCommissionPincode");
  121. env->ExceptionDescribe();
  122. env->ExceptionClear();
  123. err = CHIP_ERROR_INCORRECT_STATE;
  124. goto exit;
  125. }
  126. }
  127. exit:
  128. if (err != CHIP_NO_ERROR)
  129. {
  130. ChipLogError(Zcl, "PromptForCommissionPincode error: %s", err.AsString());
  131. }
  132. }
  133. /*
  134. * Called to notify the user that commissioning succeeded. It can be in form of UI Notification.
  135. */
  136. void JNIMyUserPrompter::PromptCommissioningSucceeded(uint16_t vendorId, uint16_t productId, const char * commissioneeName)
  137. {
  138. CHIP_ERROR err = CHIP_NO_ERROR;
  139. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  140. std::string stringCommissioneeName(commissioneeName);
  141. VerifyOrExit(mJNIMyUserPrompterObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  142. VerifyOrExit(mPromptCommissioningSucceededMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  143. VerifyOrExit(env != nullptr, err = CHIP_JNI_ERROR_NO_ENV);
  144. {
  145. UtfString jniCommissioneeName(env, stringCommissioneeName.data());
  146. env->ExceptionClear();
  147. env->CallVoidMethod(mJNIMyUserPrompterObject, mPromptCommissioningSucceededMethod, static_cast<jint>(vendorId),
  148. static_cast<jint>(productId), jniCommissioneeName.jniValue());
  149. if (env->ExceptionCheck())
  150. {
  151. ChipLogError(Zcl, "Java exception in PromptCommissioningSucceeded");
  152. env->ExceptionDescribe();
  153. env->ExceptionClear();
  154. err = CHIP_ERROR_INCORRECT_STATE;
  155. goto exit;
  156. }
  157. }
  158. exit:
  159. if (err != CHIP_NO_ERROR)
  160. {
  161. ChipLogError(Zcl, "PromptCommissioningSucceeded error: %s", err.AsString());
  162. }
  163. }
  164. /*
  165. * Called to notify the user that commissioning failed. It can be in form of UI Notification.
  166. */
  167. void JNIMyUserPrompter::PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error)
  168. {
  169. CHIP_ERROR err = CHIP_NO_ERROR;
  170. JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
  171. std::string stringCommissioneeName(commissioneeName);
  172. VerifyOrExit(mJNIMyUserPrompterObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  173. VerifyOrExit(mPromptCommissioningFailedMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
  174. VerifyOrExit(env != nullptr, err = CHIP_JNI_ERROR_NO_ENV);
  175. {
  176. std::string stringError(error.AsString());
  177. UtfString jniCommissioneeName(env, stringCommissioneeName.data());
  178. UtfString jniCommissioneeError(env, stringError.data());
  179. env->ExceptionClear();
  180. env->CallVoidMethod(mJNIMyUserPrompterObject, mPromptCommissioningFailedMethod, jniCommissioneeName.jniValue(),
  181. jniCommissioneeError.jniValue());
  182. if (env->ExceptionCheck())
  183. {
  184. ChipLogError(Zcl, "Java exception in PromptCommissioningFailed");
  185. env->ExceptionDescribe();
  186. env->ExceptionClear();
  187. err = CHIP_ERROR_INCORRECT_STATE;
  188. goto exit;
  189. }
  190. }
  191. exit:
  192. if (err != CHIP_NO_ERROR)
  193. {
  194. ChipLogError(Zcl, "PromptCommissioningFailed error: %s", err.AsString());
  195. }
  196. }