From ca00cc1396f7e2b2ac202f841a0b419944a3ef1c Mon Sep 17 00:00:00 2001 From: chenzexin Date: Thu, 22 Aug 2024 17:08:47 +0800 Subject: [PATCH 1/5] update onstop callback Signed-off-by: chenzexin --- .../ui_extension_ability/js_ui_extension.cpp | 2 + .../js_ui_extension_base.cpp | 127 +++++++++++++++++- .../js_ui_extension_base.h | 14 +- 3 files changed, 139 insertions(+), 4 deletions(-) diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp index ffb171b716..a92ca2b831 100755 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp @@ -353,6 +353,7 @@ bool JsUIExtension::CheckPromise(napi_value result) return true; } +namespace { napi_value PromiseCallback(napi_env env, napi_callback_info info) { void *data = nullptr; @@ -367,6 +368,7 @@ napi_value PromiseCallback(napi_env env, napi_callback_info info) data = nullptr; return nullptr; } +} bool JsUIExtension::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo) { diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp index f577f4b6e5..73cb96c79b 100644 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp @@ -21,7 +21,10 @@ #include "ability_info.h" #include "ability_manager_client.h" #include "configuration_utils.h" +#include "connection_manager.h" +#include "context.h" #include "hilog_tag_wrapper.h" +#include "hilog_wrapper.h" #include "hitrace_meter.h" #include "insight_intent_executor_info.h" #include "insight_intent_executor_mgr.h" @@ -227,6 +230,123 @@ void JsUIExtensionBase::OnStop() TAG_LOGD(AAFwkTag::UI_EXT, "called"); HandleScope handleScope(jsRuntime_); CallObjectMethod("onDestroy"); + OnStopCallBack(); + TAG_LOGD(AAFwkTag::UI_EXT, "JsUIExtension OnStop end."); +} + +void JsUIExtensionBase::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback) +{ + if (callbackInfo == nullptr) { + isAsyncCallback = false; + OnStop(); + return; + } + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UI_EXT, "OnStop begin."); + HandleScope handleScope(jsRuntime_); + napi_value result = CallObjectMethod("onDestroy", nullptr, 0, true); + if (!CheckPromise(result)) { + OnStopCallBack(); + isAsyncCallback = false; + return; + } + + std::weak_ptr weakPtr = shared_from_this(); + auto asyncCallback = [extensionWeakPtr = weakPtr]() { + auto jsUIExtensionBase = extensionWeakPtr.lock(); + if (jsUIExtensionBase == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "extension is nullptr."); + return; + } + jsUIExtensionBase->OnStopCallBack(); + }; + callbackInfo->Push(asyncCallback); + isAsyncCallback = CallPromise(result, callbackInfo); + if (!isAsyncCallback) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to call promise."); + OnStopCallBack(); + } + TAG_LOGD(AAFwkTag::UI_EXT, "OnStop end."); +} + +void JsUIExtensionBase::OnStopCallBack() +{ + if (context_ == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get context"); + return; + } + bool ret = ConnectionManager::GetInstance().DisconnectCaller(context_->GetToken()); + if (ret) { + ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid()); + TAG_LOGD(AAFwkTag::UI_EXT, "The service connection is not disconnected."); + } + + auto applicationContext = Context::GetApplicationContext(); + if (applicationContext != nullptr) { + applicationContext->DispatchOnAbilityDestroy(jsObj_); + } +} + +bool JsUIExtensionBase::CheckPromise(napi_value result) +{ + if (result == nullptr) { + TAG_LOGD(AAFwkTag::UI_EXT, "result is null, no need to call promise."); + return false; + } + napi_env env = jsRuntime_.GetNapiEnv(); + bool isPromise = false; + napi_is_promise(env, result, &isPromise); + if (!isPromise) { + TAG_LOGD(AAFwkTag::UI_EXT, "result is not promise, no need to call promise."); + return false; + } + return true; +} + +namespace { +napi_value PromiseCallback(napi_env env, napi_callback_info info) +{ + void *data = nullptr; + NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data), nullptr); + auto *callbackInfo = static_cast *>(data); + if (callbackInfo == nullptr) { + TAG_LOGD(AAFwkTag::UI_EXT, "Invalid input info."); + return nullptr; + } + callbackInfo->Call(); + AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo); + data = nullptr; + return nullptr; +} +} + +bool JsUIExtensionBase::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo) +{ + auto env = jsRuntime_.GetNapiEnv(); + if (!CheckTypeForNapiValue(env, result, napi_object)) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to convert native value to NativeObject."); + return false; + } + napi_value then = nullptr; + napi_get_named_property(env, result, "then", &then); + if (then == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get property: then."); + return false; + } + bool isCallable = false; + napi_is_callable(env, then, &isCallable); + if (!isCallable) { + TAG_LOGE(AAFwkTag::UI_EXT, "property then is not callable."); + return false; + } + HandleScope handleScope(jsRuntime_); + napi_value promiseCallback = nullptr; + napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback, + callbackInfo, &promiseCallback); + napi_value argv[1] = { promiseCallback }; + napi_call_function(env, result, then, 1, argv, nullptr); + TAG_LOGD(AAFwkTag::UI_EXT, "exit"); + return true; } void JsUIExtensionBase::OnCommandWindow( @@ -594,7 +714,7 @@ void JsUIExtensionBase::DestroyWindow(const sptr &sessionInf } } -napi_value JsUIExtensionBase::CallObjectMethod(const char *name, napi_value const *argv, size_t argc) +napi_value JsUIExtensionBase::CallObjectMethod(const char *name, napi_value const *argv, size_t argc, bool withResult) { TAG_LOGD(AAFwkTag::UI_EXT, "CallObjectMethod(%{public}s), begin", name); if (!jsObj_) { @@ -614,6 +734,11 @@ napi_value JsUIExtensionBase::CallObjectMethod(const char *name, napi_value cons TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get '%{public}s' object", name); return nullptr; } + if (withResult) { + napi_value result = nullptr; + napi_call_function(env, obj, method, argc, argv, &result); + return handleEscape.Escape(result); + } TAG_LOGD(AAFwkTag::UI_EXT, "CallFunction(%{public}s), success", name); napi_value result = nullptr; napi_call_function(env, obj, method, argc, argv, &result); diff --git a/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_base.h b/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_base.h index 053a52a5f3..a2ea4e4729 100644 --- a/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_base.h +++ b/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_base.h @@ -24,7 +24,7 @@ #include "native_engine/native_engine.h" #include "ohos_application.h" #include "session_info.h" -#include "ui_extension_base.h" +#include "ui_extension_base_impl.h" #include "ui_extension_context.h" #include "ui_extension_window_command.h" #include "want.h" @@ -95,6 +95,11 @@ public: * You can override this function to implement your own processing logic. */ void OnStop() override; + virtual void OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback); + /** + * @brief The callback of OnStop. + */ + virtual void OnStopCallBack(); /** * @brief Called when the system configuration is updated. @@ -153,7 +158,10 @@ public: void BindContext() override; protected: - napi_value CallObjectMethod(const char *name, napi_value const *argv = nullptr, size_t argc = 0); + napi_value CallObjectMethod(const char *name, napi_value const *argv = nullptr, size_t argc = 0, + bool withResult = false); + bool CheckPromise(napi_value result); + bool CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo); void ForegroundWindow(const AAFwk::Want &want, const sptr &sessionInfo); void BackgroundWindow(const sptr &sessionInfo); void DestroyWindow(const sptr &sessionInfo); @@ -171,7 +179,7 @@ protected: protected: JsRuntime &jsRuntime_; std::shared_ptr shellContextRef_; - std::unique_ptr jsObj_; + std::shared_ptr jsObj_; std::shared_ptr context_; std::map> uiWindowMap_; std::set foregroundWindows_; From cc2afde9e1cdcfaf2afed05d824db13bc7976c11 Mon Sep 17 00:00:00 2001 From: chenzexin Date: Thu, 22 Aug 2024 17:48:18 +0800 Subject: [PATCH 2/5] debug Signed-off-by: chenzexin --- .../native/ui_extension_ability/js_ui_extension_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp index 73cb96c79b..d5f024de82 100644 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp @@ -727,7 +727,7 @@ napi_value JsUIExtensionBase::CallObjectMethod(const char *name, napi_value cons TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get object"); return nullptr; } - + HandleEscape handleEscape(jsRuntime_); napi_value method = nullptr; napi_get_named_property(env, obj, name, &method); if (!CheckTypeForNapiValue(env, method, napi_function)) { From 292314160b90eb23950a9f1a3f01b3fdf5729747 Mon Sep 17 00:00:00 2001 From: chenzexin Date: Thu, 22 Aug 2024 23:00:53 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E2=80=9Cfix=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenzexin --- .../js_ui_extension_base.cpp | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp index d5f024de82..b280af73fb 100644 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp @@ -231,7 +231,7 @@ void JsUIExtensionBase::OnStop() HandleScope handleScope(jsRuntime_); CallObjectMethod("onDestroy"); OnStopCallBack(); - TAG_LOGD(AAFwkTag::UI_EXT, "JsUIExtension OnStop end."); + TAG_LOGD(AAFwkTag::UI_EXT, "end"); } void JsUIExtensionBase::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback) @@ -242,7 +242,7 @@ void JsUIExtensionBase::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *cal return; } HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - TAG_LOGD(AAFwkTag::UI_EXT, "OnStop begin."); + TAG_LOGD(AAFwkTag::UI_EXT, "begin"); HandleScope handleScope(jsRuntime_); napi_value result = CallObjectMethod("onDestroy", nullptr, 0, true); if (!CheckPromise(result)) { @@ -251,11 +251,10 @@ void JsUIExtensionBase::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *cal return; } - std::weak_ptr weakPtr = shared_from_this(); - auto asyncCallback = [extensionWeakPtr = weakPtr]() { + auto asyncCallback = [extensionWeakPtr = weak_from_this()]() { auto jsUIExtensionBase = extensionWeakPtr.lock(); if (jsUIExtensionBase == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "extension is nullptr."); + TAG_LOGE(AAFwkTag::UI_EXT, "extension is nullptr"); return; } jsUIExtensionBase->OnStopCallBack(); @@ -263,10 +262,10 @@ void JsUIExtensionBase::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *cal callbackInfo->Push(asyncCallback); isAsyncCallback = CallPromise(result, callbackInfo); if (!isAsyncCallback) { - TAG_LOGE(AAFwkTag::UI_EXT, "Failed to call promise."); + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to call promise"); OnStopCallBack(); } - TAG_LOGD(AAFwkTag::UI_EXT, "OnStop end."); + TAG_LOGD(AAFwkTag::UI_EXT, "end"); } void JsUIExtensionBase::OnStopCallBack() @@ -275,10 +274,10 @@ void JsUIExtensionBase::OnStopCallBack() TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get context"); return; } - bool ret = ConnectionManager::GetInstance().DisconnectCaller(context_->GetToken()); + auto ret = ConnectionManager::GetInstance().DisconnectCaller(context_->GetToken()); if (ret) { ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid()); - TAG_LOGD(AAFwkTag::UI_EXT, "The service connection is not disconnected."); + TAG_LOGD(AAFwkTag::UI_EXT, "service connection not disconnected"); } auto applicationContext = Context::GetApplicationContext(); @@ -290,14 +289,14 @@ void JsUIExtensionBase::OnStopCallBack() bool JsUIExtensionBase::CheckPromise(napi_value result) { if (result == nullptr) { - TAG_LOGD(AAFwkTag::UI_EXT, "result is null, no need to call promise."); + TAG_LOGD(AAFwkTag::UI_EXT, "result is nullptr"); return false; } napi_env env = jsRuntime_.GetNapiEnv(); bool isPromise = false; napi_is_promise(env, result, &isPromise); if (!isPromise) { - TAG_LOGD(AAFwkTag::UI_EXT, "result is not promise, no need to call promise."); + TAG_LOGD(AAFwkTag::UI_EXT, "result isn't promise"); return false; } return true; @@ -310,7 +309,7 @@ napi_value PromiseCallback(napi_env env, napi_callback_info info) NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data), nullptr); auto *callbackInfo = static_cast *>(data); if (callbackInfo == nullptr) { - TAG_LOGD(AAFwkTag::UI_EXT, "Invalid input info."); + TAG_LOGD(AAFwkTag::UI_EXT, "Invalid input"); return nullptr; } callbackInfo->Call(); @@ -324,27 +323,35 @@ bool JsUIExtensionBase::CallPromise(napi_value result, AppExecFwk::AbilityTransa { auto env = jsRuntime_.GetNapiEnv(); if (!CheckTypeForNapiValue(env, result, napi_object)) { - TAG_LOGE(AAFwkTag::UI_EXT, "Failed to convert native value to NativeObject."); + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to convert native value to NativeObject"); return false; } napi_value then = nullptr; napi_get_named_property(env, result, "then", &then); if (then == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get property: then."); + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get property: then"); return false; } bool isCallable = false; napi_is_callable(env, then, &isCallable); if (!isCallable) { - TAG_LOGE(AAFwkTag::UI_EXT, "property then is not callable."); + TAG_LOGE(AAFwkTag::UI_EXT, "property then is not callable"); return false; } HandleScope handleScope(jsRuntime_); napi_value promiseCallback = nullptr; - napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback, + napi_status createStatus = napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback, callbackInfo, &promiseCallback); + if(createStatus != napi_ok) { + TAG_LOGE("Failed to create promiseCallback, %{public}d", createStatus); + return false; + } napi_value argv[1] = { promiseCallback }; - napi_call_function(env, result, then, 1, argv, nullptr); + napi_status callStatus = napi_call_function(env, result, then, 1, argv, nullptr); + if(callStatus != napi_ok) { + TAG_LOGE("Failed to call promiseCallback, %{public}d", callStatus); + return false; + } TAG_LOGD(AAFwkTag::UI_EXT, "exit"); return true; } From 13829477ce55a19b633891cd6df94860408d6674 Mon Sep 17 00:00:00 2001 From: chenzexin Date: Thu, 22 Aug 2024 23:07:14 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E2=80=9Cfix=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenzexin --- .../native/ui_extension_ability/js_ui_extension_base.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp index b280af73fb..e0bbbacead 100644 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp @@ -230,6 +230,10 @@ void JsUIExtensionBase::OnStop() TAG_LOGD(AAFwkTag::UI_EXT, "called"); HandleScope handleScope(jsRuntime_); CallObjectMethod("onDestroy"); +#ifdef SUPPORT_GRAPHICS + UnregisterDisplayInfoChangedListener(); +#endif // SUPPORT_GRAPHICS + OnStopCallBack(); TAG_LOGD(AAFwkTag::UI_EXT, "end"); } From 7bcd27dc838430994db4797cdf11dc40880d2fab Mon Sep 17 00:00:00 2001 From: chenzexin Date: Fri, 23 Aug 2024 02:12:13 +0000 Subject: [PATCH 5/5] fix log Signed-off-by: chenzexin --- .../native/ui_extension_ability/js_ui_extension_base.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp index 14b9affd3e..d67caba6dd 100644 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_base.cpp @@ -360,14 +360,14 @@ bool JsUIExtensionBase::CallPromise(napi_value result, AppExecFwk::AbilityTransa napi_value promiseCallback = nullptr; napi_status createStatus = napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback, callbackInfo, &promiseCallback); - if(createStatus != napi_ok) { - TAG_LOGE("Failed to create promiseCallback, %{public}d", createStatus); + if (createStatus != napi_ok) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to create promiseCallback, %{public}d", createStatus); return false; } napi_value argv[1] = { promiseCallback }; napi_status callStatus = napi_call_function(env, result, then, 1, argv, nullptr); - if(callStatus != napi_ok) { - TAG_LOGE("Failed to call promiseCallback, %{public}d", callStatus); + if (callStatus != napi_ok) { + TAG_LOGE(AAFwkTag::UI_EXT, "Failed to call promiseCallback, %{public}d", callStatus); return false; } TAG_LOGD(AAFwkTag::UI_EXT, "exit");