!10053 【fix】增加js_ui_extension_base OnStop异步实现

Merge pull request !10053 from chenzexin/0820
This commit is contained in:
openharmony_ci
2024-08-23 03:47:13 +00:00
committed by Gitee
3 changed files with 148 additions and 5 deletions
@@ -359,6 +359,7 @@ bool JsUIExtension::CheckPromise(napi_value result)
return true;
}
namespace {
napi_value PromiseCallback(napi_env env, napi_callback_info info)
{
void *data = nullptr;
@@ -373,6 +374,7 @@ napi_value PromiseCallback(napi_env env, napi_callback_info info)
data = nullptr;
return nullptr;
}
}
bool JsUIExtension::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo)
{
@@ -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"
@@ -244,6 +247,131 @@ void JsUIExtensionBase::OnStop()
#ifdef SUPPORT_GRAPHICS
UnregisterDisplayInfoChangedListener();
#endif // SUPPORT_GRAPHICS
OnStopCallBack();
TAG_LOGD(AAFwkTag::UI_EXT, "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, "begin");
HandleScope handleScope(jsRuntime_);
napi_value result = CallObjectMethod("onDestroy", nullptr, 0, true);
if (!CheckPromise(result)) {
OnStopCallBack();
isAsyncCallback = false;
return;
}
auto asyncCallback = [extensionWeakPtr = weak_from_this()]() {
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, "end");
}
void JsUIExtensionBase::OnStopCallBack()
{
if (context_ == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT, "Failed to get context");
return;
}
auto ret = ConnectionManager::GetInstance().DisconnectCaller(context_->GetToken());
if (ret) {
ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
TAG_LOGD(AAFwkTag::UI_EXT, "service connection 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 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 isn't 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<AppExecFwk::AbilityTransactionCallbackInfo<> *>(data);
if (callbackInfo == nullptr) {
TAG_LOGD(AAFwkTag::UI_EXT, "Invalid input");
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_status createStatus = napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback,
callbackInfo, &promiseCallback);
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(AAFwkTag::UI_EXT, "Failed to call promiseCallback, %{public}d", callStatus);
return false;
}
TAG_LOGD(AAFwkTag::UI_EXT, "exit");
return true;
}
void JsUIExtensionBase::OnCommandWindow(
@@ -611,7 +739,7 @@ void JsUIExtensionBase::DestroyWindow(const sptr<AAFwk::SessionInfo> &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_) {
@@ -624,13 +752,18 @@ 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)) {
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);
@@ -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"
@@ -101,6 +101,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.
@@ -165,7 +170,10 @@ public:
void ConfigurationUpdated();
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<AAFwk::SessionInfo> &sessionInfo);
void BackgroundWindow(const sptr<AAFwk::SessionInfo> &sessionInfo);
void DestroyWindow(const sptr<AAFwk::SessionInfo> &sessionInfo);
@@ -183,7 +191,7 @@ protected:
protected:
JsRuntime &jsRuntime_;
std::shared_ptr<NativeReference> shellContextRef_;
std::unique_ptr<NativeReference> jsObj_;
std::shared_ptr<NativeReference> jsObj_;
std::shared_ptr<UIExtensionContext> context_;
std::map<uint64_t, sptr<Rosen::Window>> uiWindowMap_;
std::set<uint64_t> foregroundWindows_;