From 193411940b05217d370a1fb3683ef8aa937c4486 Mon Sep 17 00:00:00 2001 From: wangzhen Date: Mon, 18 Aug 2025 21:42:06 +0800 Subject: [PATCH 1/2] Add static transfer record Signed-off-by: wangzhen Change-Id: Ie5693bd1603049b01aea79ccbad7dcdf3084abbb --- .../include/ets_caller_complex.h | 4 ++++ .../caller_complex/src/ets_caller_complex.cpp | 22 ++++++++++++++++++- .../ability_runtime/js_caller_complex.cpp | 12 +++++++++- .../ability_runtime/js_caller_complex.h | 1 + 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h b/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h index fa3ac766510..e5c52b2f1f3 100644 --- a/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h +++ b/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h @@ -43,12 +43,16 @@ public: static ani_object NativeTransferDynamic(ani_env *env, ani_object, ani_object input); static bool IsInstanceOf(ani_env *env, ani_object aniObj); static ani_object CreateDynamicCaller(ani_env *env, sptr remoteObj); + static void TransferFinalizeCallback(uintptr_t jsPtr); protected: void ReleaseCallInner(ani_env *env); private: ReleaseCallFunc releaseCallFunc_; std::shared_ptr callerCallback_; wptr remoteObj_; + + static std::mutex staticTransferRecordMutex_; + static std::unordered_map staticTransferRecord_; }; struct CallbackWrap { diff --git a/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp b/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp index b50bc60bbc2..9902880d430 100644 --- a/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp +++ b/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp @@ -39,6 +39,9 @@ void ReleaseNativeRemote(ani_env *env, ani_ref aniObj) namespace OHOS { namespace AbilityRuntime { +std::mutex EtsCallerComplex::staticTransferRecordMutex_; +std::unordered_map EtsCallerComplex::staticTransferRecord_; + EtsCallerComplex* EtsCallerComplex::GetComplexPtrFrom(ani_env *env, ani_object aniObj) { if (env == nullptr || aniObj == nullptr) { @@ -170,7 +173,9 @@ void EtsCallerComplex::SetCallerCallback(std::shared_ptr callbac ani_object EtsCallerComplex::NativeTransferStatic(ani_env *env, ani_object, ani_object input) { TAG_LOGI(AAFwkTag::UIABILITY, "transfer static caller"); + std::lock_guard lock(staticTransferRecordMutex_); ani_object output = nullptr; + uintptr_t srcPtr = 0; do { void *unwrapResult = nullptr; bool success = arkts_esvalue_unwrap(env, input, &unwrapResult); @@ -182,7 +187,12 @@ ani_object EtsCallerComplex::NativeTransferStatic(ani_env *env, ani_object, ani_ TAG_LOGE(AAFwkTag::UIABILITY, "null unwrapResult"); break; } - auto remoteObj = GetJsCallerRemoteObj(reinterpret_cast(unwrapResult)); + srcPtr = reinterpret_cast(unwrapResult); + auto recordItr = staticTransferRecord_.find(srcPtr); + if (recordItr != staticTransferRecord_.end()) { + return recordItr->second; + } + auto remoteObj = GetJsCallerRemoteObj(srcPtr); if (remoteObj == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null remoteObj"); } @@ -198,6 +208,8 @@ ani_object EtsCallerComplex::NativeTransferStatic(ani_env *env, ani_object, ani_ if (output == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "failed to create"); EtsErrorUtil::ThrowEtsTransferClassError(env); + } else { + staticTransferRecord_.emplace(srcPtr, output); } return output; } @@ -291,6 +303,12 @@ ani_object EtsCallerComplex::CreateDynamicCaller(ani_env *env, sptrGetVM(&aniVM) != ANI_OK) { @@ -379,6 +397,8 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) return status; } + SetFinalizeCallback(EtsCallerComplex::TransferFinalizeCallback); + *result = ANI_VERSION_1; return ANI_OK; } diff --git a/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp b/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp index ebe0844fdd2..e3ddd5e8e99 100644 --- a/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_caller_complex.cpp @@ -200,6 +200,9 @@ public: auto ret = ptr->ChangeCurrentState(state); TAG_LOGD(AAFwkTag::DEFAULT, "ChangeCurrentState ret:%{public}s", ret ? "true" : "false"); + if (finalizeCallback_) { + finalizeCallback_(reinterpret_cast(ptr)); + } return ret; } @@ -449,7 +452,8 @@ private: TAG_LOGD(AAFwkTag::DEFAULT, "end"); return CreateJsUndefined(env); } - +public: + static std::function finalizeCallback_; private: ReleaseCallFunc releaseCallFunc_; sptr callee_; @@ -470,6 +474,7 @@ private: std::set JsCallerComplex::jsCallerComplexManagerList; std::mutex JsCallerComplex::jsCallerComplexMutex; +std::function JsCallerComplex::finalizeCallback_; } // nameless napi_value CreateJsCallerComplex( @@ -527,5 +532,10 @@ sptr GetJsCallerRemoteObj(uintptr_t jsCallerComplex) } return callerPtr->GetRemoteObject(); } + +void SetFinalizeCallback(std::function finalizeCallback) +{ + JsCallerComplex::finalizeCallback_ = finalizeCallback; +} } // AbilityRuntime } // OHOS diff --git a/interfaces/kits/native/ability/native/ability_runtime/js_caller_complex.h b/interfaces/kits/native/ability/native/ability_runtime/js_caller_complex.h index 93d8e907b63..64b7c87b9f5 100644 --- a/interfaces/kits/native/ability/native/ability_runtime/js_caller_complex.h +++ b/interfaces/kits/native/ability/native/ability_runtime/js_caller_complex.h @@ -30,6 +30,7 @@ napi_value CreateJsCallerComplex( napi_value CreateJsCalleeRemoteObject(napi_env env, sptr callee); sptr GetJsCallerRemoteObj(uintptr_t jsCallerComplex); +void SetFinalizeCallback(std::function finalizeCallback); } // AbilityRuntime } // OHOS #endif // OHOS_ABILITY_RUNTIME_JS_CALLER_COMPLEX_H -- Gitee From 2cf304bf71d1a965ca57f508377d7d87735789b7 Mon Sep 17 00:00:00 2001 From: wangzhen Date: Tue, 19 Aug 2025 18:53:16 +0800 Subject: [PATCH 2/2] Use reference Signed-off-by: wangzhen Change-Id: Id4b0d384c81762aa4a1021408c47e50ad9184937 --- .../include/ets_caller_complex.h | 20 ++++++---- .../caller_complex/src/ets_caller_complex.cpp | 37 ++++++++++--------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h b/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h index e5c52b2f1f3..dc748e4bb32 100644 --- a/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h +++ b/frameworks/ets/ani/caller_complex/include/ets_caller_complex.h @@ -24,6 +24,16 @@ namespace OHOS { namespace AbilityRuntime { +struct EtsRefWrap { + EtsRefWrap(ani_env *env, ani_object srcObj); + EtsRefWrap(EtsRefWrap &) = delete; + void operator=(EtsRefWrap &) = delete; + ~EtsRefWrap(); + + ani_vm *aniVM = nullptr; + ani_ref objectRef = nullptr; +}; + class EtsCallerComplex { public: EtsCallerComplex(ReleaseCallFunc releaseCallFunc, std::shared_ptr callerCallBack, @@ -52,18 +62,14 @@ private: wptr remoteObj_; static std::mutex staticTransferRecordMutex_; - static std::unordered_map staticTransferRecord_; + static std::unordered_map> staticTransferRecords_; }; -struct CallbackWrap { +struct CallbackWrap: public EtsRefWrap { CallbackWrap(ani_env *env, ani_object callerObj, const std::string &callbackName); - CallbackWrap(CallbackWrap &) = delete; - void operator=(CallbackWrap &) = delete; - ~CallbackWrap(); + ~CallbackWrap() = default; void Invoke(const std::string &msg) const; private: - ani_vm *aniVM = nullptr; - ani_ref callbackRef = nullptr; std::string name; }; } // namespace AbilityRuntime diff --git a/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp b/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp index 9902880d430..16983755c59 100644 --- a/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp +++ b/frameworks/ets/ani/caller_complex/src/ets_caller_complex.cpp @@ -40,7 +40,7 @@ void ReleaseNativeRemote(ani_env *env, ani_ref aniObj) namespace OHOS { namespace AbilityRuntime { std::mutex EtsCallerComplex::staticTransferRecordMutex_; -std::unordered_map EtsCallerComplex::staticTransferRecord_; +std::unordered_map> EtsCallerComplex::staticTransferRecords_; EtsCallerComplex* EtsCallerComplex::GetComplexPtrFrom(ani_env *env, ani_object aniObj) { @@ -188,9 +188,9 @@ ani_object EtsCallerComplex::NativeTransferStatic(ani_env *env, ani_object, ani_ break; } srcPtr = reinterpret_cast(unwrapResult); - auto recordItr = staticTransferRecord_.find(srcPtr); - if (recordItr != staticTransferRecord_.end()) { - return recordItr->second; + auto recordItr = staticTransferRecords_.find(srcPtr); + if (recordItr != staticTransferRecords_.end()) { + return reinterpret_cast(recordItr->second->objectRef); } auto remoteObj = GetJsCallerRemoteObj(srcPtr); if (remoteObj == nullptr) { @@ -209,7 +209,7 @@ ani_object EtsCallerComplex::NativeTransferStatic(ani_env *env, ani_object, ani_ TAG_LOGE(AAFwkTag::UIABILITY, "failed to create"); EtsErrorUtil::ThrowEtsTransferClassError(env); } else { - staticTransferRecord_.emplace(srcPtr, output); + staticTransferRecords_.emplace(srcPtr, std::make_shared(env, output)); } return output; } @@ -306,10 +306,10 @@ ani_object EtsCallerComplex::CreateDynamicCaller(ani_env *env, sptrGetVM(&aniVM) != ANI_OK) { TAG_LOGE(AAFwkTag::UIABILITY, "get aniVM failed"); @@ -317,16 +317,14 @@ CallbackWrap::CallbackWrap(ani_env *env, ani_object callerObj, const std::string } ani_status status = ANI_ERROR; - if ((status = env->GlobalReference_Create(callerObj, &callbackRef)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "callbackRef: %{public}d", status); - return; + if ((status = env->GlobalReference_Create(srcObj, &objectRef)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "create ref: %{public}d", status); } - name = callbackName; } -CallbackWrap::~CallbackWrap() +EtsRefWrap::~EtsRefWrap() { - if (callbackRef == nullptr) { + if (objectRef == nullptr) { return; } ani_status status = ANI_ERROR; @@ -335,14 +333,17 @@ CallbackWrap::~CallbackWrap() TAG_LOGE(AAFwkTag::UIABILITY, "GetEnv failed, status : %{public}d", status); return; } - aniEnv->GlobalReference_Delete(callbackRef); - callbackRef = nullptr; + aniEnv->GlobalReference_Delete(objectRef); + objectRef = nullptr; } +CallbackWrap::CallbackWrap(ani_env *env, ani_object callerObj, const std::string &callbackName) + : EtsRefWrap(env, callerObj), name(callbackName) {} + void CallbackWrap::Invoke(const std::string &msg) const { - if (callbackRef == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "callbackRef null"); + if (objectRef == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "objectRef null"); return; } ani_string aniMsg = nullptr; @@ -356,7 +357,7 @@ void CallbackWrap::Invoke(const std::string &msg) const TAG_LOGE(AAFwkTag::UIABILITY, "String_NewUTF8 failed %{public}d", status); return; } - status = aniEnv->Object_CallMethodByName_Void(reinterpret_cast(callbackRef), name.c_str(), + status = aniEnv->Object_CallMethodByName_Void(reinterpret_cast(objectRef), name.c_str(), "Lstd/core/String;:V", aniMsg); if (status != ANI_OK) { TAG_LOGE(AAFwkTag::UIABILITY, "%{public}s failed %{public}d", name.c_str(), status); -- Gitee