First JNI test & changes necessary to make it work (#24355)
* * Change various references of "SessionHandle &" to instead use "const SessionHandle &" to match how SessionHandle is often used as a parameter & to support rvalue
* Add Java/JNI hooks into for-test classes (like MessagingContext) to allow for unit tests of Java & JNI functionality
* Add first JNI unit test, GetConnectedDeviceCallbackJniTest, testing success/failure cases for device callback
* Restyled by whitespace
* Restyled by clang-format
* Restyled by gn
* * Fix a user-reported bug where we were seeing the following callstack:
JNIEnv::NewObject(_jclass*, _jmethodID*, ...)
chip::Controller::GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void*, chip::ScopedNodeId const&, chip::ChipError)
chip::OperationalSessionSetup::DequeueConnectionCallbacks(chip::ChipError)
chip::OperationalSessionSetup::OnNodeAddressResolutionFailed(chip::PeerId const&, chip::ChipError)
chip::AddressResolve::Impl::Resolver::HandleAction(chip::IntrusiveList<chip::AddressResolve::Impl::NodeLookupHandle, (chip::IntrusiveMode)0, chip::IntrusiveListBaseHook<chip::AddressResolve::Impl::NodeLookupHandle, (chip::IntrusiveMode)0> >::Iterator&)
chip::AddressResolve::Impl::Resolver::HandleTimer()
chip::System::LayerImplSelect::HandleEvents()
Though JNI tests were added to try to catch this at presubmit, those tests did not fail, which leads me to believe there's a difference in the JRE (wherein the version with the user-reported bug), a cast to an int is not being done, whereas in android emulator, the cast to int is done
* Add a README pointing to building android guide & specifying that these tests must be run externally due to android emulator dependency
* Fix path to android_building.md
* Restyled by clang-format
* Restyled by prettier-markdown
* Missed const correctness changes for SessionHandle&
* Restyled by clang-format
* More missed const correctness changes for SessionHandle&
* Restyled by clang-format
* More missed const correctness changes for SessionHandle&
* Restyled by clang-format
* Only build JNI test libs if chip_link_tests
* Restyled by gn
* Add missing tests.gni import
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/src/app/OperationalSessionSetup.h b/src/app/OperationalSessionSetup.h
index 6ed951f..2eb86c2 100644
--- a/src/app/OperationalSessionSetup.h
+++ b/src/app/OperationalSessionSetup.h
@@ -115,7 +115,7 @@
* application code does incorrectly hold onto this information so do not follow those incorrect
* implementations as an example.
*/
-typedef void (*OnDeviceConnected)(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+typedef void (*OnDeviceConnected)(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
typedef void (*OnDeviceConnectionFailure)(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
/**
diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp
index aa96e5f..f10ae76 100644
--- a/src/app/ReadClient.cpp
+++ b/src/app/ReadClient.cpp
@@ -822,7 +822,7 @@
timeout = System::Clock::Seconds16(mMaxInterval) + publisherTransmissionTimeout;
}
- // EFR32/MBED/INFINION/K32W's chrono count return long unsinged, but other platform returns unsigned
+ // EFR32/MBED/INFINION/K32W's chrono count return long unsigned, but other platform returns unsigned
ChipLogProgress(
DataManagement,
"Refresh LivenessCheckTime for %lu milliseconds with SubscriptionId = 0x%08" PRIx32 " Peer = %02x:" ChipLogFormatX64,
@@ -1068,7 +1068,8 @@
return CHIP_NO_ERROR;
}
-void ReadClient::HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+void ReadClient::HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr,
+ const SessionHandle & sessionHandle)
{
ReadClient * const _this = static_cast<ReadClient *>(context);
VerifyOrDie(_this != nullptr);
diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h
index cca7047..1d6487e 100644
--- a/src/app/ReadClient.h
+++ b/src/app/ReadClient.h
@@ -509,7 +509,8 @@
void StopResubscription();
void ClearActiveSubscriptionState();
- static void HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ static void HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr,
+ const SessionHandle & sessionHandle);
static void HandleDeviceConnectionFailure(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
CHIP_ERROR GetMinEventNumber(const ReadPrepareParams & aReadPrepareParams, Optional<EventNumber> & aEventMin);
diff --git a/src/app/clusters/bindings/BindingManager.cpp b/src/app/clusters/bindings/BindingManager.cpp
index 97a08ac..ef65730 100644
--- a/src/app/clusters/bindings/BindingManager.cpp
+++ b/src/app/clusters/bindings/BindingManager.cpp
@@ -123,7 +123,7 @@
return mLastSessionEstablishmentError;
}
-void BindingManager::HandleDeviceConnected(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+void BindingManager::HandleDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
FabricIndex fabricToRemove = kUndefinedFabricIndex;
NodeId nodeToRemove = kUndefinedNodeId;
diff --git a/src/app/clusters/bindings/BindingManager.h b/src/app/clusters/bindings/BindingManager.h
index 646281f..5dab477 100644
--- a/src/app/clusters/bindings/BindingManager.h
+++ b/src/app/clusters/bindings/BindingManager.h
@@ -143,7 +143,8 @@
Callback::Callback<OnDeviceConnectionFailure> * GetOnDeviceConnectionFailure() { return &mOnConnectionFailureCallback; }
private:
- static void HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+ static void HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr,
+ const SessionHandle & sessionHandle)
{
ConnectionCallback * _this = static_cast<ConnectionCallback *>(context);
_this->mBindingManager.HandleDeviceConnected(exchangeMgr, sessionHandle);
@@ -169,7 +170,7 @@
BoundDeviceChangedHandler mBoundDeviceChangedHandler;
BindingManagerInitParams mInitParams;
- void HandleDeviceConnected(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ void HandleDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
void HandleDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error);
// Used to keep track of synchronous failures from FindOrEstablishSession.
diff --git a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp
index a8e2966..8c05e0e 100644
--- a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp
+++ b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp
@@ -422,7 +422,7 @@
}
// Called whenever FindOrEstablishSession is successful
-void DefaultOTARequestor::OnConnected(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+void DefaultOTARequestor::OnConnected(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
DefaultOTARequestor * requestorCore = static_cast<DefaultOTARequestor *>(context);
VerifyOrDie(requestorCore != nullptr);
@@ -728,7 +728,7 @@
return CHIP_NO_ERROR;
}
-CHIP_ERROR DefaultOTARequestor::SendQueryImageRequest(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+CHIP_ERROR DefaultOTARequestor::SendQueryImageRequest(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
VerifyOrReturnError(mProviderLocation.HasValue(), CHIP_ERROR_INCORRECT_STATE);
@@ -796,7 +796,7 @@
return CHIP_NO_ERROR;
}
-CHIP_ERROR DefaultOTARequestor::StartDownload(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+CHIP_ERROR DefaultOTARequestor::StartDownload(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
VerifyOrReturnError(mBdxDownloader != nullptr, CHIP_ERROR_INCORRECT_STATE);
@@ -829,7 +829,8 @@
return err;
}
-CHIP_ERROR DefaultOTARequestor::SendApplyUpdateRequest(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+CHIP_ERROR DefaultOTARequestor::SendApplyUpdateRequest(Messaging::ExchangeManager & exchangeMgr,
+ const SessionHandle & sessionHandle)
{
VerifyOrReturnError(mProviderLocation.HasValue(), CHIP_ERROR_INCORRECT_STATE);
ReturnErrorOnFailure(GenerateUpdateToken());
@@ -844,7 +845,7 @@
}
CHIP_ERROR DefaultOTARequestor::SendNotifyUpdateAppliedRequest(Messaging::ExchangeManager & exchangeMgr,
- SessionHandle & sessionHandle)
+ const SessionHandle & sessionHandle)
{
VerifyOrReturnError(mProviderLocation.HasValue(), CHIP_ERROR_INCORRECT_STATE);
ReturnErrorOnFailure(GenerateUpdateToken());
diff --git a/src/app/clusters/ota-requestor/DefaultOTARequestor.h b/src/app/clusters/ota-requestor/DefaultOTARequestor.h
index 32de977..6cbe162 100644
--- a/src/app/clusters/ota-requestor/DefaultOTARequestor.h
+++ b/src/app/clusters/ota-requestor/DefaultOTARequestor.h
@@ -232,7 +232,7 @@
/**
* Send QueryImage request using values matching Basic cluster
*/
- CHIP_ERROR SendQueryImageRequest(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ CHIP_ERROR SendQueryImageRequest(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
/**
* Validate and extract mandatory information from QueryImageResponse
@@ -263,17 +263,17 @@
/**
* Start download of the software image returned in QueryImageResponse
*/
- CHIP_ERROR StartDownload(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ CHIP_ERROR StartDownload(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
/**
* Send ApplyUpdate request using values obtained from QueryImageResponse
*/
- CHIP_ERROR SendApplyUpdateRequest(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ CHIP_ERROR SendApplyUpdateRequest(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
/**
* Send NotifyUpdateApplied request
*/
- CHIP_ERROR SendNotifyUpdateAppliedRequest(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ CHIP_ERROR SendNotifyUpdateAppliedRequest(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
/**
* Store current update information to KVS
@@ -288,7 +288,7 @@
/**
* Session connection callbacks
*/
- static void OnConnected(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ static void OnConnected(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
static void OnConnectionFailure(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
Callback::Callback<OnDeviceConnected> mOnConnectedCallback;
Callback::Callback<OnDeviceConnectionFailure> mOnConnectionFailureCallback;
diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp
index 4620040..919f6cb 100644
--- a/src/controller/CHIPDeviceController.cpp
+++ b/src/controller/CHIPDeviceController.cpp
@@ -1679,7 +1679,7 @@
}
void DeviceCommissioner::OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr,
- SessionHandle & sessionHandle)
+ const SessionHandle & sessionHandle)
{
// CASE session established.
DeviceCommissioner * commissioner = static_cast<DeviceCommissioner *>(context);
diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h
index cc3588f..94c8b66 100644
--- a/src/controller/CHIPDeviceController.h
+++ b/src/controller/CHIPDeviceController.h
@@ -784,7 +784,7 @@
/* Callback called when adding root cert to device results in failure */
static void OnRootCertFailureResponse(void * context, CHIP_ERROR error);
- static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
static void OnDeviceAttestationInformationVerification(void * context,
diff --git a/src/controller/CommissionerDiscoveryController.cpp b/src/controller/CommissionerDiscoveryController.cpp
index bfb502b..bd6bee4 100644
--- a/src/controller/CommissionerDiscoveryController.cpp
+++ b/src/controller/CommissionerDiscoveryController.cpp
@@ -177,7 +177,7 @@
void CommissionerDiscoveryController::CommissioningSucceeded(uint16_t vendorId, uint16_t productId, NodeId nodeId,
Messaging::ExchangeManager & exchangeMgr,
- SessionHandle & sessionHandle)
+ const SessionHandle & sessionHandle)
{
mVendorId = vendorId;
mProductId = productId;
diff --git a/src/controller/CommissionerDiscoveryController.h b/src/controller/CommissionerDiscoveryController.h
index 8d0c36a..8d7fee9 100644
--- a/src/controller/CommissionerDiscoveryController.h
+++ b/src/controller/CommissionerDiscoveryController.h
@@ -138,7 +138,8 @@
*
*/
virtual void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId,
- chip::Messaging::ExchangeManager & exchangeMgr, chip::SessionHandle & sessionHandle) = 0;
+ chip::Messaging::ExchangeManager & exchangeMgr,
+ const chip::SessionHandle & sessionHandle) = 0;
virtual ~PostCommissioningListener() = default;
};
@@ -217,7 +218,7 @@
*
*/
void CommissioningSucceeded(uint16_t vendorId, uint16_t productId, NodeId nodeId,
- chip::Messaging::ExchangeManager & exchangeMgr, chip::SessionHandle & sessionHandle);
+ chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle);
/**
* This method should be called by the commissioner to indicate that commissioning failed.
diff --git a/src/controller/CommissioningWindowOpener.cpp b/src/controller/CommissioningWindowOpener.cpp
index 71cb87b..41deca5 100644
--- a/src/controller/CommissioningWindowOpener.cpp
+++ b/src/controller/CommissioningWindowOpener.cpp
@@ -125,7 +125,7 @@
}
CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindowInternal(Messaging::ExchangeManager & exchangeMgr,
- SessionHandle & sessionHandle)
+ const SessionHandle & sessionHandle)
{
ChipLogProgress(Controller, "OpenCommissioningWindow for device ID %" PRIu64, mNodeId);
@@ -259,7 +259,7 @@
}
void CommissioningWindowOpener::OnDeviceConnectedCallback(void * context, Messaging::ExchangeManager & exchangeMgr,
- SessionHandle & sessionHandle)
+ const SessionHandle & sessionHandle)
{
auto * self = static_cast<CommissioningWindowOpener *>(context);
diff --git a/src/controller/CommissioningWindowOpener.h b/src/controller/CommissioningWindowOpener.h
index 4e31466..d213600 100644
--- a/src/controller/CommissioningWindowOpener.h
+++ b/src/controller/CommissioningWindowOpener.h
@@ -120,13 +120,14 @@
kOpenCommissioningWindow,
};
- CHIP_ERROR OpenCommissioningWindowInternal(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ CHIP_ERROR OpenCommissioningWindowInternal(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
static void OnPIDReadResponse(void * context, uint16_t value);
static void OnVIDReadResponse(void * context, VendorId value);
static void OnVIDPIDReadFailureResponse(void * context, CHIP_ERROR error);
static void OnOpenCommissioningWindowSuccess(void * context, const app::DataModel::NullObjectType &);
static void OnOpenCommissioningWindowFailure(void * context, CHIP_ERROR error);
- static void OnDeviceConnectedCallback(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ static void OnDeviceConnectedCallback(void * context, Messaging::ExchangeManager & exchangeMgr,
+ const SessionHandle & sessionHandle);
static void OnDeviceConnectionFailureCallback(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
DeviceController * const mController = nullptr;
diff --git a/src/controller/CurrentFabricRemover.cpp b/src/controller/CurrentFabricRemover.cpp
index d5aefe9..f6e2229 100644
--- a/src/controller/CurrentFabricRemover.cpp
+++ b/src/controller/CurrentFabricRemover.cpp
@@ -35,7 +35,8 @@
return mController->GetConnectedDevice(remoteNodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback);
}
-CHIP_ERROR CurrentFabricRemover::ReadCurrentFabricIndex(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+CHIP_ERROR CurrentFabricRemover::ReadCurrentFabricIndex(Messaging::ExchangeManager & exchangeMgr,
+ const SessionHandle & sessionHandle)
{
using TypeInfo = chip::app::Clusters::OperationalCredentials::Attributes::CurrentFabricIndex::TypeInfo;
OperationalCredentialsCluster cluster(exchangeMgr, sessionHandle, kRootEndpointId);
@@ -43,7 +44,8 @@
return cluster.ReadAttribute<TypeInfo>(this, OnSuccessReadCurrentFabricIndex, OnReadAttributeFailure);
}
-CHIP_ERROR CurrentFabricRemover::SendRemoveFabricIndex(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+CHIP_ERROR CurrentFabricRemover::SendRemoveFabricIndex(Messaging::ExchangeManager & exchangeMgr,
+ const SessionHandle & sessionHandle)
{
if (mFabricIndex == kUndefinedFabricIndex)
{
@@ -59,7 +61,7 @@
}
void CurrentFabricRemover::OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr,
- SessionHandle & sessionHandle)
+ const SessionHandle & sessionHandle)
{
CHIP_ERROR err = CHIP_NO_ERROR;
auto * self = static_cast<CurrentFabricRemover *>(context);
diff --git a/src/controller/CurrentFabricRemover.h b/src/controller/CurrentFabricRemover.h
index 8acef3c..63921f9 100644
--- a/src/controller/CurrentFabricRemover.h
+++ b/src/controller/CurrentFabricRemover.h
@@ -70,10 +70,10 @@
FabricIndex mFabricIndex = kUndefinedFabricIndex;
Step mNextStep = Step::kAcceptRemoveFabricStart;
- CHIP_ERROR ReadCurrentFabricIndex(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
- CHIP_ERROR SendRemoveFabricIndex(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ CHIP_ERROR ReadCurrentFabricIndex(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
+ CHIP_ERROR SendRemoveFabricIndex(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
- static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
static void OnSuccessReadCurrentFabricIndex(void * context, FabricIndex fabricIndex);
diff --git a/src/controller/java/AndroidCallbacks-ForTestJNI.cpp b/src/controller/java/AndroidCallbacks-ForTestJNI.cpp
new file mode 100644
index 0000000..ecec62d
--- /dev/null
+++ b/src/controller/java/AndroidCallbacks-ForTestJNI.cpp
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright (c) 2020-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 <jni.h>
+
+#include "AndroidCallbacks.h"
+#include "lib/support/CHIPMem.h"
+#include "lib/support/CodeUtils.h"
+#include "lib/support/logging/CHIPLogging.h"
+#include "messaging/tests/MessagingContext.h"
+
+#define JNI_METHOD(RETURN, CLASS_NAME, METHOD_NAME) \
+ extern "C" JNIEXPORT RETURN JNICALL Java_chip_devicecontroller_##CLASS_NAME##_##METHOD_NAME
+
+using namespace chip;
+using namespace chip::Controller;
+using namespace chip::Test;
+
+JNI_METHOD(void, GetConnectedDeviceCallbackForTestJni, onDeviceConnected)
+(JNIEnv * env, jobject self, jlong callbackHandle, jlong messagingContextHandle)
+{
+ GetConnectedDeviceCallback * connectedDeviceCallback = reinterpret_cast<GetConnectedDeviceCallback *>(callbackHandle);
+ VerifyOrReturn(connectedDeviceCallback != nullptr, ChipLogError(Controller, "GetConnectedDeviceCallbackJni handle is nullptr"));
+
+ MessagingContext * messagingContext = reinterpret_cast<MessagingContext *>(messagingContextHandle);
+ VerifyOrReturn(messagingContext != nullptr, ChipLogError(Controller, "MessagingContext handle is nullptr"));
+
+ GetConnectedDeviceCallback::OnDeviceConnectedFn(connectedDeviceCallback, messagingContext->GetExchangeManager(),
+ messagingContext->GetSessionBobToAlice());
+}
+
+JNI_METHOD(void, GetConnectedDeviceCallbackForTestJni, onDeviceConnectionFailure)
+(JNIEnv * env, jobject self, jlong callbackHandle, jint errorCode)
+{
+ GetConnectedDeviceCallback * connectedDeviceCallback = reinterpret_cast<GetConnectedDeviceCallback *>(callbackHandle);
+ VerifyOrReturn(connectedDeviceCallback != nullptr, ChipLogError(Controller, "GetConnectedDeviceCallbackJni handle is nullptr"));
+
+ GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(connectedDeviceCallback, ScopedNodeId(), chip::ChipError(errorCode));
+}
diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp
index e1df5b4..17635ba 100644
--- a/src/controller/java/AndroidCallbacks.cpp
+++ b/src/controller/java/AndroidCallbacks.cpp
@@ -58,7 +58,7 @@
}
void GetConnectedDeviceCallback::OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr,
- SessionHandle & sessionHandle)
+ const SessionHandle & sessionHandle)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
auto * self = static_cast<GetConnectedDeviceCallback *>(context);
diff --git a/src/controller/java/AndroidCallbacks.h b/src/controller/java/AndroidCallbacks.h
index 915825a..cd7fdfd 100644
--- a/src/controller/java/AndroidCallbacks.h
+++ b/src/controller/java/AndroidCallbacks.h
@@ -33,7 +33,7 @@
GetConnectedDeviceCallback(jobject wrapperCallback, jobject javaCallback);
~GetConnectedDeviceCallback();
- static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle);
+ static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
Callback::Callback<OnDeviceConnected> mOnSuccess;
diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn
index cf1c5fa..70f2b13 100644
--- a/src/controller/java/BUILD.gn
+++ b/src/controller/java/BUILD.gn
@@ -16,6 +16,7 @@
import("//build_overrides/chip.gni")
import("${chip_root}/build/chip/java/config.gni")
import("${chip_root}/build/chip/java/rules.gni")
+import("${chip_root}/build/chip/tests.gni")
if (!build_java_matter_controller) {
import("${build_root}/config/android_abi.gni")
@@ -89,6 +90,37 @@
ldflags = [ "-Wl,--gc-sections" ]
}
+if (chip_link_tests) {
+ shared_library("jni_for_test") {
+ sources = [ "AndroidCallbacks-ForTestJNI.cpp" ]
+ output_name = "libCHIPForTestController"
+
+ public_configs = [ "${chip_root}/src:includes" ]
+
+ deps = [
+ ":jni",
+ "${chip_root}/src/messaging/tests:helpers",
+ ]
+
+ if (build_java_matter_controller) {
+ defines = [ "JAVA_MATTER_CONTROLLER_TEST" ]
+ include_dirs = java_matter_controller_dependent_paths
+
+ deps += [ "${chip_root}/src/platform/Linux" ]
+
+ cflags = [ "-Wno-unknown-pragmas" ]
+
+ output_dir = "${root_out_dir}/lib/jni"
+ } else {
+ deps += [ "${chip_root}/src/platform/android" ]
+
+ output_dir = "${root_out_dir}/lib/jni/${android_abi}"
+ }
+
+ ldflags = [ "-Wl,--gc-sections" ]
+ }
+}
+
android_library("java") {
output_name = "CHIPController.jar"
@@ -163,6 +195,74 @@
# ..../platforms/android-21/android.jar to access BLE items)
}
+if (chip_link_tests) {
+ android_library("java_for_test") {
+ output_name = "CHIPControllerForTest.jar"
+
+ deps = [ "${chip_root}/third_party/java_deps:annotation" ]
+
+ data_deps = [
+ ":jni",
+ ":jni_for_test",
+ ]
+
+ sources = [
+ "src/chip/devicecontroller/GetConnectedDeviceCallbackForTestJni.java",
+ ]
+
+ if (build_java_matter_controller) {
+ 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" ]
+
+ # TODO: add classpath support (we likely need to add something like
+ # ..../platforms/android-21/android.jar to access BLE items)
+ }
+
+ android_library("tests") {
+ output_name = "CHIPControllerTests.jar"
+
+ deps = [
+ ":java_for_test",
+ "${chip_root}/src/messaging/tests/java",
+ "${chip_root}/third_party/java_deps:annotation",
+ ]
+
+ data_deps = [
+ ":jni",
+ ":jni_for_test",
+ "${chip_root}/src/messaging/tests/java:jni",
+ ]
+
+ sources =
+ [ "tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java" ]
+
+ if (build_java_matter_controller) {
+ 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" ]
+
+ # TODO: add classpath support (we likely need to add something like
+ # ..../platforms/android-21/android.jar to access BLE items)
+ }
+}
+
if (!build_java_matter_controller) {
java_prebuilt("android") {
jar_path = "${android_sdk_root}/platforms/android-21/android.jar"
diff --git a/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackForTestJni.java b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackForTestJni.java
new file mode 100644
index 0000000..a3321af
--- /dev/null
+++ b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackForTestJni.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2020-2023 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.
+ *
+ */
+package chip.devicecontroller;
+
+import chip.testing.MessagingContext;
+
+/** Utilities for unit testing {@link GetConnectedDeviceCallbackJni}. */
+public final class GetConnectedDeviceCallbackForTestJni {
+ private final MessagingContext messagingContext;
+
+ static {
+ System.loadLibrary("CHIPForTestController");
+ }
+
+ public GetConnectedDeviceCallbackForTestJni(MessagingContext messagingContext) {
+ this.messagingContext = messagingContext;
+ }
+
+ public void onDeviceConnected(GetConnectedDeviceCallbackJni callback) {
+ onDeviceConnected(callback.getCallbackHandle(), messagingContext.getMessagingContextHandle());
+ }
+
+ private native void onDeviceConnected(long callbackHandle, long messagingContextHandle);
+
+ public void onDeviceConnectionFailure(GetConnectedDeviceCallbackJni callback, int errorCode) {
+ onDeviceConnectionFailure(callback.getCallbackHandle(), errorCode);
+ }
+
+ private native void onDeviceConnectionFailure(long callbackHandle, int errorCode);
+}
diff --git a/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java
index d00cdc4..b45b04a 100644
--- a/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java
+++ b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java
@@ -19,7 +19,7 @@
/** JNI wrapper callback class for getting a connected device. */
public class GetConnectedDeviceCallbackJni {
- private GetConnectedDeviceCallback wrappedCallback;
+ private final GetConnectedDeviceCallback wrappedCallback;
private long callbackHandle;
public GetConnectedDeviceCallbackJni(GetConnectedDeviceCallback wrappedCallback) {
diff --git a/src/controller/java/tests/README.md b/src/controller/java/tests/README.md
new file mode 100644
index 0000000..14aedc4
--- /dev/null
+++ b/src/controller/java/tests/README.md
@@ -0,0 +1,8 @@
+# Android emulator tests
+
+**These tests must be run externally**
+
+## Building & setting up emulator
+
+Please refer to [Building Android](../../../../docs/guides/android_building.md)
+guide to learn how to setup & run these tests in an android emulator.
diff --git a/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java b/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java
new file mode 100644
index 0000000..f7f9814
--- /dev/null
+++ b/src/controller/java/tests/chip/devicecontroller/GetConnectedDeviceCallbackJniTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2020-2023 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.
+ *
+ */
+package chip.devicecontroller;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import chip.devicecontroller.GetConnectedDeviceCallbackJni.GetConnectedDeviceCallback;
+import chip.testing.MessagingContext;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public final class GetConnectedDeviceCallbackJniTest {
+ private GetConnectedDeviceCallbackForTestJni callbackTestUtil;
+
+ @Before
+ public void setUp() {
+ callbackTestUtil = new GetConnectedDeviceCallbackForTestJni(new MessagingContext());
+ }
+
+ @Test
+ public void deviceConnected() {
+ var callback = new FakeGetConnectedDeviceCallback();
+ var jniCallback = new GetConnectedDeviceCallbackJni(callback);
+ callbackTestUtil.onDeviceConnected(jniCallback);
+
+ assertThat(callback.devicePointer).isNotEqualTo(0L);
+ }
+
+ @Test
+ public void connectionFailure() {
+ var callback = new FakeGetConnectedDeviceCallback();
+ var jniCallback = new GetConnectedDeviceCallbackJni(callback);
+ callbackTestUtil.onDeviceConnectionFailure(jniCallback, 100);
+
+ assertThat(callback.error).isInstanceOf(ChipDeviceControllerException.class);
+ assertThat(((ChipDeviceControllerException) callback.error).errorCode).isEqualTo(100);
+ }
+
+ class FakeGetConnectedDeviceCallback implements GetConnectedDeviceCallback {
+ long devicePointer = 0;
+ long nodeId = 0;
+ Exception error = null;
+
+ @Override
+ public void onDeviceConnected(long devicePointer) {
+ this.devicePointer = devicePointer;
+ }
+
+ @Override
+ public void onConnectionFailure(long nodeId, Exception error) {
+ this.nodeId = nodeId;
+ this.error = error;
+ }
+ }
+}
diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp
index d055bab..ea376ba 100644
--- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp
+++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp
@@ -587,7 +587,7 @@
mOnSuccess(OnDeviceConnectedFn, this), mOnFailure(OnConnectionFailureFn, this), mCallback(callback)
{}
- static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle)
+ static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
{
auto * self = static_cast<GetDeviceCallbacks *>(context);
auto * operationalDeviceProxy = new OperationalDeviceProxy(&exchangeMgr, sessionHandle);
diff --git a/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.h b/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.h
index 9bc96cc..bf7c8b7 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.h
+++ b/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.h
@@ -64,7 +64,8 @@
chip::Callback::Callback<chip::OnDeviceConnected> mOnConnected;
chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnConnectFailed;
- static void OnConnected(void * context, chip::Messaging::ExchangeManager & exchangeMgr, chip::SessionHandle & sessionHandle);
+ static void OnConnected(
+ void * context, chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle);
static void OnConnectionFailure(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error);
};
diff --git a/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.mm b/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.mm
index f61aeee..490fe3e 100644
--- a/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.mm
+++ b/src/darwin/Framework/CHIP/MTRDeviceConnectionBridge.mm
@@ -20,7 +20,7 @@
#import "MTRError_Internal.h"
void MTRDeviceConnectionBridge::OnConnected(
- void * context, chip::Messaging::ExchangeManager & exchangeMgr, chip::SessionHandle & sessionHandle)
+ void * context, chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle)
{
auto * object = static_cast<MTRDeviceConnectionBridge *>(context);
object->mCompletionHandler(&exchangeMgr, chip::MakeOptional<chip::SessionHandle>(*sessionHandle->AsSecureSession()), nil);
diff --git a/src/messaging/tests/java/BUILD.gn b/src/messaging/tests/java/BUILD.gn
new file mode 100644
index 0000000..5903014
--- /dev/null
+++ b/src/messaging/tests/java/BUILD.gn
@@ -0,0 +1,80 @@
+# Copyright (c) 2020-2021 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.
+
+import("//build_overrides/build.gni")
+import("//build_overrides/chip.gni")
+import("${chip_root}/build/chip/java/config.gni")
+import("${chip_root}/build/chip/java/rules.gni")
+
+if (!build_java_matter_controller) {
+ import("${build_root}/config/android_abi.gni")
+}
+
+shared_library("jni") {
+ output_name = "libCHIPMessaging"
+
+ sources = [ "MessagingContext-JNI.cpp" ]
+ deps = [ "${chip_root}/src/messaging/tests:helpers" ]
+
+ public_configs = [ "${chip_root}/src:includes" ]
+
+ if (build_java_matter_controller) {
+ defines = [ "JAVA_MATTER_CONTROLLER_TEST" ]
+ include_dirs = java_matter_controller_dependent_paths
+
+ deps += [ "${chip_root}/src/platform/Linux" ]
+
+ cflags = [ "-Wno-unknown-pragmas" ]
+
+ output_dir = "${root_out_dir}/lib/jni"
+ } else {
+ deps += [ "${chip_root}/src/platform/android" ]
+
+ output_dir = "${root_out_dir}/lib/jni/${android_abi}"
+ }
+
+ ldflags = [ "-Wl,--gc-sections" ]
+}
+
+android_library("java") {
+ output_name = "CHIPMessaging.jar"
+
+ deps = [ "${chip_root}/third_party/java_deps:annotation" ]
+
+ data_deps = [ ":jni" ]
+
+ sources = [ "src/chip/testing/MessagingContext.java" ]
+
+ if (build_java_matter_controller) {
+ 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" ]
+
+ # TODO: add classpath support (we likely need to add something like
+ # ..../platforms/android-21/android.jar to access BLE items)
+}
+
+if (!build_java_matter_controller) {
+ java_prebuilt("android") {
+ jar_path = "${android_sdk_root}/platforms/android-21/android.jar"
+ }
+}
diff --git a/src/messaging/tests/java/MessagingContext-JNI.cpp b/src/messaging/tests/java/MessagingContext-JNI.cpp
new file mode 100644
index 0000000..0c3b40a
--- /dev/null
+++ b/src/messaging/tests/java/MessagingContext-JNI.cpp
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2020-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 <jni.h>
+
+#include "lib/support/CHIPMem.h"
+#include "lib/support/CodeUtils.h"
+#include "lib/support/JniReferences.h"
+#include "lib/support/logging/CHIPLogging.h"
+#include "messaging/tests/MessagingContext.h"
+
+#define JNI_METHOD(RETURN, CLASS_NAME, METHOD_NAME) \
+ extern "C" JNIEXPORT RETURN JNICALL Java_chip_testing_##CLASS_NAME##_##METHOD_NAME
+
+using namespace chip;
+using namespace chip::Test;
+
+JNI_METHOD(jlong, MessagingContext, newMessagingContext)
+(JNIEnv * env, jobject self, jboolean initializeNodes)
+{
+ LoopbackMessagingContext * messagingContext = chip::Platform::New<LoopbackMessagingContext>();
+ messagingContext->ConfigInitializeNodes(initializeNodes != JNI_FALSE);
+ CHIP_ERROR err = messagingContext->Init();
+ if (err != CHIP_NO_ERROR)
+ {
+ jclass exceptionCls = env->FindClass("chip/platform/AndroidChipPlatformException");
+ JniReferences::GetInstance().ThrowError(env, exceptionCls, err);
+ return 0;
+ }
+
+ MessagingContext * messagingContextResult = messagingContext;
+ return reinterpret_cast<jlong>(messagingContextResult);
+}
+
+JNI_METHOD(void, MessagingContext, deleteMessagingContext)
+(JNIEnv * env, jobject self, jlong contextHandle)
+{
+ MessagingContext * messagingContext = reinterpret_cast<MessagingContext *>(contextHandle);
+ VerifyOrReturn(messagingContext != nullptr, ChipLogError(Test, "MessagingContext handle is nullptr"));
+ messagingContext->Shutdown();
+ delete messagingContext;
+}
diff --git a/src/messaging/tests/java/src/chip/testing/MessagingContext.java b/src/messaging/tests/java/src/chip/testing/MessagingContext.java
new file mode 100644
index 0000000..a20dc3f
--- /dev/null
+++ b/src/messaging/tests/java/src/chip/testing/MessagingContext.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020-2023 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.
+ *
+ */
+package chip.testing;
+
+/** JNI wrapper for test utilities class. */
+public final class MessagingContext {
+ private long messagingContextHandle;
+
+ static {
+ System.loadLibrary("CHIPMessaging");
+ }
+
+ public MessagingContext(boolean initializeNodes) {
+ this.messagingContextHandle = newMessagingContext(initializeNodes);
+ }
+
+ public MessagingContext() {
+ this(true);
+ }
+
+ public long getMessagingContextHandle() {
+ return messagingContextHandle;
+ }
+
+ private native long newMessagingContext(boolean initializeNodes);
+
+ private native void deleteMessagingContext(long messagingContextHandle);
+
+ // TODO(#8578): Replace finalizer with PhantomReference.
+ @SuppressWarnings("deprecation")
+ protected void finalize() throws Throwable {
+ super.finalize();
+
+ if (messagingContextHandle != 0) {
+ deleteMessagingContext(messagingContextHandle);
+ messagingContextHandle = 0;
+ }
+ }
+}
diff --git a/src/transport/raw/tests/NetworkTestHelpers.cpp b/src/transport/raw/tests/NetworkTestHelpers.cpp
index e21c022..7e8e45e 100644
--- a/src/transport/raw/tests/NetworkTestHelpers.cpp
+++ b/src/transport/raw/tests/NetworkTestHelpers.cpp
@@ -30,7 +30,7 @@
CHIP_ERROR IOContext::Init()
{
CHIP_ERROR err = Platform::MemoryInit();
- chip::DeviceLayer::SetConfigurationMgr(&chip::DeviceLayer::ConfigurationManagerImpl::GetDefaultInstance());
+ chip::DeviceLayer::SetConfigurationMgr(&chip::DeviceLayer::ConfigurationMgrImpl());
gSystemLayer.Init();