From 223408a7761d841507808e3a7fe3bce4e7a63380 Mon Sep 17 00:00:00 2001 From: zhangzezhong Date: Sat, 28 Jun 2025 19:17:09 +0800 Subject: [PATCH] fixed setReceiveDataCallback Signed-off-by: zhangzezhong --- .../ets_ui_extension_content_session.h | 10 +- .../src/ets_ui_extension_content_session.cpp | 115 ++++++++++++++++-- 2 files changed, 113 insertions(+), 12 deletions(-) diff --git a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h index 439179de83..5c82b9eeaa 100644 --- a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h +++ b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h @@ -78,7 +78,7 @@ public: static void NativeSetWindowBackgroundColor(ani_env* env, ani_object obj, ani_string color); static int NativeTerminateSelfWithResult(ani_env* env, ani_object obj, ani_object abilityResult, ani_object callback); - static ani_object NativeSetReceiveDataCallback(ani_env* env, ani_object obj); + static void NativeSetReceiveDataCallback(ani_env* env, ani_object clsObj, ani_object funcObj); static ani_object NativeGetUIExtensionHostWindowProxy(ani_env* env, ani_object obj); void SendData(ani_env* env, ani_object object, ani_object data); @@ -87,14 +87,16 @@ public: int32_t TerminateSelfWithResult(); void SetWindowBackgroundColor(ani_env* env, ani_string color); ani_object GetUIExtensionHostWindowProxy(ani_env* env, ani_object object); - ani_object SetReceiveDataCallback(ani_env* env, ani_object object); + void SetReceiveDataCallback(ani_env* env, ani_object functionObj); + static void CallReceiveDataCallback(ani_vm* vm, ani_ref callbackRef, const AAFwk::WantParams& wantParams); private: + void SetReceiveDataCallbackRegister(ani_env* env, ani_object functionObj); sptr sessionInfo_; sptr uiWindow_; std::weak_ptr context_; - std::shared_ptr receiveDataCallback_; - bool isRegistered = false; + ani_ref receiveDataCallback_ = nullptr; + bool isRegistered_ = false; std::shared_ptr receiveDataForResultCallback_; bool isSyncRegistered = false; std::shared_ptr listener_; diff --git a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp index f71d1ee917..7f5c312215 100644 --- a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp +++ b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp @@ -75,14 +75,12 @@ EtsUIExtensionContentSession* EtsUIExtensionContentSession::GetEtsContentSession return etsContentSession; } -ani_object EtsUIExtensionContentSession::NativeSetReceiveDataCallback(ani_env* env, ani_object obj) +void EtsUIExtensionContentSession::NativeSetReceiveDataCallback(ani_env* env, ani_object clsObj, ani_object funcObj) { - auto etsContentSession = EtsUIExtensionContentSession::GetEtsContentSession(env, obj); - ani_object object = nullptr; + auto etsContentSession = GetEtsContentSession(env, clsObj); if (etsContentSession != nullptr) { - object = etsContentSession->SetReceiveDataCallback(env, obj); + etsContentSession->SetReceiveDataCallback(env, funcObj); } - return object; } void EtsUIExtensionContentSession::NativeSendData(ani_env* env, ani_object obj, ani_object data) @@ -328,10 +326,111 @@ ani_object EtsUIExtensionContentSession::GetUIExtensionHostWindowProxy(ani_env* return reinterpret_cast(resultRef); } -ani_object EtsUIExtensionContentSession::SetReceiveDataCallback(ani_env* env, ani_object object) +void EtsUIExtensionContentSession::SetReceiveDataCallback(ani_env* env, ani_object functionObj) { - TAG_LOGD(AAFwkTag::UI_EXT, "called"); - return nullptr; + TAG_LOGD(AAFwkTag::UI_EXT, "SetReceiveDataCallback call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "env null"); + return; + } + if (!isRegistered_) { + SetReceiveDataCallbackRegister(env, functionObj); + } else { + if (receiveDataCallback_ == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null receiveDataCallback_"); + EtsErrorUtil::ThrowErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + ani_status status = ANI_OK; + if ((status = env->GlobalReference_Delete(receiveDataCallback_)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "GlobalReference_Delete failed status = %{public}d", status); + EtsErrorUtil::ThrowErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + receiveDataCallback_ = nullptr; + if ((status = env->GlobalReference_Create(functionObj, &receiveDataCallback_)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "GlobalReference_Create failed status:%{public}d", status); + EtsErrorUtil::ThrowErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + } + TAG_LOGD(AAFwkTag::UI_EXT, "SetReceiveDataCallback end"); +} + +void EtsUIExtensionContentSession::SetReceiveDataCallbackRegister(ani_env* env, ani_object functionObj) +{ + if (uiWindow_ == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "uiWindow_ is nullptr"); + EtsErrorUtil::ThrowErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + ani_status status = ANI_OK; + if (receiveDataCallback_ == nullptr) { + if ((status = env->GlobalReference_Create(functionObj, &receiveDataCallback_)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "GlobalReference_Create receiveDataCallback_ failed status:%{public}d", status); + EtsErrorUtil::ThrowErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + } + ani_vm *aniVM = nullptr; + if (env->GetVM(&aniVM) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "get aniVM failed"); + EtsErrorUtil::ThrowInvalidParamError(env, "Get aniVm failed."); + return; + } + auto callbackRef = receiveDataCallback_; + auto handler = std::make_shared(AppExecFwk::EventRunner::GetMainEventRunner()); + uiWindow_->RegisterTransferComponentDataListener([aniVM, handler, callbackRef] ( + const AAFwk::WantParams& wantParams) { + if (handler) { + handler->PostTask([aniVM, callbackRef, wantParams]() { + EtsUIExtensionContentSession::CallReceiveDataCallback(aniVM, callbackRef, wantParams); + }, "EtsUIExtensionContentSession:OnSetReceiveDataCallback"); + } + }); + isRegistered_ = true; +} + +void EtsUIExtensionContentSession::CallReceiveDataCallback(ani_vm* vm, ani_ref callbackRef, + const AAFwk::WantParams& wantParams) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "CallReceiveDataCallback call"); + if (vm == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "vm is nullptr"); + return; + } + ani_env *env = nullptr; + ani_status status = ANI_OK; + if ((status = vm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "GetEnv failed status: %{public}d", status); + return; + } + if (callbackRef == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "callbackPtr is nullptr"); + return; + } + ani_object callbackObj = static_cast(callbackRef); + ani_fn_object callbackFunc = reinterpret_cast(callbackObj); + if (callbackFunc == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "callbackFunc is nullptr"); + return; + } + ani_ref wantObj = AppExecFwk::WrapWantParams(env, wantParams); + if (wantObj == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "wantObj is nullptr"); + return; + } + ani_ref argv[] = {wantObj}; + ani_ref result; + if ((status = env->FunctionalObject_Call(callbackFunc, 1, argv, &result)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "FunctionalObjectCall failed status %{public}d", status); + } + TAG_LOGD(AAFwkTag::UI_EXT, "CallReceiveDataCallback end"); } } // namespace AbilityRuntime } // namespace OHOS \ No newline at end of file