From 9b4b408b36e473e0f8374722e7e041564cf2ee27 Mon Sep 17 00:00:00 2001 From: Sharad Binjola Date: Thu, 4 Apr 2024 14:20:05 -0700 Subject: [PATCH] Decoupling android IM code from ChipDeviceController --- examples/tv-casting-app/android/BUILD.gn | 2 + .../java/AndroidInteractionClient.cpp | 1 - src/controller/java/BUILD.gn | 172 +++++++++++------- .../java/CHIPInteractionClient-JNI.cpp | 79 ++++++++ .../chip/devicecontroller/ChipClusters.java | 8 +- .../ChipInteractionClient.java | 62 +++++++ 6 files changed, 255 insertions(+), 69 deletions(-) create mode 100644 src/controller/java/CHIPInteractionClient-JNI.cpp create mode 100644 src/controller/java/src/chip/devicecontroller/ChipInteractionClient.java diff --git a/examples/tv-casting-app/android/BUILD.gn b/examples/tv-casting-app/android/BUILD.gn index 52a3342773175b..308e8e624b9eb7 100644 --- a/examples/tv-casting-app/android/BUILD.gn +++ b/examples/tv-casting-app/android/BUILD.gn @@ -55,6 +55,7 @@ shared_library("jni") { "${chip_root}/examples/tv-casting-app/tv-casting-common", "${chip_root}/src/app/data-model:heap", "${chip_root}/src/app/server/java:jni", + "${chip_root}/src/controller/java:android_interaction_model_jni", "${chip_root}/src/lib", "${chip_root}/third_party/inipp", ] @@ -72,6 +73,7 @@ android_library("java") { deps = [ ":android", "${chip_root}/src/app/server/java", + "${chip_root}/src/controller/java:android_interaction_model", "${chip_root}/src/platform/android:java", "${chip_root}/third_party/android_deps:annotation", ] diff --git a/src/controller/java/AndroidInteractionClient.cpp b/src/controller/java/AndroidInteractionClient.cpp index ec809570bcb1c7..cb59a7bf1718c2 100644 --- a/src/controller/java/AndroidInteractionClient.cpp +++ b/src/controller/java/AndroidInteractionClient.cpp @@ -24,7 +24,6 @@ #include "AndroidInteractionClient.h" #include "AndroidCallbacks.h" -#include "AndroidDeviceControllerWrapper.h" #include diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 9342f1330a6b5f..5625534f0c3859 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -42,6 +42,42 @@ if (!matter_enable_java_compilation) { import("${build_root}/config/android_abi.gni") } +source_set("android_interaction_model_jni") { + sources = [ + "AndroidCallbacks-JNI.cpp", + "AndroidCallbacks.cpp", + "AndroidCallbacks.h", + "AndroidConnectionFailureExceptions.cpp", + "AndroidConnectionFailureExceptions.h", + "AndroidControllerExceptions.cpp", + "AndroidControllerExceptions.h", + "AndroidInteractionClient.cpp", + "AndroidInteractionClient.h", + "BaseCHIPCluster-JNI.cpp", + "CHIPAttributeTLVValueDecoder.h", + "CHIPEventTLVValueDecoder.h", + "CHIPInteractionClient-JNI.cpp", + ] + + if (matter_enable_tlv_decoder_api) { + defines = [ "USE_JAVA_TLV_ENCODE_DECODE" ] + + sources += [ + "CHIPTLVValueDecoder-JNI.cpp", + "zap-generated/CHIPAttributeTLVValueDecoder.cpp", + "zap-generated/CHIPEventTLVValueDecoder.cpp", + ] + } + + public_deps = [ + "${chip_root}/src/app/data-model:heap", + "${chip_root}/src/app/server/java:jni", + "${chip_root}/src/lib", + "${chip_root}/src/lib/support/jsontlv", + "${chip_root}/third_party/inipp", + ] +} + shared_library("jni") { output_name = "libCHIPController" @@ -56,33 +92,21 @@ shared_library("jni") { check_includes = false sources = [ - "AndroidCallbacks-JNI.cpp", - "AndroidCallbacks.cpp", - "AndroidCallbacks.h", "AndroidCheckInDelegate.cpp", "AndroidCheckInDelegate.h", "AndroidClusterExceptions.cpp", "AndroidClusterExceptions.h", "AndroidCommissioningWindowOpener.cpp", "AndroidCommissioningWindowOpener.h", - "AndroidConnectionFailureExceptions.cpp", - "AndroidConnectionFailureExceptions.h", - "AndroidControllerExceptions.cpp", - "AndroidControllerExceptions.h", "AndroidCurrentFabricRemover.cpp", "AndroidCurrentFabricRemover.h", "AndroidDeviceControllerWrapper.cpp", "AndroidDeviceControllerWrapper.h", - "AndroidInteractionClient.cpp", - "AndroidInteractionClient.h", "AndroidOperationalCredentialsIssuer.cpp", "AndroidOperationalCredentialsIssuer.h", "AttestationTrustStoreBridge.cpp", "AttestationTrustStoreBridge.h", - "BaseCHIPCluster-JNI.cpp", - "CHIPAttributeTLVValueDecoder.h", "CHIPDeviceController-JNI.cpp", - "CHIPEventTLVValueDecoder.h", "DeviceAttestation-JNI.cpp", "DeviceAttestationDelegateBridge.cpp", "DeviceAttestationDelegateBridge.h", @@ -92,26 +116,16 @@ shared_library("jni") { ] deps = [ + ":android_interaction_model", ":controller_config", "${chip_root}/src/app/icd/client:handler", "${chip_root}/src/app/icd/client:manager", "${chip_root}/src/credentials:default_attestation_verifier", "${chip_root}/src/inet", "${chip_root}/src/lib", - "${chip_root}/src/lib/support/jsontlv", "${chip_root}/src/platform", ] - if (matter_enable_tlv_decoder_api) { - defines += [ "USE_JAVA_TLV_ENCODE_DECODE" ] - - sources += [ - "CHIPTLVValueDecoder-JNI.cpp", - "zap-generated/CHIPAttributeTLVValueDecoder.cpp", - "zap-generated/CHIPEventTLVValueDecoder.cpp", - ] - } - if (chip_build_controller_dynamic_server) { sources += [ "BdxOTASender.cpp", @@ -452,58 +466,19 @@ android_library("chipclusterID") { ] } -android_library("java") { - output_name = "CHIPController.jar" - - deps = [ - ":chipcluster", - ":chipclusterID", - "${chip_root}/third_party/java_deps:annotation", - ] - - data_deps = [ ":jni" ] - +android_library("android_interaction_model") { sources = [ - "src/chip/devicecontroller/AttestationInfo.java", - "src/chip/devicecontroller/AttestationTrustStoreDelegate.java", - "src/chip/devicecontroller/CSRInfo.java", - "src/chip/devicecontroller/ChipClusterException.java", - "src/chip/devicecontroller/ChipCommandType.java", - "src/chip/devicecontroller/ChipDeviceController.java", - "src/chip/devicecontroller/ChipDeviceControllerException.java", - "src/chip/devicecontroller/CommissioningWindowStatus.java", - "src/chip/devicecontroller/ConnectionFailureException.java", - "src/chip/devicecontroller/ControllerParams.java", - "src/chip/devicecontroller/DeviceAttestation.java", - "src/chip/devicecontroller/DeviceAttestationDelegate.java", - "src/chip/devicecontroller/DiscoveredDevice.java", + "src/chip/devicecontroller/ChipInteractionClient.java", "src/chip/devicecontroller/ExtendableInvokeCallback.java", "src/chip/devicecontroller/ExtendableInvokeCallbackJni.java", "src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java", - "src/chip/devicecontroller/GroupKeySecurityPolicy.java", - "src/chip/devicecontroller/ICDCheckInDelegate.java", - "src/chip/devicecontroller/ICDCheckInDelegateWrapper.java", - "src/chip/devicecontroller/ICDClientInfo.java", - "src/chip/devicecontroller/ICDDeviceInfo.java", - "src/chip/devicecontroller/ICDRegistrationInfo.java", "src/chip/devicecontroller/InvokeCallback.java", "src/chip/devicecontroller/InvokeCallbackJni.java", - "src/chip/devicecontroller/KeypairDelegate.java", - "src/chip/devicecontroller/NetworkCredentials.java", - "src/chip/devicecontroller/NetworkLocation.java", - "src/chip/devicecontroller/OTAProviderDelegate.java", - "src/chip/devicecontroller/OpenCommissioningCallback.java", - "src/chip/devicecontroller/OperationalKeyConfig.java", - "src/chip/devicecontroller/PairingHintBitmap.java", - "src/chip/devicecontroller/PaseVerifierParams.java", "src/chip/devicecontroller/ReportCallback.java", "src/chip/devicecontroller/ReportCallbackJni.java", "src/chip/devicecontroller/ResubscriptionAttemptCallback.java", "src/chip/devicecontroller/StatusException.java", "src/chip/devicecontroller/SubscriptionEstablishedCallback.java", - "src/chip/devicecontroller/ThreadScanResult.java", - "src/chip/devicecontroller/UnpairDeviceCallback.java", - "src/chip/devicecontroller/WiFiScanResult.java", "src/chip/devicecontroller/WriteAttributesCallback.java", "src/chip/devicecontroller/WriteAttributesCallbackJni.java", "src/chip/devicecontroller/model/AttributeState.java", @@ -522,6 +497,8 @@ android_library("java") { "src/chip/devicecontroller/model/Status.java", ] + sources += [ "src/chip/devicecontroller/ChipClusterException.java" ] + if (matter_enable_tlv_decoder_api) { sources += [ "src/chip/devicecontroller/ChipTLVValueDecoder.java" ] } @@ -544,6 +521,73 @@ android_library("java") { ] } + deps = [ + ":chipcluster", + ":chipclusterID", + "${chip_root}/third_party/java_deps:annotation", + ] + + if (matter_enable_java_compilation) { + deps += [ + "${chip_root}/third_party/java_deps:json", + "${chip_root}/third_party/java_deps/stub_src", + ] + } else { + deps += [ ":android" ] + + data_deps = [ "${chip_root}/build/chip/java:shared_cpplib" ] + } + + javac_flags = [ + "-Xlint:deprecation", + "-parameters", # Store infomation about method parameters + ] +} + +android_library("java") { + output_name = "CHIPController.jar" + + deps = [ + ":android_interaction_model", + ":chipcluster", + ":chipclusterID", + "${chip_root}/third_party/java_deps:annotation", + ] + + data_deps = [ ":jni" ] + + sources = [ + "src/chip/devicecontroller/AttestationInfo.java", + "src/chip/devicecontroller/AttestationTrustStoreDelegate.java", + "src/chip/devicecontroller/CSRInfo.java", + "src/chip/devicecontroller/ChipCommandType.java", + "src/chip/devicecontroller/ChipDeviceController.java", + "src/chip/devicecontroller/ChipDeviceControllerException.java", + "src/chip/devicecontroller/CommissioningWindowStatus.java", + "src/chip/devicecontroller/ConnectionFailureException.java", + "src/chip/devicecontroller/ControllerParams.java", + "src/chip/devicecontroller/DeviceAttestation.java", + "src/chip/devicecontroller/DeviceAttestationDelegate.java", + "src/chip/devicecontroller/DiscoveredDevice.java", + "src/chip/devicecontroller/GroupKeySecurityPolicy.java", + "src/chip/devicecontroller/ICDCheckInDelegate.java", + "src/chip/devicecontroller/ICDCheckInDelegateWrapper.java", + "src/chip/devicecontroller/ICDClientInfo.java", + "src/chip/devicecontroller/ICDDeviceInfo.java", + "src/chip/devicecontroller/ICDRegistrationInfo.java", + "src/chip/devicecontroller/KeypairDelegate.java", + "src/chip/devicecontroller/NetworkCredentials.java", + "src/chip/devicecontroller/NetworkLocation.java", + "src/chip/devicecontroller/OTAProviderDelegate.java", + "src/chip/devicecontroller/OpenCommissioningCallback.java", + "src/chip/devicecontroller/OperationalKeyConfig.java", + "src/chip/devicecontroller/PairingHintBitmap.java", + "src/chip/devicecontroller/PaseVerifierParams.java", + "src/chip/devicecontroller/ThreadScanResult.java", + "src/chip/devicecontroller/UnpairDeviceCallback.java", + "src/chip/devicecontroller/WiFiScanResult.java", + ] + if (matter_enable_java_compilation) { deps += [ "${chip_root}/third_party/java_deps:json", diff --git a/src/controller/java/CHIPInteractionClient-JNI.cpp b/src/controller/java/CHIPInteractionClient-JNI.cpp new file mode 100644 index 00000000000000..587f5da6f1406d --- /dev/null +++ b/src/controller/java/CHIPInteractionClient-JNI.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * 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 "AndroidInteractionClient.h" + +#define JNI_METHOD(RETURN, METHOD_NAME) \ + extern "C" JNIEXPORT RETURN JNICALL Java_chip_devicecontroller_ChipDeviceController_##METHOD_NAME + +JNI_METHOD(void, subscribe) +(JNIEnv * env, jobject self, jlong handle, jlong callbackHandle, jlong devicePtr, jobject attributePathList, jobject eventPathList, + jint minInterval, jint maxInterval, jboolean keepSubscriptions, jboolean isFabricFiltered, jint imTimeoutMs) +{ + CHIP_ERROR err = subscribe(env, handle, callbackHandle, devicePtr, attributePathList, eventPathList, nullptr, minInterval, + maxInterval, keepSubscriptions, isFabricFiltered, imTimeoutMs, nullptr); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "JNI IM Subscribe Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +JNI_METHOD(void, read) +(JNIEnv * env, jobject self, jlong handle, jlong callbackHandle, jlong devicePtr, jobject attributePathList, jobject eventPathList, + jboolean isFabricFiltered, jint imTimeoutMs) +{ + CHIP_ERROR err = read(env, handle, callbackHandle, devicePtr, attributePathList, eventPathList, nullptr, isFabricFiltered, + imTimeoutMs, nullptr); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "JNI IM Read Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +JNI_METHOD(void, write) +(JNIEnv * env, jobject self, jlong handle, jlong callbackHandle, jlong devicePtr, jobject attributeList, jint timedRequestTimeoutMs, + jint imTimeoutMs) +{ + CHIP_ERROR err = write(env, handle, callbackHandle, devicePtr, attributeList, timedRequestTimeoutMs, imTimeoutMs); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "JNI IM Write Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +JNI_METHOD(void, invoke) +(JNIEnv * env, jobject self, jlong handle, jlong callbackHandle, jlong devicePtr, jobject invokeElement, jint timedRequestTimeoutMs, + jint imTimeoutMs) +{ + CHIP_ERROR err = invoke(env, handle, callbackHandle, devicePtr, invokeElement, timedRequestTimeoutMs, imTimeoutMs); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "JNI IM Invoke Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +JNI_METHOD(void, extendableInvoke) +(JNIEnv * env, jobject self, jlong handle, jlong callbackHandle, jlong devicePtr, jobject invokeElementList, + jint timedRequestTimeoutMs, jint imTimeoutMs) +{ + CHIP_ERROR err = + extendableInvoke(env, handle, callbackHandle, devicePtr, invokeElementList, timedRequestTimeoutMs, imTimeoutMs); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "JNI IM Batch Invoke Error: %" CHIP_ERROR_FORMAT, err.Format()); + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index c55a45b77aaca8..66ae0a97ce86a6 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -121,7 +121,7 @@ protected void readAttribute( boolean isFabricFiltered) { ReportCallbackJni jniCallback = new ReportCallbackJni(null, callback, null); ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, attributeId); - ChipDeviceController.read(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, isFabricFiltered, timeoutMillis.orElse(0L).intValue(), null); + ChipInteractionClient.read(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, isFabricFiltered, timeoutMillis.orElse(0L).intValue(), null); } protected void writeAttribute( @@ -132,7 +132,7 @@ protected void writeAttribute( WriteAttributesCallbackJni jniCallback = new WriteAttributesCallbackJni(callback); byte[] tlv = encodeToTlv(value); AttributeWriteRequest writeRequest = AttributeWriteRequest.newInstance(endpointId, clusterId, attributeId, tlv); - ChipDeviceController.write(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(writeRequest), timedRequestTimeoutMs, timeoutMillis.orElse(0L).intValue()); + ChipInteractionClient.write(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(writeRequest), timedRequestTimeoutMs, timeoutMillis.orElse(0L).intValue()); } protected void subscribeAttribute( @@ -142,7 +142,7 @@ protected void subscribeAttribute( int maxInterval) { ReportCallbackJni jniCallback = new ReportCallbackJni(callback, callback, null); ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, attributeId); - ChipDeviceController.subscribe(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, minInterval, maxInterval, false, true, timeoutMillis.orElse(0L).intValue(), null); + ChipInteractionClient.subscribe(0, jniCallback.getCallbackHandle(), devicePtr, Arrays.asList(path), null, null, minInterval, maxInterval, false, true, timeoutMillis.orElse(0L).intValue(), null); } protected void invoke( @@ -153,7 +153,7 @@ protected void invoke( InvokeCallbackJni jniCallback = new InvokeCallbackJni(callback); byte[] tlv = encodeToTlv(value); InvokeElement element = InvokeElement.newInstance(endpointId, clusterId, commandId, tlv, null); - ChipDeviceController.invoke(0, jniCallback.getCallbackHandle(), devicePtr, element, timedRequestTimeoutMs, timeoutMillis.orElse(0L).intValue()); + ChipInteractionClient.invoke(0, jniCallback.getCallbackHandle(), devicePtr, element, timedRequestTimeoutMs, timeoutMillis.orElse(0L).intValue()); } private static native byte[] encodeToTlv(BaseTLVType value); diff --git a/src/controller/java/src/chip/devicecontroller/ChipInteractionClient.java b/src/controller/java/src/chip/devicecontroller/ChipInteractionClient.java new file mode 100644 index 00000000000000..4795fec5c1aff6 --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/ChipInteractionClient.java @@ -0,0 +1,62 @@ +package chip.devicecontroller; + +import chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.ChipEventPath; +import chip.devicecontroller.model.DataVersionFilter; +import chip.devicecontroller.model.InvokeElement; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nullable; +import chip.devicecontroller.model.AttributeWriteRequest; + +public class ChipInteractionClient { + static native void subscribe( + long deviceControllerPtr, + long callbackHandle, + long devicePtr, + List attributePaths, + List eventPaths, + List dataVersionFilters, + int minInterval, + int maxInterval, + boolean keepSubscriptions, + boolean isFabricFiltered, + int imTimeoutMs, + @Nullable Long eventMin); + + static native void read( + long deviceControllerPtr, + long callbackHandle, + long devicePtr, + List attributePaths, + List eventPaths, + List dataVersionFilters, + boolean isFabricFiltered, + int imTimeoutMs, + @Nullable Long eventMin); + + static native void write( + long deviceControllerPtr, + long callbackHandle, + long devicePtr, + List attributeList, + int timedRequestTimeoutMs, + int imTimeoutMs); + + static native void invoke( + long deviceControllerPtr, + long callbackHandle, + long devicePtr, + InvokeElement invokeElement, + int timedRequestTimeoutMs, + int imTimeoutMs); + + static native void extendableInvoke( + long deviceControllerPtr, + long callbackHandle, + long devicePtr, + List invokeElementList, + int timedRequestTimeoutMs, + int imTimeoutMs); + +} \ No newline at end of file