blob: e1f445ec1124429271f7115bf6413d9a05a6e15e [file] [log] [blame]
{{> header}}
{{#if (chip_has_client_clusters)}}
#include "CHIPCallbackTypes.h"
#include "CHIPInvokeCallbacks.h"
#include <app-common/zap-generated/cluster-objects.h>
#include <jni.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/CHIPJNIError.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <platform/PlatformManager.h>
{{! TODO(#8773): Clean up callbacks. }}
namespace chip {
{{#chip_client_clusters}}
{{#chip_cluster_responses}}
CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback::CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback(jobject javaCallback): Callback::Callback<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}CallbackType>(CallbackFn, this)
{
JNIEnv * env = 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}}Cluster{{asUpperCamelCase name}}Callback::~CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
if (env == nullptr) {
ChipLogError(Zcl, "Could not delete global reference for Java callback");
return;
}
env->DeleteGlobalRef(javaCallbackRef);
};
void CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback::CallbackFn(void * context, const chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::DecodableType & dataResponse)
{
chip::DeviceLayer::StackUnlock unlock;
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
jobject javaCallbackRef;
jmethodID javaMethod;
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Error invoking Java callback: no JNIEnv"));
std::unique_ptr<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback, void (*)(CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback *)> cppCallback(
reinterpret_cast<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback *>(context),
chip::Platform::Delete<CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Callback>
);
VerifyOrReturn(cppCallback != nullptr, ChipLogError(Zcl, "Error invoking Java callback: failed to cast native callback"));
javaCallbackRef = cppCallback->javaCallbackRef;
// Java callback is allowed to be null, exit early if this is the case.
VerifyOrReturn(javaCallbackRef != nullptr);
err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "({{#chip_cluster_response_arguments}}{{asJniSignature type null parent.parent.name true}}{{/chip_cluster_response_arguments}})V", &javaMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err)));
{{#chip_cluster_response_arguments}}
{{>decode_value source=(concat "dataResponse." (asLowerCamelCase name)) target=(asSymbol label) cluster=(asUpperCamelCase parent.parent.name) depth=0}}
{{/chip_cluster_response_arguments}}
env->CallVoidMethod(javaCallbackRef, javaMethod{{#chip_cluster_response_arguments}}, {{asSymbol label}}{{/chip_cluster_response_arguments}});
}
{{/chip_cluster_responses}}
{{/chip_client_clusters}}
} // namespace chip
{{/if}}