From 377ac096ad4b1bfab1314865e34e260d7151b674 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 14 Sep 2022 16:16:41 -0400 Subject: [PATCH] Allow java applications to set timeouts for commands (#22602) * Allow java applications to set timeouts for commands * Add zapt template updates * Code review comment: use MakeOptional * Add namespace for MakeOptional * Update src/controller/java/BaseCHIPCluster-JNI.cpp Co-authored-by: Boris Zbarsky Co-authored-by: Boris Zbarsky --- src/controller/CHIPCluster.h | 6 +++ src/controller/java/BaseCHIPCluster-JNI.cpp | 43 +++++++++++++++++++ .../java/templates/ChipClusters-java.zapt | 19 ++++++++ .../chip/devicecontroller/ChipClusters.java | 19 ++++++++ 4 files changed, 87 insertions(+) diff --git a/src/controller/CHIPCluster.h b/src/controller/CHIPCluster.h index d7ca650e1636b4..747760e2f5ea32 100644 --- a/src/controller/CHIPCluster.h +++ b/src/controller/CHIPCluster.h @@ -62,6 +62,12 @@ class DLL_EXPORT ClusterBase // TODO: remove when we start using InvokeCommand everywhere void SetCommandTimeout(Optional timeout) { mTimeout = timeout; } + /** + * Returns the current command timeout set via SetCommandTimeout, or an + * empty optional if no timeout has been set. + */ + Optional GetCommandTimeout() { return mTimeout; } + ClusterId GetClusterId() const { return mClusterId; } /* diff --git a/src/controller/java/BaseCHIPCluster-JNI.cpp b/src/controller/java/BaseCHIPCluster-JNI.cpp index e40670a13f13e8..830e757c46faf6 100644 --- a/src/controller/java/BaseCHIPCluster-JNI.cpp +++ b/src/controller/java/BaseCHIPCluster-JNI.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #define JNI_METHOD(RETURN, CLASS_NAME, METHOD_NAME) \ @@ -14,3 +15,45 @@ JNI_METHOD(void, BaseChipCluster, deleteCluster)(JNIEnv * env, jobject self, jlo delete cluster; } } + +JNI_METHOD(jobject, BaseChipCluster, getCommandTimeout) +(JNIEnv * env, jobject self, jlong clusterPtr) +{ + chip::DeviceLayer::StackLock lock; + chip::Controller::ClusterBase * cluster = reinterpret_cast(clusterPtr); + + chip::Optional timeout = cluster->GetCommandTimeout(); + if (!timeout.HasValue()) + { + jobject emptyOptional = nullptr; + chip::JniReferences::GetInstance().CreateOptional(nullptr, emptyOptional); + return emptyOptional; + } + + jobject timeoutOptional = nullptr; + jobject timeoutBoxed = nullptr; + jlong timeoutPrimitive = static_cast(timeout.Value().count()); + chip::JniReferences::GetInstance().CreateBoxedObject("java/lang/Long", "(J)V", timeoutPrimitive, timeoutBoxed); + chip::JniReferences::GetInstance().CreateOptional(timeoutBoxed, timeoutOptional); + return timeoutOptional; +} + +JNI_METHOD(void, BaseChipCluster, setCommandTimeout) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject timeoutOptional) +{ + chip::DeviceLayer::StackLock lock; + chip::Controller::ClusterBase * cluster = reinterpret_cast(clusterPtr); + + jobject boxedLong = nullptr; + chip::JniReferences::GetInstance().GetOptionalValue(timeoutOptional, boxedLong); + + if (boxedLong != nullptr) + { + jlong timeoutMillis = chip::JniReferences::GetInstance().LongToPrimitive(boxedLong); + cluster->SetCommandTimeout(chip::MakeOptional(chip::System::Clock::Milliseconds32(static_cast(timeoutMillis)))); + } + else + { + cluster->SetCommandTimeout(chip::NullOptional); + } +} diff --git a/src/controller/java/templates/ChipClusters-java.zapt b/src/controller/java/templates/ChipClusters-java.zapt index e630dbb54b043c..43dcb4a9a209b5 100644 --- a/src/controller/java/templates/ChipClusters-java.zapt +++ b/src/controller/java/templates/ChipClusters-java.zapt @@ -68,6 +68,25 @@ public class ChipClusters { chipClusterPtr = initWithDevice(devicePtr, endpointId); } + /** + * Sets the timeout, in milliseconds, after which commands sent through this cluster will fail + * with a timeout (regardless of whether or not a response has been received). If set to an + * empty optional, the default timeout will be used. + */ + public void setCommandTimeout(Optional timeoutMillis) { + setCommandTimeout(chipClusterPtr, timeoutMillis); + } + + private native void setCommandTimeout(long clusterPtr, Optional timeoutMillis); + + /** Returns the current timeout (in milliseconds) for commands sent through this cluster. */ + public Optional getCommandTimeout() { + Optional timeout = getCommandTimeout(chipClusterPtr); + return timeout == null ? Optional.empty() : timeout; + } + + private native Optional getCommandTimeout(long clusterPtr); + public abstract long initWithDevice(long devicePtr, int endpointId); public native void deleteCluster(long chipClusterPtr); diff --git a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java index b3438e06c46c3e..bb39d141a53239 100644 --- a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java @@ -97,6 +97,25 @@ public BaseChipCluster(long devicePtr, int endpointId) { chipClusterPtr = initWithDevice(devicePtr, endpointId); } + /** + * Sets the timeout, in milliseconds, after which commands sent through this cluster will fail + * with a timeout (regardless of whether or not a response has been received). If set to an + * empty optional, the default timeout will be used. + */ + public void setCommandTimeout(Optional timeoutMillis) { + setCommandTimeout(chipClusterPtr, timeoutMillis); + } + + private native void setCommandTimeout(long clusterPtr, Optional timeoutMillis); + + /** Returns the current timeout (in milliseconds) for commands sent through this cluster. */ + public Optional getCommandTimeout() { + Optional timeout = getCommandTimeout(chipClusterPtr); + return timeout == null ? Optional.empty() : timeout; + } + + private native Optional getCommandTimeout(long clusterPtr); + public abstract long initWithDevice(long devicePtr, int endpointId); public native void deleteCluster(long chipClusterPtr);