Skip to content

Commit 5175651

Browse files
austinh0pull[bot]
authored andcommitted
Use templated reads/writes. (#12127)
1 parent e979a18 commit 5175651

23 files changed

+8335
-2007
lines changed

src/app/zap-templates/templates/chip/helper.js

+28-3
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,35 @@ function chip_has_clusters(options)
152152
* @param {*} options
153153
*/
154154
function chip_server_global_responses(options)
155+
{
156+
return asBlocks.call(this, getServerGlobalAttributeResponses(), options);
157+
}
158+
159+
async function if_in_global_responses(options)
160+
{
161+
const attribute = this.response.arguments[0];
162+
const globalResponses = await getServerGlobalAttributeResponses();
163+
const responseTypeExists = globalResponses.find(
164+
// Some fields of item/attribute here may be undefined.
165+
item => item.isList == attribute.isList && item.isStruct == attribute.isStruct && item.chipType == attribute.chipType
166+
&& item.isNullable == attribute.isNullable && item.isOptional == attribute.isOptional)
167+
168+
if (responseTypeExists)
169+
{
170+
return options.fn(this);
171+
}
172+
else
173+
{
174+
return options.inverse(this);
175+
}
176+
}
177+
178+
function getServerGlobalAttributeResponses()
155179
{
156180
const sorter = (a, b) => a.chipCallback.name.localeCompare(b.chipCallback.name, 'en', { numeric : true });
157181

158182
const reducer = (unique, item) => {
159-
const { type, size, isList, chipCallback, chipType } = item.response.arguments[0];
183+
const { type, size, isList, isOptional, isNullable, chipCallback, chipType } = item.response.arguments[0];
160184

161185
// List-typed elements have a dedicated callback
162186
if (isList) {
@@ -167,11 +191,11 @@ function chip_server_global_responses(options)
167191
return unique;
168192
}
169193

170-
return [...unique, { chipCallback, chipType, size } ];
194+
return [...unique, { chipCallback, chipType, size, isOptional, isNullable } ];
171195
};
172196

173197
const filter = attributes => attributes.reduce(reducer, []).sort(sorter);
174-
return asBlocks.call(this, Clusters.getAttributesByClusterSide('server').then(filter), options);
198+
return Clusters.getAttributesByClusterSide('server').then(filter);
175199
}
176200

177201
/**
@@ -381,3 +405,4 @@ exports.chip_server_cluster_attributes = chip_server_clust
381405
exports.chip_server_has_list_attributes = chip_server_has_list_attributes;
382406
exports.chip_available_cluster_commands = chip_available_cluster_commands;
383407
exports.if_chip_enum = if_chip_enum;
408+
exports.if_in_global_responses = if_in_global_responses;

src/controller/java/templates/CHIPCallbackTypes.zapt

+11
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,22 @@
44
#include <app-common/zap-generated/cluster-objects.h>
55

66
typedef void (*CHIPDefaultSuccessCallbackType)(void *, const chip::app::DataModel::NullObjectType &);
7+
typedef void (*CHIPDefaultWriteSuccessCallbackType)(void *);
78
typedef void (*CHIPDefaultFailureCallbackType)(void *, EmberAfStatus);
89

910
{{#chip_client_clusters}}
1011
{{#chip_cluster_responses}}
1112
typedef void (*CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}CallbackType)(void *, const chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::DecodableType &);
1213
{{/chip_cluster_responses}}
14+
15+
{{! TODO: global response types?}}
16+
17+
{{#chip_server_cluster_attributes}}
18+
{{#if isList}}
19+
typedef void (*CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}AttributeCallbackType)(void *, const chip::app::Clusters::{{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo::DecodableType &);
20+
{{else}}
21+
typedef void (*CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}AttributeCallbackType)(void *, chip::app::Clusters::{{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo::DecodableArgType);
22+
{{/if}}
23+
{{/chip_server_cluster_attributes}}
1324
{{/chip_client_clusters}}
1425
{{/if}}

src/controller/java/templates/CHIPClusters-JNI.zapt

+9-10
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,14 @@ JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, {{asLowerCamelCase name}})
8181
{{! TODO: Lists not supported in attribute writes yet. }}
8282
{{#unless isList}}
8383

84-
JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, write{{asUpperCamelCase name}}Attribute)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, {{asJniBasicType type false}} value)
84+
JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, write{{asUpperCamelCase name}}Attribute)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, {{asJniBasicType type true}} value)
8585
{
8686
chip::DeviceLayer::StackLock lock;
87+
using TypeInfo = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
88+
TypeInfo::Type cppValue;
89+
90+
{{>encode_value target="cppValue" source="value"}}
91+
8792
std::unique_ptr<CHIPDefaultSuccessCallback, void (*)(CHIPDefaultSuccessCallback *)> onSuccess(Platform::New<CHIPDefaultSuccessCallback>(callback), Platform::Delete<CHIPDefaultSuccessCallback>);
8893
VerifyOrReturn(onSuccess.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY));
8994

@@ -94,15 +99,9 @@ JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, write{{asUpperCamelCase na
9499
{{asCamelCased ../name false}}Cluster * cppCluster = reinterpret_cast<{{asCamelCased ../name false}}Cluster *>(clusterPtr);
95100
VerifyOrReturn(cppCluster != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE));
96101

97-
{{#if (isOctetString type)}}
98-
JniByteArray jniArr(env, value);
99-
err = cppCluster->WriteAttribute{{asUpperCamelCase name}}(onSuccess->Cancel(), onFailure->Cancel(), chip::ByteSpan((const uint8_t*) jniArr.data(), jniArr.size()));
100-
{{else if (isCharString type)}}
101-
JniUtfString valueStr(env, value);
102-
err = cppCluster->WriteAttribute{{asUpperCamelCase name}}(onSuccess->Cancel(), onFailure->Cancel(), chip::CharSpan(valueStr.c_str(), strlen(valueStr.c_str())));
103-
{{else}}
104-
err = cppCluster->WriteAttribute{{asUpperCamelCase name}}(onSuccess->Cancel(), onFailure->Cancel(), static_cast<{{chipType}}>(value));
105-
{{/if}}
102+
auto successFn = chip::Callback::Callback<CHIPDefaultWriteSuccessCallbackType>::FromCancelable(onSuccess->Cancel());
103+
auto failureFn = chip::Callback::Callback<CHIPDefaultFailureCallbackType>::FromCancelable(onFailure->Cancel());
104+
err = cppCluster->WriteAttribute<TypeInfo>(cppValue, onSuccess->mContext, successFn->mCall, failureFn->mCall);
106105
VerifyOrReturn(err == CHIP_NO_ERROR, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error writing attribute", err));
107106

108107
onSuccess.release();

src/controller/java/templates/CHIPClustersRead-JNI.zapt

+14-8
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919
JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, read{{asUpperCamelCase name}}Attribute)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback)
2020
{
2121
chip::DeviceLayer::StackLock lock;
22-
{{#if isList}}
23-
std::unique_ptr<CHIP{{asCamelCased parent.name false}}{{asCamelCased name false}}AttributeCallback, void (*)(CHIP{{asCamelCased parent.name false}}{{asCamelCased name false}}AttributeCallback *)> onSuccess(
24-
chip::Platform::New<CHIP{{asCamelCased parent.name false}}{{asCamelCased name false}}AttributeCallback>(callback), chip::Platform::Delete<CHIP{{asCamelCased parent.name false}}{{asCamelCased name false}}AttributeCallback>);
25-
{{else}}
26-
std::unique_ptr<CHIP{{chipCallback.name}}AttributeCallback, void (*)(CHIP{{chipCallback.name}}AttributeCallback *)> onSuccess(chip::Platform::New<CHIP{{chipCallback.name}}AttributeCallback>(callback{{#if (isString type)}},
27-
{{#if (isOctetString type)}}true{{else}}false{{/if}}{{/if}}), chip::Platform::Delete<CHIP{{chipCallback.name}}AttributeCallback>);
28-
{{/if}}
22+
using TypeInfo = chip::app::Clusters::{{asUpperCamelCase ../name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
23+
24+
{{~#*inline "callbackName"}}
25+
{{#if_in_global_responses}}
26+
CHIP{{chipCallback.name}}AttributeCallback
27+
{{else}}
28+
CHIP{{asCamelCased parent.name false}}{{asCamelCased name false}}AttributeCallback
29+
{{/if_in_global_responses}}
30+
{{/inline}}
31+
32+
std::unique_ptr<{{>callbackName}}, void (*)({{>callbackName}} *)> onSuccess(chip::Platform::New<{{>callbackName}}>(callback, false), chip::Platform::Delete<{{>callbackName}}>);
2933
VerifyOrReturn(onSuccess.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY));
3034

3135
std::unique_ptr<chip::CHIPDefaultFailureCallback, void (*)(chip::CHIPDefaultFailureCallback *)> onFailure(chip::Platform::New<chip::CHIPDefaultFailureCallback>(callback), chip::Platform::Delete<chip::CHIPDefaultFailureCallback>);
@@ -35,7 +39,9 @@ JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, read{{asUpperCamelCase nam
3539
chip::Controller::{{asCamelCased ../name false}}Cluster * cppCluster = reinterpret_cast<chip::Controller::{{asCamelCased ../name false}}Cluster *>(clusterPtr);
3640
VerifyOrReturn(cppCluster != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE));
3741

38-
err = cppCluster->ReadAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel());
42+
auto successFn = chip::Callback::Callback<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}AttributeCallbackType>::FromCancelable(onSuccess->Cancel());
43+
auto failureFn = chip::Callback::Callback<CHIPDefaultFailureCallbackType>::FromCancelable(onFailure->Cancel());
44+
err = cppCluster->ReadAttribute<TypeInfo>(onSuccess->mContext, successFn->mCall, failureFn->mCall);
3945
VerifyOrReturn(err == CHIP_NO_ERROR, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error reading attribute", err));
4046

4147
onSuccess.release();

src/controller/java/templates/CHIPInvokeCallbacks-src.zapt

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ void CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callbac
6161
// Java callback is allowed to be null, exit early if this is the case.
6262
VerifyOrReturn(javaCallbackRef != nullptr);
6363

64-
err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "({{#chip_cluster_response_arguments}}{{#if isArray}}{{else if isOptional}}Ljava/util/Optional;{{else if (isOctetString type)}}[B{{else if (isShortString type)}}Ljava/lang/String;{{else}}{{asJniSignature type true}}{{/if}}{{/chip_cluster_response_arguments}})V", &javaMethod);
64+
err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "({{#chip_cluster_response_arguments}}{{#if isArray}}{{else if isOptional}}Ljava/util/Optional;{{else if (isOctetString type)}}[B{{else if (isCharString type)}}Ljava/lang/String;{{else}}{{asJniSignature type true}}{{/if}}{{/chip_cluster_response_arguments}})V", &javaMethod);
6565
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));
6666

6767
{{#chip_cluster_response_arguments}}
68-
{{>decode_value}}
68+
{{>decode_value source=(concat "dataResponse." (asLowerCamelCase name)) target=(asSymbol label)}}
6969
{{/chip_cluster_response_arguments}}
7070

7171
env->CallVoidMethod(javaCallbackRef, javaMethod{{#chip_cluster_response_arguments}}, {{asSymbol label}}{{/chip_cluster_response_arguments}});

src/controller/java/templates/CHIPReadCallbacks-src.zapt

+33-4
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ void CHIP{{chipCallback.name}}AttributeCallback::CallbackFn(void * context, {{ch
8282

8383
{{#chip_client_clusters}}
8484
{{#chip_server_cluster_attributes}}
85-
{{#if isList}}
8685

8786
{{! NOTE: Some of our helpers rely on broken ZAP APIs that sniff for "isArray"
8887
when we are just trying to work with the type of an array element. Fix
@@ -92,8 +91,10 @@ void CHIP{{chipCallback.name}}AttributeCallback::CallbackFn(void * context, {{ch
9291
{{~#*inline "asUnboxedJniSignatureForEntry"}}{{> asUnboxedJniSignature isArray=false}}{{/inline~}}
9392
{{~#*inline "asBoxedJavaBasicType"}}{{asJavaBasicTypeForZclType type true}}{{/inline~}}
9493
{{~#*inline "asBoxedJavaBasicTypeForEntry"}}{{>asBoxedJavaBasicType isArray=false}}{{/inline~}}
95-
CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback(jobject javaCallback) :
96-
chip::Callback::Callback<{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}ListAttributeCallback>(CallbackFn, this)
94+
{{#if_in_global_responses}}
95+
{{else}}
96+
CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback(jobject javaCallback, bool keepAlive) :
97+
chip::Callback::Callback<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}AttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
9798
{
9899
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
99100
if (env == nullptr) {
@@ -116,7 +117,9 @@ CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::
116117
}
117118
env->DeleteGlobalRef(javaCallbackRef);
118119
}
120+
{{/if_in_global_responses}}
119121

122+
{{#if isList}}
120123
void CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::CallbackFn(void * context, {{zapTypeToDecodableClusterObjectType type ns=parent.name isArgument=true}} list)
121124
{
122125
chip::DeviceLayer::StackUnlock unlock;
@@ -126,7 +129,7 @@ void CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallb
126129

127130
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
128131

129-
std::unique_ptr<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback> cppCallback(reinterpret_cast<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback *>(context));
132+
std::unique_ptr<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback, decltype(&maybeDestroy)> cppCallback(reinterpret_cast<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback *>(context), maybeDestroy);
130133

131134
// It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
132135
javaCallbackRef = cppCallback.get()->javaCallbackRef;
@@ -311,6 +314,32 @@ void CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallb
311314
env->ExceptionClear();
312315
env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
313316
}
317+
{{else}}
318+
{{#if_in_global_responses}}
319+
{{else}}
320+
void CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::CallbackFn(void * context, {{zapTypeToDecodableClusterObjectType type ns=parent.name isArgument=true}} value)
321+
{
322+
chip::DeviceLayer::StackUnlock unlock;
323+
CHIP_ERROR err = CHIP_NO_ERROR;
324+
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
325+
jobject javaCallbackRef;
326+
327+
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
328+
std::unique_ptr<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback, decltype(&maybeDestroy)> cppCallback(reinterpret_cast<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback *>(context), maybeDestroy);
329+
330+
// It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
331+
javaCallbackRef = cppCallback.get()->javaCallbackRef;
332+
VerifyOrReturn(javaCallbackRef != nullptr, ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));
333+
334+
jmethodID javaMethod;
335+
err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "({{#if isArray}}{{else if isStruct}}{{else if isOptional}}Ljava/util/Optional;{{else if (isOctetString type)}}[B{{else if (isCharString type)}}Ljava/lang/String;{{else}}{{asJniSignature type true}}{{/if}})V", &javaMethod);
336+
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));
337+
338+
{{>decode_value source="value" target="javaValue"}}
339+
340+
env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
341+
}
342+
{{/if_in_global_responses}}
314343
{{/if}}
315344
{{/chip_server_cluster_attributes}}
316345
{{/chip_client_clusters}}

src/controller/java/templates/CHIPReadCallbacks.zapt

+17-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{{> header}}
22
{{#if (chip_has_client_clusters)}}
3-
#include <zap-generated/CHIPClientCallbacks.h>
3+
#include "CHIPCallbackTypes.h"
44

55
#include <jni.h>
6+
#include <zap-generated/CHIPClientCallbacks.h>
67

78
{{#chip_server_global_responses}}
89
class CHIP{{chipCallback.name}}AttributeCallback : public chip::Callback::Callback<{{chipCallback.name}}AttributeCallback> {
@@ -14,7 +15,7 @@ public:
1415
static void maybeDestroy(CHIP{{chipCallback.name}}AttributeCallback * callback) {
1516
if (!callback->keepAlive) {
1617
callback->Cancel();
17-
delete callback;
18+
chip::Platform::Delete<CHIP{{chipCallback.name}}AttributeCallback>(callback);
1819
}
1920
}
2021

@@ -24,26 +25,34 @@ private:
2425
jobject javaCallbackRef;
2526
bool keepAlive;
2627
};
27-
2828
{{/chip_server_global_responses}}
2929

3030
{{#chip_client_clusters}}
3131
{{#chip_server_cluster_attributes}}
32-
{{#if isList}}
33-
class CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback : public chip::Callback::Callback<{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}ListAttributeCallback>
32+
{{#if_in_global_responses}}
33+
{{else}}
34+
class CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback : public chip::Callback::Callback<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}AttributeCallbackType>
3435
{
3536
public:
36-
CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback(jobject javaCallback);
37+
CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback(jobject javaCallback, bool keepAlive = false);
3738

3839
~CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback();
3940

40-
static void CallbackFn(void * context, {{zapTypeToDecodableClusterObjectType type ns=parent.name isArgument=true}} list);
41+
static void maybeDestroy(CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback * callback) {
42+
if (!callback->keepAlive) {
43+
callback->Cancel();
44+
chip::Platform::Delete<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback>(callback);
45+
}
46+
}
47+
48+
static void CallbackFn(void * context, {{zapTypeToDecodableClusterObjectType type ns=parent.name isArgument=true}} {{#if isList}}list{{else}}value{{/if}});
4149

4250
private:
4351
jobject javaCallbackRef;
52+
bool keepAlive;
4453
};
54+
{{/if_in_global_responses}}
4555

46-
{{/if}}
4756
{{/chip_server_cluster_attributes}}
4857
{{/chip_client_clusters}}
4958

0 commit comments

Comments
 (0)