From e022057aea58fee7f855d8994c7f971c5ac2c875 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Wed, 24 May 2023 00:43:53 -0700 Subject: [PATCH] Use controller exception in Java controller (#26708) --- .../PairOnNetworkLongImSubscribeCommand.kt | 2 +- .../jni/com/chip/casting/MatterError.java | 8 +-- src/controller/java/AndroidCallbacks.cpp | 56 +++++++++++-------- .../java/AndroidClusterExceptions.cpp | 8 +-- .../java/AndroidClusterExceptions.h | 4 +- .../java/AndroidControllerExceptions.cpp | 43 ++++++++++++++ .../java/AndroidControllerExceptions.h | 45 +++++++++++++++ src/controller/java/BUILD.gn | 2 + .../ChipDeviceControllerException.java | 4 +- .../ResubscriptionAttemptCallback.java | 2 +- .../GetConnectedDeviceCallbackJniTest.java | 4 +- 11 files changed, 138 insertions(+), 40 deletions(-) create mode 100644 src/controller/java/AndroidControllerExceptions.cpp create mode 100644 src/controller/java/AndroidControllerExceptions.h diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt index c4b870da4369c9..b2faca8cf92b63 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImSubscribeCommand.kt @@ -57,7 +57,7 @@ class PairOnNetworkLongImSubscribeCommand( } private inner class InternalResubscriptionAttemptCallback : ResubscriptionAttemptCallback { - override fun onResubscriptionAttempt(terminationCause: Int, nextResubscribeIntervalMsec: Int) { + override fun onResubscriptionAttempt(terminationCause: Long, nextResubscribeIntervalMsec: Long) { logger.log(Level.INFO, "ResubscriptionAttemptCallback"); } } diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java index e669a7b61bc56b..ac12eaccd28977 100644 --- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java +++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/MatterError.java @@ -20,15 +20,15 @@ import java.util.Objects; public class MatterError { - private int errorCode; + private long errorCode; private String errorMessage; public static final MatterError DISCOVERY_SERVICE_LOST = - new MatterError(4, "Discovery service was lost."); + new MatterError(4L, "Discovery service was lost."); public static final MatterError NO_ERROR = new MatterError(0, null); - public MatterError(int errorCode, String errorMessage) { + public MatterError(long errorCode, String errorMessage) { this.errorCode = errorCode; this.errorMessage = errorMessage; } @@ -37,7 +37,7 @@ public boolean isNoError() { return this.equals(NO_ERROR); } - public int getErrorCode() { + public long getErrorCode() { return errorCode; } diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index d004de149235cb..a84bd92f65fdea 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -16,6 +16,7 @@ */ #include "AndroidCallbacks.h" #include +#include #include #include #include @@ -105,16 +106,14 @@ void GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void * context, con JniReferences::GetInstance().FindMethod(env, javaCallback, "onConnectionFailure", "(JLjava/lang/Exception;)V", &failureMethod); VerifyOrReturn(failureMethod != nullptr, ChipLogError(Controller, "Could not find onConnectionFailure method")); - // Create the exception to return. - jclass controllerExceptionCls; - CHIP_ERROR err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipDeviceControllerException", - controllerExceptionCls); - VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find exception type for onConnectionFailure")); - JniClass controllerExceptionJniCls(controllerExceptionCls); - - jmethodID exceptionConstructor = env->GetMethodID(controllerExceptionCls, "", "(ILjava/lang/String;)V"); - jobject exception = - env->NewObject(controllerExceptionCls, exceptionConstructor, error.AsInteger(), env->NewStringUTF(ErrorStr(error))); + jthrowable exception; + CHIP_ERROR err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, ErrorStr(error), + error.AsInteger(), exception); + VerifyOrReturn( + err == CHIP_NO_ERROR, + ChipLogError(Controller, + "Unable to create AndroidControllerException on GetConnectedDeviceCallback::OnDeviceConnectionFailureFn: %s", + ErrorStr(err))); DeviceLayer::StackUnlock unlock; env->CallVoidMethod(javaCallback, failureMethod, peerId.GetNodeId(), exception); @@ -558,12 +557,12 @@ CHIP_ERROR ReportCallback::OnResubscriptionNeeded(app::ReadClient * apReadClient jmethodID onResubscriptionAttemptMethod; ReturnLogErrorOnFailure(JniReferences::GetInstance().FindMethod( - env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(II)V", &onResubscriptionAttemptMethod)); + env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(JJ)V", &onResubscriptionAttemptMethod)); DeviceLayer::StackUnlock unlock; env->CallVoidMethod(mResubscriptionAttemptCallbackRef, onResubscriptionAttemptMethod, - static_cast(aTerminationCause.AsInteger()), - static_cast(apReadClient->ComputeTimeTillNextSubscription())); + static_cast(aTerminationCause.AsInteger()), + static_cast(apReadClient->ComputeTimeTillNextSubscription())); VerifyOrReturnError(!env->ExceptionCheck(), CHIP_JNI_ERROR_EXCEPTION_THROWN); return CHIP_NO_ERROR; } @@ -585,8 +584,10 @@ void ReportCallback::ReportError(jobject attributePath, jobject eventPath, const JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); jthrowable exception; - err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception); - VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err))); + err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception); + VerifyOrReturn( + err == CHIP_NO_ERROR, + ChipLogError(Controller, "Unable to create AndroidControllerException on ReportCallback::ReportError: %s", ErrorStr(err))); jmethodID onErrorMethod; err = JniReferences::GetInstance().FindMethod( @@ -813,12 +814,12 @@ CHIP_ERROR ReportEventCallback::OnResubscriptionNeeded(app::ReadClient * apReadC jmethodID onResubscriptionAttemptMethod; ReturnLogErrorOnFailure(JniReferences::GetInstance().FindMethod( - env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(II)V", &onResubscriptionAttemptMethod)); + env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(JJ)V", &onResubscriptionAttemptMethod)); DeviceLayer::StackUnlock unlock; env->CallVoidMethod(mResubscriptionAttemptCallbackRef, onResubscriptionAttemptMethod, - static_cast(aTerminationCause.AsInteger()), - static_cast(apReadClient->ComputeTimeTillNextSubscription())); + static_cast(aTerminationCause.AsInteger()), + static_cast(apReadClient->ComputeTimeTillNextSubscription())); return CHIP_NO_ERROR; } @@ -839,8 +840,10 @@ void ReportEventCallback::ReportError(jobject eventPath, const char * message, C JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); jthrowable exception; - err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception); - VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err))); + err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception); + VerifyOrReturn(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Unable to create AndroidControllerException: %s on eportEventCallback::ReportError", + ErrorStr(err))); jmethodID onErrorMethod; err = JniReferences::GetInstance().FindMethod( @@ -943,8 +946,11 @@ void WriteAttributesCallback::ReportError(jobject attributePath, const char * me ChipLogError(Controller, "WriteAttributesCallback ReportError is called"); jthrowable exception; - err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception); - VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err))); + err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception); + VerifyOrReturn(err == CHIP_NO_ERROR, + ChipLogError(Controller, + "Unable to create AndroidControllerException on WriteAttributesCallback::ReportError: %s", + ErrorStr(err))); jmethodID onErrorMethod; err = JniReferences::GetInstance().FindMethod(env, mJavaCallbackRef, "onError", @@ -1043,8 +1049,10 @@ void InvokeCallback::ReportError(const char * message, ChipError::StorageType er ChipLogError(Controller, "InvokeCallback ReportError is called"); jthrowable exception; - err = AndroidClusterExceptions::GetInstance().CreateIllegalStateException(env, message, errorCode, exception); - VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create IllegalStateException: %s", ErrorStr(err))); + err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception); + VerifyOrReturn( + err == CHIP_NO_ERROR, + ChipLogError(Controller, "Unable to create AndroidControllerException: %s on InvokeCallback::ReportError", ErrorStr(err))); jmethodID onErrorMethod; err = JniReferences::GetInstance().FindMethod(env, mJavaCallbackRef, "onError", "(Ljava/lang/Exception;)V", &onErrorMethod); diff --git a/src/controller/java/AndroidClusterExceptions.cpp b/src/controller/java/AndroidClusterExceptions.cpp index a858a4b50fe948..4a757588b94414 100644 --- a/src/controller/java/AndroidClusterExceptions.cpp +++ b/src/controller/java/AndroidClusterExceptions.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2023 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ namespace chip { -CHIP_ERROR AndroidClusterExceptions::CreateChipClusterException(JNIEnv * env, jint errorCode, jthrowable & outEx) +CHIP_ERROR AndroidClusterExceptions::CreateChipClusterException(JNIEnv * env, uint32_t errorCode, jthrowable & outEx) { CHIP_ERROR err = CHIP_NO_ERROR; jmethodID exceptionConstructor; @@ -34,10 +34,10 @@ CHIP_ERROR AndroidClusterExceptions::CreateChipClusterException(JNIEnv * env, ji VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_JNI_ERROR_TYPE_NOT_FOUND); chip::JniClass clusterExceptionJniCls(clusterExceptionCls); - exceptionConstructor = env->GetMethodID(clusterExceptionCls, "", "(I)V"); + exceptionConstructor = env->GetMethodID(clusterExceptionCls, "", "(J)V"); VerifyOrReturnError(exceptionConstructor != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND); - outEx = (jthrowable) env->NewObject(clusterExceptionCls, exceptionConstructor, errorCode); + outEx = (jthrowable) env->NewObject(clusterExceptionCls, exceptionConstructor, static_cast(errorCode)); VerifyOrReturnError(outEx != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND); return err; diff --git a/src/controller/java/AndroidClusterExceptions.h b/src/controller/java/AndroidClusterExceptions.h index 51a3638d3b39d8..e0bdd07bab51e1 100644 --- a/src/controller/java/AndroidClusterExceptions.h +++ b/src/controller/java/AndroidClusterExceptions.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2023 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ class AndroidClusterExceptions /** * Creates a Java ChipClusterException object in outEx. */ - CHIP_ERROR CreateChipClusterException(JNIEnv * env, jint errorCode, jthrowable & outEx); + CHIP_ERROR CreateChipClusterException(JNIEnv * env, uint32_t errorCode, jthrowable & outEx); /** * Creates a Java IllegalStateException in outEx. diff --git a/src/controller/java/AndroidControllerExceptions.cpp b/src/controller/java/AndroidControllerExceptions.cpp new file mode 100644 index 00000000000000..0419ad2a9bf0ee --- /dev/null +++ b/src/controller/java/AndroidControllerExceptions.cpp @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AndroidControllerExceptions.h" + +#include +#include +#include +#include + +namespace chip { + +CHIP_ERROR AndroidControllerExceptions::CreateAndroidControllerException(JNIEnv * env, const char * message, uint32_t errorCode, + jthrowable & outEx) +{ + jclass controllerExceptionCls; + CHIP_ERROR err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipDeviceControllerException", + controllerExceptionCls); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_JNI_ERROR_TYPE_NOT_FOUND); + JniClass controllerExceptionJniCls(controllerExceptionCls); + + jmethodID exceptionConstructor = env->GetMethodID(controllerExceptionCls, "", "(Jjava/lang/String;)V"); + outEx = (jthrowable) env->NewObject(controllerExceptionCls, exceptionConstructor, static_cast(errorCode), + env->NewStringUTF(message)); + VerifyOrReturnError(outEx != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND); + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/controller/java/AndroidControllerExceptions.h b/src/controller/java/AndroidControllerExceptions.h new file mode 100644 index 00000000000000..02ed39d4bbb447 --- /dev/null +++ b/src/controller/java/AndroidControllerExceptions.h @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { +class AndroidControllerExceptions +{ +public: + AndroidControllerExceptions(const AndroidControllerExceptions &) = delete; + AndroidControllerExceptions(const AndroidControllerExceptions &&) = delete; + AndroidControllerExceptions & operator=(const AndroidControllerExceptions &) = delete; + + static AndroidControllerExceptions & GetInstance() + { + static AndroidControllerExceptions androidControllerExceptions; + return androidControllerExceptions; + } + + /** + * Creates a Java AndroidControllerException object in outEx. + */ + CHIP_ERROR CreateAndroidControllerException(JNIEnv * env, const char * message, uint32_t errorCode, jthrowable & outEx); + +private: + AndroidControllerExceptions() {} +}; +} // namespace chip diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 3d982bfa925e7d..ece7ed06d2e0dd 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -41,6 +41,8 @@ shared_library("jni") { "AndroidClusterExceptions.h", "AndroidCommissioningWindowOpener.cpp", "AndroidCommissioningWindowOpener.h", + "AndroidControllerExceptions.cpp", + "AndroidControllerExceptions.h", "AndroidCurrentFabricRemover.cpp", "AndroidCurrentFabricRemover.h", "AndroidDeviceControllerWrapper.cpp", diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java index 2d2d583e146665..ec7cfb7b3318ea 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceControllerException.java @@ -21,11 +21,11 @@ public class ChipDeviceControllerException extends RuntimeException { private static final long serialVersionUID = 1L; - public int errorCode; + public long errorCode; public ChipDeviceControllerException() {} - public ChipDeviceControllerException(int errorCode, String message) { + public ChipDeviceControllerException(long errorCode, String message) { super(message != null ? message : String.format("Error Code %d", errorCode)); this.errorCode = errorCode; } diff --git a/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java b/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java index cf029ffa54b593..01c6eaab8d5df3 100644 --- a/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java +++ b/src/controller/java/src/chip/devicecontroller/ResubscriptionAttemptCallback.java @@ -18,5 +18,5 @@ package chip.devicecontroller; public interface ResubscriptionAttemptCallback { - void onResubscriptionAttempt(int terminationCause, int nextResubscribeIntervalMsec); + void onResubscriptionAttempt(long terminationCause, long nextResubscribeIntervalMsec); } diff --git a/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java b/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java index f7f981483ba27c..56494b0efc20b7 100644 --- a/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java +++ b/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java @@ -48,10 +48,10 @@ public void deviceConnected() { public void connectionFailure() { var callback = new FakeGetConnectedDeviceCallback(); var jniCallback = new GetConnectedDeviceCallbackJni(callback); - callbackTestUtil.onDeviceConnectionFailure(jniCallback, 100); + callbackTestUtil.onDeviceConnectionFailure(jniCallback, 100L); assertThat(callback.error).isInstanceOf(ChipDeviceControllerException.class); - assertThat(((ChipDeviceControllerException) callback.error).errorCode).isEqualTo(100); + assertThat(((ChipDeviceControllerException) callback.error).errorCode).isEqualTo(100L); } class FakeGetConnectedDeviceCallback implements GetConnectedDeviceCallback {