| {{> header}} |
| #include <jni/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 { |
| |
| {{#zcl_clusters}} |
| {{#zcl_commands_source_server}} |
| 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", "({{#zcl_command_arguments}}{{asJniSignature type null parent.parent.name true}}{{/zcl_command_arguments}})V", &javaMethod); |
| VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err))); |
| |
| {{#zcl_command_arguments}} |
| {{>decode_value source=(concat "dataResponse." (asLowerCamelCase name)) target=(asSymbol label) cluster=parent.parent.name depth=0}} |
| {{/zcl_command_arguments}} |
| |
| env->CallVoidMethod(javaCallbackRef, javaMethod{{#zcl_command_arguments}}, {{asSymbol label}}{{/zcl_command_arguments}}); |
| } |
| {{/zcl_commands_source_server}} |
| {{/zcl_clusters}} |
| } // namespace chip |