| {{> 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}} |