blob: 4f8624fb44fb77a169b54732e7f191a3b9780ee3 [file] [log] [blame]
{{> header}}
#include <jni/CHIPReadCallbacks.h>
#include <controller/java/zap-generated/CHIPClientCallbacks.h>
#include <jni.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <platform/PlatformManager.h>
{{#zcl_clusters}}
{{#zcl_attributes_server removeKeys='isOptional'}}
{{! TODO: Add support for struct-typed attributes }}
{{#if_unsupported_attribute_callback type isArray ../id}}
{{else}}
{{#if_basic_attribute type ../id}}
{{else}}
CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback(jobject javaCallback, bool keepAlive) :
chip::Callback::Callback<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}AttributeCallbackType>(CallbackFn, this), keepAlive(keepAlive)
{
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
if (env == nullptr) {
ChipLogError(Zcl, "Could not create global reference for Java callback");
return;
}
javaCallbackRef = env->NewGlobalRef(javaCallback);
if (javaCallbackRef == nullptr) {
ChipLogError(Zcl, "Could not create global reference for Java callback");
}
}
CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::~CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback() {
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
if (env == nullptr)
{
ChipLogError(Zcl, "Could not delete global reference for Java callback");
return;
}
env->DeleteGlobalRef(javaCallbackRef);
}
{{/if_basic_attribute}}
{{#if isArray}}
void CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::CallbackFn(void * context, {{zapTypeToDecodableClusterObjectType type ns=parent.name isArgument=true}} list)
{
chip::DeviceLayer::StackUnlock unlock;
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
jobject javaCallbackRef;
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
std::unique_ptr<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback, decltype(&maybeDestroy)> cppCallback(reinterpret_cast<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback *>(context), maybeDestroy);
// It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
javaCallbackRef = cppCallback->javaCallbackRef;
VerifyOrReturn(javaCallbackRef != nullptr, ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));
jmethodID javaMethod;
err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));
{{>decode_value source="list" target="arrayListObj" cluster=parent.name depth=0}}
env->ExceptionClear();
env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj);
}
{{else}}
{{#if_basic_attribute type ../id}}
{{else}}
void CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback::CallbackFn(void * context, {{zapTypeToDecodableClusterObjectType type ns=parent.name isArgument=true}} value)
{
chip::DeviceLayer::StackUnlock unlock;
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
jobject javaCallbackRef;
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));
std::unique_ptr<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback, decltype(&maybeDestroy)> cppCallback(reinterpret_cast<CHIP{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}AttributeCallback *>(context), maybeDestroy);
// It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback.
javaCallbackRef = cppCallback->javaCallbackRef;
VerifyOrReturn(javaCallbackRef != nullptr, ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null"));
jmethodID javaMethod;
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}}{{asJniSignatureBasic type true}}{{/if}})V", &javaMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method"));
{{>decode_value source="value" target="javaValue" cluster=parent.name depth=0}}
env->CallVoidMethod(javaCallbackRef, javaMethod, javaValue);
}
{{/if_basic_attribute}}
{{/if}}
{{/if_unsupported_attribute_callback}}
{{/zcl_attributes_server}}
{{/zcl_clusters}}