From ff65bf4e04182c2df2a1d8ec61fed2def0cd1d2b Mon Sep 17 00:00:00 2001 From: zhangzezhong Date: Wed, 25 Jun 2025 23:30:47 +0800 Subject: [PATCH] isolate uiability Signed-off-by: zhangzezhong --- frameworks/ets/ani/BUILD.gn | 1 + frameworks/ets/ani/ui_ability_ffi/BUILD.gn | 105 +++ .../include}/ets_ability_context.h | 0 .../ui_ability_ffi/include/ets_ability_ffi.h | 143 ++++ .../src}/ets_ability_context.cpp | 3 +- .../ui_ability_ffi/src/ets_ability_ffi.cpp | 612 ++++++++++++++++++ frameworks/native/ability/BUILD.gn | 3 - frameworks/native/ability/native/BUILD.gn | 9 +- .../ability_runtime/ets_ability_object.cpp | 207 ++++++ .../native/ability_runtime/ets_ui_ability.cpp | 360 ++--------- .../ability_runtime/ets_ability_object.h | 71 ++ .../native/ability_runtime/ets_ui_ability.h | 10 +- 12 files changed, 1199 insertions(+), 325 deletions(-) create mode 100644 frameworks/ets/ani/ui_ability_ffi/BUILD.gn rename {interfaces/kits/native/ability/native/ability_runtime => frameworks/ets/ani/ui_ability_ffi/include}/ets_ability_context.h (100%) create mode 100644 frameworks/ets/ani/ui_ability_ffi/include/ets_ability_ffi.h rename frameworks/{native/ability/native/ability_runtime => ets/ani/ui_ability_ffi/src}/ets_ability_context.cpp (99%) create mode 100644 frameworks/ets/ani/ui_ability_ffi/src/ets_ability_ffi.cpp create mode 100644 frameworks/native/ability/native/ability_runtime/ets_ability_object.cpp create mode 100644 interfaces/kits/native/ability/native/ability_runtime/ets_ability_object.h diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index 2c324d61cda..ea480d8ac79 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -19,6 +19,7 @@ group("ani_packages") { "${ability_runtime_path}/frameworks/ets/ani/ability_delegator:ability_delegator_registry_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", "${ability_runtime_path}/frameworks/ets/ani/native_constructor:context_ani", + "${ability_runtime_path}/frameworks/ets/ani/ui_ability_ffi:ui_ability_ani", "${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_abc_etc", "${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_ani_kit", ] diff --git a/frameworks/ets/ani/ui_ability_ffi/BUILD.gn b/frameworks/ets/ani/ui_ability_ffi/BUILD.gn new file mode 100644 index 00000000000..dac4668bf45 --- /dev/null +++ b/frameworks/ets/ani/ui_ability_ffi/BUILD.gn @@ -0,0 +1,105 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") +import("//foundation/ability/ability_runtime/ets_environment/ets_environment.gni") + +config("ets_ability_config") { + include_dirs = [ + "include", + ] + + if (ability_runtime_graphics) { + defines = [ + "SUPPORT_GRAPHICS", + "SUPPORT_SCREEN", + ] + } +} + +ohos_shared_library("ui_ability_ani") { + defines = [] + + branch_protector_ret = "pac_ret" + + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "include", + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/interfaces/kits/native/ability/native", + "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime", + "${ability_runtime_path}/utils/global/time/include", + ] + + public_configs = [ ":ets_ability_config" ] + + deps = [ + "${ability_runtime_innerkits_path}/ability_manager:ability_connect_callback_stub", + "${ability_runtime_innerkits_path}/ability_manager:ability_manager", + "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", + "${ability_runtime_innerkits_path}/ability_manager:ability_start_setting", + "${ability_runtime_innerkits_path}/ability_manager:process_options", + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_napi_path}/inner/napi_common:napi_common", + "${ability_runtime_native_path}/ability:ability_context_native", + "${ability_runtime_native_path}/ability/native:abilitykit_native", + "${ability_runtime_native_path}/ability/native:insight_intent_executor", + "${ability_runtime_native_path}/ability/native:uiabilitykit_native", + "${ability_runtime_native_path}/appkit:app_context", + "${ability_runtime_native_path}/appkit:app_context_utils", + "${ability_runtime_native_path}/appkit:appkit_delegator", + "${ability_runtime_native_path}/insight_intent/insight_intent_context:insightintentcontext", + "${ability_runtime_path}/ets_environment/frameworks/ets_environment:ets_environment", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + "${ability_runtime_path}/utils/global/freeze:freeze_util", + "${ability_runtime_services_path}/common:app_util", + "${ability_runtime_services_path}/common:event_report", + ] + + external_deps = [ + "ability_base:base", + "ability_base:configuration", + "ability_base:want", + "bundle_framework:appexecfwk_base", + "bundle_framework:bms_ani_common", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "ets_runtime:libark_jsruntime", + "eventhandler:libeventhandler", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "ipc:ipc_napi", + "json:nlohmann_json_static", + "resource_management:global_resmgr", + "runtime_core:ani", + "samgr:samgr_proxy", + "window_manager:windowstageani_kit", + ] + + sources = [ + "src/ets_ability_context.cpp", + "src/ets_ability_ffi.cpp", + ] + + subsystem_name = "ability" + innerapi_tags = [ "platformsdk" ] + part_name = "ability_runtime" +} diff --git a/interfaces/kits/native/ability/native/ability_runtime/ets_ability_context.h b/frameworks/ets/ani/ui_ability_ffi/include/ets_ability_context.h similarity index 100% rename from interfaces/kits/native/ability/native/ability_runtime/ets_ability_context.h rename to frameworks/ets/ani/ui_ability_ffi/include/ets_ability_context.h diff --git a/frameworks/ets/ani/ui_ability_ffi/include/ets_ability_ffi.h b/frameworks/ets/ani/ui_ability_ffi/include/ets_ability_ffi.h new file mode 100644 index 00000000000..56c73929a39 --- /dev/null +++ b/frameworks/ets/ani/ui_ability_ffi/include/ets_ability_ffi.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_ETS_ABILITY_FFI_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_FFI_H + +#include + +#ifdef WINDOWS_PLATFORM +#define ETS_EXPORT __declspec(dllexport) +#else +#define ETS_EXPORT __attribute__((visibility("default"))) +#endif + +namespace OHOS { +namespace AppExecFwk { +class OHOSApplication; +template class AbilityTransactionCallbackInfo; +} +namespace AAFwk { +class Want; +struct LaunchParam; +} +namespace AbilityRuntime { +class AbilityContext; +} +namespace EtsEnv { +struct ETSNativeReference; +} +} // namespace OHOS + +using FFIHandle = void *; +using AbilityHandle = void *; +using RuntimeHandle = void *; + +extern "C" { +struct ETSAbilityFuncs { + FFIHandle (*CreateEtsFFI)(AbilityHandle ability, RuntimeHandle runtime) = nullptr; + void (*DeleteEtsFFI)(FFIHandle ffi) = nullptr; + bool (*LoadModule)(FFIHandle ffi, const std::string &moduleName, const std::string &modulePath, + const std::string &hapPath, bool esmodule, bool useCommonChunk, const std::string &srcEntrance) = nullptr; + bool (*BindNativeMethods)(FFIHandle ffi) = nullptr; + bool (*CreateEtsContext)(FFIHandle ffi, int32_t screenMode, + const std::shared_ptr &application, + const std::shared_ptr &abilityContext) = nullptr; + void (*OnStart)(FFIHandle ffi, const OHOS::AAFwk::Want &want, const OHOS::AAFwk::LaunchParam &launch) = nullptr; + void (*OnStop)(FFIHandle ffi) = nullptr; + bool (*CallOnDestroy)(FFIHandle ffi, OHOS::AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback) = nullptr; + void (*OnWindowStageCreate)(FFIHandle ffi) = nullptr; + void (*OnWindowStageDestroy)(FFIHandle ffi) = nullptr; + void (*OnForeground)(FFIHandle ffi, const OHOS::AAFwk::Want &want) = nullptr; + void (*OnBackground)(FFIHandle ffi) = nullptr; + void (*OnNewWant)(FFIHandle ffi, const OHOS::AAFwk::Want &want, const OHOS::AAFwk::LaunchParam &launch) = nullptr; + std::weak_ptr (*GetAbilityObject)(FFIHandle ffi) = nullptr; +}; +} + +class __ani_ref; +using ani_ref = __ani_ref *; +class __ani_object; +using ani_object = __ani_object *; + +namespace OHOS { +namespace EtsEnv { +struct ETSNativeReference; +} + +namespace AbilityRuntime { +class EtsUIAbility; +class ETSRuntime; + +class EtsAbilityFFI { +public: + EtsAbilityFFI(AbilityHandle ability, RuntimeHandle runtime); + ~EtsAbilityFFI(); + + static ETSAbilityFuncs *RegisterFuncs(); + static FFIHandle FFICreate(AbilityHandle ability, RuntimeHandle runtime); + static void FFIDelete(FFIHandle ffi); + static bool FFILoadModule(FFIHandle ffi, const std::string &moduleName, const std::string &modulePath, + const std::string &hapPath, bool esmodule, bool useCommonChunk, const std::string &srcEntrance); + static bool FFIBindNativeMethods(FFIHandle ffi); + static bool FFICreateEtsContext(FFIHandle ffi, int32_t screenMode, + const std::shared_ptr &application, + const std::shared_ptr &abilityContext); + static void FFIOnStart(FFIHandle ffi, const OHOS::AAFwk::Want &want, + const OHOS::AAFwk::LaunchParam &launch); + static void FFIOnStop(FFIHandle ffi); + static bool FFICallOnDestroy(FFIHandle ffi, OHOS::AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback); + static void FFIOnWindowStageCreate(FFIHandle ffi); + static void FFIOnWindowStageDestroy(FFIHandle ffi); + static void FFIOnForeground(FFIHandle ffi, const OHOS::AAFwk::Want &want); + static void FFIOnBackground(FFIHandle ffi); + static void FFIOnNewWant(FFIHandle ffi, const OHOS::AAFwk::Want &want, const OHOS::AAFwk::LaunchParam &launch); + static std::weak_ptr FFIGetAbilityObject(FFIHandle ffi); + + bool LoadModule(const std::string &moduleName, const std::string &modulePath, + const std::string &hapPath, bool esmodule, bool useCommonChunk, const std::string &srcEntrance); + bool BindNativeMethods(); + bool CreateEtsContext(int32_t screenMode, const std::shared_ptr &application, + const std::shared_ptr &abilityContex); + void OnStart(const AAFwk::Want &want, const AAFwk::LaunchParam &launch); + void OnStop(); + bool CallOnDestroy(AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsyncCallback); + void OnWindowStageCreate(); + void OnWindowStageDestroy(); + void OnForeground(const AAFwk::Want &want); + void OnBackground(); + void OnNewWant(const AAFwk::Want &want, const AAFwk::LaunchParam &launch); + std::weak_ptr GetAbilityObject(); + +#ifdef SUPPORT_SCREEN +private: + void UpdateEtsWindowStage(ani_ref windowStage); + std::shared_ptr etsWindowStageObj_; +#endif + +private: + bool CallObjectMethod(bool withResult, const char *name, const char *signature, ...); + ani_object CreateAppWindowStage(); + AbilityRuntime::EtsUIAbility *ability_ = nullptr; + AbilityRuntime::ETSRuntime *runtime_ = nullptr; + std::shared_ptr shellContextRef_; + std::shared_ptr etsAbilityObj_; + static std::once_flag singletonFlag_; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_FFI_H diff --git a/frameworks/native/ability/native/ability_runtime/ets_ability_context.cpp b/frameworks/ets/ani/ui_ability_ffi/src/ets_ability_context.cpp similarity index 99% rename from frameworks/native/ability/native/ability_runtime/ets_ability_context.cpp rename to frameworks/ets/ani/ui_ability_ffi/src/ets_ability_context.cpp index 216a08b9cc8..6fff62aef92 100644 --- a/frameworks/native/ability/native/ability_runtime/ets_ability_context.cpp +++ b/frameworks/ets/ani/ui_ability_ffi/src/ets_ability_context.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "ability_runtime/ets_ability_context.h" +#include "ets_ability_context.h" #include "ani_common_ability_result.h" #include "ani_common_configuration.h" @@ -265,7 +265,6 @@ void EtsAbilityContext::OnStartAbilityForResult( if (startOptionsObj) { OHOS::AppExecFwk::UnwrapStartOptions(env, startOptionsObj, startOptions); } - TAG_LOGE(AAFwkTag::CONTEXT, "displayId:%{public}d", startOptions.GetDisplayID()); std::string startTime = std::to_string( std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) .count()); diff --git a/frameworks/ets/ani/ui_ability_ffi/src/ets_ability_ffi.cpp b/frameworks/ets/ani/ui_ability_ffi/src/ets_ability_ffi.cpp new file mode 100644 index 00000000000..dd0080ffc92 --- /dev/null +++ b/frameworks/ets/ani/ui_ability_ffi/src/ets_ability_ffi.cpp @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ets_ability_ffi.h" + +#include +#include +#include + +#include "ani_common_want.h" +#include "app_recovery.h" +#include "connection_manager.h" +#include "ets_ability_context.h" +#include "ets_data_struct_converter.h" +#include "ets_runtime.h" +#include "ets_envsetup.h" +#include "ets_ui_ability.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "insight_intent_execute_param.h" +#include "string_wrapper.h" +#ifdef SUPPORT_SCREEN +#include "ani_window_stage.h" +#endif + +namespace OHOS { +namespace AbilityRuntime { +namespace { +constexpr const char *UI_ABILITY_CLASS_NAME = "L@ohos/app/ability/UIAbility/UIAbility;"; + +void OnDestroyPromiseCallback(ani_env *env, ani_object aniObj) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "OnDestroyPromiseCallback called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + ani_long destroyCallbackPtr = 0; + ani_status status = ANI_ERROR; + if ((status = env->Object_GetFieldByName_Long(aniObj, "destroyCallbackPoint", &destroyCallbackPtr)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_GetFieldByName_Long status: %{public}d", status); + return; + } + if (destroyCallbackPtr == 0) { + TAG_LOGE(AAFwkTag::UIABILITY, "null destroyCallbackPtr"); + return; + } + auto *callbackInfo = reinterpret_cast *>(destroyCallbackPtr); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null callbackInfo"); + return; + } + callbackInfo->Call(); + AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo); +} +} // namespace + +std::once_flag EtsAbilityFFI::singletonFlag_; + +EtsAbilityFFI::EtsAbilityFFI(AbilityHandle ability, RuntimeHandle runtime) +{ + ability_ = reinterpret_cast(ability); + runtime_ = reinterpret_cast(runtime); +} + +EtsAbilityFFI::~EtsAbilityFFI() +{ + if (runtime_ == nullptr) { + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + return; + } + + if (shellContextRef_ && shellContextRef_->aniRef) { + env->GlobalReference_Delete(shellContextRef_->aniRef); + } + if (etsWindowStageObj_ && etsWindowStageObj_->aniRef) { + env->GlobalReference_Delete(etsWindowStageObj_->aniRef); + } +} + +bool EtsAbilityFFI::LoadModule(const std::string &moduleName, const std::string &modulePath, const std::string &hapPath, + bool esmodule, bool useCommonChunk, const std::string &srcEntrance) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_"); + return false; + } + etsAbilityObj_ = runtime_->LoadModule(moduleName, modulePath, hapPath, esmodule, useCommonChunk, srcEntrance); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "LoadModule failed"); + return false; + } + return true; +} + +bool EtsAbilityFFI::BindNativeMethods() +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_"); + return false; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return false; + } + ani_class cls = nullptr; + ani_status status = env->FindClass(UI_ABILITY_CLASS_NAME, &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "FindClass failed status: %{public}d", status); + return false; + } + std::call_once(singletonFlag_, [&status, env, cls]() { + std::array functions = { + ani_native_function { "nativeOnDestroyCallback", ":V", reinterpret_cast(OnDestroyPromiseCallback) }, + }; + status = env->Class_BindNativeMethods(cls, functions.data(), functions.size()); + }); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Class_BindNativeMethods failed status: %{public}d", status); + return false; + } + return true; +} + +bool EtsAbilityFFI::CreateEtsContext(int32_t screenMode, + const std::shared_ptr &application, + const std::shared_ptr &abilityContex) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_"); + return false; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return false; + } + if (screenMode == AAFwk::IDLE_SCREEN_MODE) { + ani_object contextObj = CreateEtsAbilityContext(env, abilityContex, application); + if (contextObj == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null contextObj"); + return false; + } + ani_ref contextGlobalRef = nullptr; + env->GlobalReference_Create(contextObj, &contextGlobalRef); + ani_status status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "context", contextGlobalRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); + return false; + } + shellContextRef_ = std::make_shared(); + shellContextRef_->aniObj = contextObj; + shellContextRef_->aniRef = contextGlobalRef; + } + // to be done: CreateAniEmbeddableUIAbilityContext + return true; +} + +void EtsAbilityFFI::OnStart(const AAFwk::Want &want, const AAFwk::LaunchParam &launch) +{ + if (runtime_ == nullptr || etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_ or etsAbilityObj_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + ani_object wantObj = OHOS::AppExecFwk::WrapWant(env, want); + if (wantObj == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); + return; + } + ani_status status = ANI_ERROR; + if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "launchWant", wantObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "launchWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + auto launchParam = launch; + if (AppExecFwk::InsightIntentExecuteParam::IsInsightIntentExecute(want)) { + launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT; + } + ani_object launchParamObj = nullptr; + if (!AbilityRuntime::WrapLaunchParam(env, launchParam, launchParamObj)) { + TAG_LOGE(AAFwkTag::UIABILITY, "WrapLaunchParam failed"); + return; + } + CallObjectMethod(false, "onCreate", nullptr, wantObj, launchParamObj); +} + +void EtsAbilityFFI::OnStop() +{ + CallObjectMethod(false, "onDestroy", nullptr); +} + +bool EtsAbilityFFI::CallOnDestroy(AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsyncCallback) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_"); + return false; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr || etsAbilityObj_ == nullptr) { + isAsyncCallback = false; + OnStop(); + return false; + } + + ani_long destroyCallbackPoint = reinterpret_cast(callbackInfo); + ani_status status = + env->Object_SetFieldByName_Long(etsAbilityObj_->aniObj, "destroyCallbackPoint", destroyCallbackPoint); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Long status: %{public}d", status); + return false; + } + isAsyncCallback = CallObjectMethod(true, "callOnDestroy", ":Z"); + return true; +} + +void EtsAbilityFFI::OnWindowStageCreate() +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_"); + return; + } + auto etsAppWindowStage = CreateAppWindowStage(); + if (etsAppWindowStage == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAppWindowStage"); + return; + } + UpdateEtsWindowStage(reinterpret_cast(etsAppWindowStage)); + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + etsWindowStageObj_ = std::make_shared(); + etsWindowStageObj_->aniObj = etsAppWindowStage; + ani_ref entryObjectRef = nullptr; + env->GlobalReference_Create(etsAppWindowStage, &entryObjectRef); + etsWindowStageObj_->aniRef = entryObjectRef; + CallObjectMethod(false, "onWindowStageCreate", nullptr, etsAppWindowStage); +} + +void EtsAbilityFFI::OnWindowStageDestroy() +{ + UpdateEtsWindowStage(nullptr); + CallObjectMethod(false, "onWindowStageDestroy", nullptr); +} + +void EtsAbilityFFI::OnForeground(const AAFwk::Want &want) +{ + if (runtime_ == nullptr || etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_ or etsAbilityObj_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + ani_status status = ANI_ERROR; + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); + return; + } + if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantRef)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + CallObjectMethod(false, "onForeground", nullptr, wantRef); +} + +void EtsAbilityFFI::OnBackground() +{ + CallObjectMethod(false, "onBackground", nullptr); +} + +ani_object EtsAbilityFFI::CreateAppWindowStage() +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (runtime_ == nullptr || ability_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_ or ability_"); + return nullptr; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return nullptr; + } + auto scene = ability_->GetScene(); + if (scene == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "scene not found"); + return nullptr; + } + ani_object etsWindowStage = CreateAniWindowStage(env, scene); + if (etsWindowStage == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsWindowStage"); + return nullptr; + } + return etsWindowStage; +} + +void EtsAbilityFFI::UpdateEtsWindowStage(ani_ref windowStage) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "UpdateEtsWindowStage called"); + if (shellContextRef_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null shellContextRef_"); + return; + } + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + ani_status status = ANI_ERROR; + if (windowStage == nullptr) { + ani_ref undefinedRef = nullptr; + env->GetUndefined(&undefinedRef); + if ((status = env->Object_SetFieldByName_Ref(shellContextRef_->aniObj, "windowStage", undefinedRef)) != + ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + return; + } + if ((status = env->Object_SetFieldByName_Ref(shellContextRef_->aniObj, "windowStage", windowStage)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); + return; + } +} + +void EtsAbilityFFI::OnNewWant(const AAFwk::Want &want, const AAFwk::LaunchParam &launch) +{ + if (runtime_ == nullptr || etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_ or etsAbilityObj_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + ani_object wantObj = OHOS::AppExecFwk::WrapWant(env, want); + if (wantObj == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); + return; + } + ani_status status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantObj); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + auto launchParam = launch; + if (AppExecFwk::InsightIntentExecuteParam::IsInsightIntentExecute(want)) { + launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT; + } + ani_object launchParamObj = nullptr; + if (!AbilityRuntime::WrapLaunchParam(env, launchParam, launchParamObj)) { + TAG_LOGE(AAFwkTag::UIABILITY, "WrapLaunchParam failed"); + return; + } + std::string methodName = "OnNewWant"; + CallObjectMethod(false, "onNewWant", nullptr, wantObj, launchParamObj); +} + +std::weak_ptr EtsAbilityFFI::GetAbilityObject() +{ + return etsAbilityObj_; +} + +bool EtsAbilityFFI::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); + TAG_LOGD(AAFwkTag::UIABILITY, "EtsUIAbility call ets, name: %{public}s", name); + if (runtime_ == nullptr || etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime_ or etsAbilityObj_"); + return false; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return false; + } + auto obj = etsAbilityObj_->aniObj; + auto cls = etsAbilityObj_->aniCls; + + ani_method method = nullptr; + ani_status status = env->Class_FindMethod(cls, name, signature, &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Class_FindMethod status: %{public}d", status); + env->ResetError(); + return false; + } + if (withResult) { + ani_boolean res = ANI_FALSE; + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Boolean_V(obj, method, &res, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_CallMethod_Boolean_V status: %{public}d", status); + runtime_->HandleUncaughtError(); + return false; + } + va_end(args); + return res; + } + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Void_V(obj, method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_CallMethod_Void_V status: %{public}d", status); + runtime_->HandleUncaughtError(); + return false; + } + va_end(args); + TAG_LOGD(AAFwkTag::UIABILITY, "CallObjectMethod end, name: %{public}s", name); + return false; +} + +FFIHandle EtsAbilityFFI::FFICreate(AbilityHandle ability, RuntimeHandle runtime) +{ + return new (std::nothrow) EtsAbilityFFI(ability, runtime); +} + +void EtsAbilityFFI::FFIDelete(FFIHandle ffi) +{ + if (ffi != nullptr) { + delete reinterpret_cast(ffi); + } +} + +bool EtsAbilityFFI::FFILoadModule(FFIHandle ffi, const std::string &moduleName, const std::string &modulePath, + const std::string &hapPath, bool esmodule, bool useCommonChunk, const std::string &srcEntrance) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return false; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + return pFFI->LoadModule(moduleName, modulePath, hapPath, esmodule, useCommonChunk, srcEntrance); +} + +bool EtsAbilityFFI::FFIBindNativeMethods(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return false; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + return pFFI->BindNativeMethods(); +} + +bool EtsAbilityFFI::FFICreateEtsContext(FFIHandle ffi, int32_t screenMode, + const std::shared_ptr &application, + const std::shared_ptr &abilityContext) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return false; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + return pFFI->CreateEtsContext(screenMode, application, abilityContext); +} + +void EtsAbilityFFI::FFIOnStart(FFIHandle ffi, const OHOS::AAFwk::Want &want, const OHOS::AAFwk::LaunchParam &launch) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnStart(want, launch); +} + +void EtsAbilityFFI::FFIOnStop(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnStop(); +} + +bool EtsAbilityFFI::FFICallOnDestroy(FFIHandle ffi, + OHOS::AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsyncCallback) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return false; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + return pFFI->CallOnDestroy(callbackInfo, isAsyncCallback); +} + +void EtsAbilityFFI::FFIOnWindowStageCreate(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnWindowStageCreate(); +} + +void EtsAbilityFFI::FFIOnWindowStageDestroy(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnWindowStageDestroy(); +} + +void EtsAbilityFFI::FFIOnForeground(FFIHandle ffi, const OHOS::AAFwk::Want &want) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnForeground(want); +} + +void EtsAbilityFFI::FFIOnBackground(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnBackground(); +} + +void EtsAbilityFFI::FFIOnNewWant(FFIHandle ffi, const OHOS::AAFwk::Want &want, const OHOS::AAFwk::LaunchParam &launch) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnNewWant(want, launch); +} + +std::weak_ptr EtsAbilityFFI::FFIGetAbilityObject(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ffi"); + return {}; + } + EtsAbilityFFI *pFFI = reinterpret_cast(ffi); + return pFFI->GetAbilityObject(); +} + +ETSAbilityFuncs *EtsAbilityFFI::RegisterFuncs() +{ + static ETSAbilityFuncs funcs = { + .CreateEtsFFI = EtsAbilityFFI::FFICreate, + .DeleteEtsFFI = EtsAbilityFFI::FFIDelete, + .LoadModule = EtsAbilityFFI::FFILoadModule, + .BindNativeMethods = EtsAbilityFFI::FFIBindNativeMethods, + .CreateEtsContext = EtsAbilityFFI::FFICreateEtsContext, + .OnStart = EtsAbilityFFI::FFIOnStart, + .OnStop = EtsAbilityFFI::FFIOnStop, + .CallOnDestroy = EtsAbilityFFI::FFICallOnDestroy, + .OnWindowStageCreate = EtsAbilityFFI::FFIOnWindowStageCreate, + .OnWindowStageDestroy = EtsAbilityFFI::FFIOnWindowStageDestroy, + .OnForeground = EtsAbilityFFI::FFIOnForeground, + .OnBackground = EtsAbilityFFI::FFIOnBackground, + .OnNewWant = EtsAbilityFFI::FFIOnNewWant, + .GetAbilityObject = EtsAbilityFFI::FFIGetAbilityObject, + }; + + return &funcs; +} +} // namespace AbilityRuntime +} // namespace OHOS + +ETS_EXPORT extern "C" ETSAbilityFuncs *OHOS_ETS_Ability_RegisterFuncs() +{ + return OHOS::AbilityRuntime::EtsAbilityFFI::RegisterFuncs(); +} \ No newline at end of file diff --git a/frameworks/native/ability/BUILD.gn b/frameworks/native/ability/BUILD.gn index 0efa4b17397..b8dd2a18bc0 100644 --- a/frameworks/native/ability/BUILD.gn +++ b/frameworks/native/ability/BUILD.gn @@ -59,7 +59,6 @@ ohos_shared_library("ability_context_native") { "ability_runtime/connection_manager.cpp", "ability_runtime/dialog_request_callback_impl.cpp", "ability_runtime/dialog_ui_extension_callback.cpp", - "ability_runtime/ets_extension_context.cpp", "ability_runtime/js_extension_context.cpp", "ability_runtime/local_call_container.cpp", "ability_runtime/local_call_record.cpp", @@ -83,7 +82,6 @@ ohos_shared_library("ability_context_native") { "ability_base:base", "ability_base:session_info", "ability_base:want", - "bundle_framework:bms_ani_common", "bundle_framework:libappexecfwk_common", "access_token:libaccesstoken_sdk", "access_token:libtoken_callback_sdk", @@ -96,7 +94,6 @@ ohos_shared_library("ability_context_native") { "image_framework:image_native", "ipc:ipc_core", "napi:ace_napi", - "runtime_core:ani", ] public_external_deps = [ "ability_base:extractortool", diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index e68e098980d..9059995279a 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -297,7 +297,6 @@ ohos_shared_library("abilitykit_native") { "${ability_runtime_native_path}/ability/native/ability_loader.cpp", "${ability_runtime_native_path}/ability/native/ability_post_event_timeout.cpp", "${ability_runtime_native_path}/ability/native/ability_process.cpp", - "${ability_runtime_native_path}/ability/native/ability_runtime/ets_ability_context.cpp", "${ability_runtime_native_path}/ability/native/ability_runtime/js_ability.cpp", "${ability_runtime_native_path}/ability/native/ability_runtime/js_ability_context.cpp", "${ability_runtime_native_path}/ability/native/ability_runtime/js_caller_complex.cpp", @@ -385,7 +384,6 @@ ohos_shared_library("abilitykit_native") { "ipc:rpc", "napi:ace_napi", "resource_management:global_resmgr", - "runtime_core:ani", "samgr:samgr_proxy", "window_manager:windowstage_kit", ] @@ -814,7 +812,7 @@ config("uiability_config") { ohos_shared_library("uiabilitykit_native") { include_dirs = [ - "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/ui_ability_ffi/include", "${ability_runtime_path}/interfaces/kits/native/ability/native", "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime", "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_ability", @@ -823,6 +821,7 @@ ohos_shared_library("uiabilitykit_native") { ] sources = [ + "${ability_runtime_native_path}/ability/native/ability_runtime/ets_ability_object.cpp", "${ability_runtime_native_path}/ability/native/ability_runtime/ets_ui_ability.cpp", "${ability_runtime_native_path}/ability/native/ability_runtime/js_ui_ability.cpp", "${ability_runtime_native_path}/ability/native/continuation/distributed/continuation_handler_stage.cpp", @@ -855,7 +854,6 @@ ohos_shared_library("uiabilitykit_native") { "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:appkit_delegator", "${ability_runtime_native_path}/insight_intent/insight_intent_context:insightintentcontext", - "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", "${ability_runtime_path}/utils/global/freeze:freeze_util", "${ability_runtime_services_path}/common:app_util", "${ability_runtime_services_path}/common:event_report", @@ -876,9 +874,7 @@ ohos_shared_library("uiabilitykit_native") { "ipc:ipc_core", "ipc:ipc_napi", "resource_management:global_resmgr", - "runtime_core:ani", "samgr:samgr_proxy", - "window_manager:windowstageani_kit", ] public_external_deps = [ "bundle_framework:appexecfwk_core", @@ -1767,6 +1763,7 @@ ohos_shared_library("ui_extension") { "${ability_runtime_native_path}/ability/native:insight_intent_executor", "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:app_context_utils", + "${ability_runtime_path}/ets_environment/frameworks/ets_environment:ets_environment", "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] diff --git a/frameworks/native/ability/native/ability_runtime/ets_ability_object.cpp b/frameworks/native/ability/native/ability_runtime/ets_ability_object.cpp new file mode 100644 index 00000000000..1dd6b66ce94 --- /dev/null +++ b/frameworks/native/ability/native/ability_runtime/ets_ability_object.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ets_ability_object.h" + +#include +#include + +#include "ets_ability_ffi.h" +#include "hilog_tag_wrapper.h" +#include "want_params_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +const char *ETS_FFI_LIBNAME = "libui_ability_ani.z.so"; +const char *ETS_FFI_REGISTER_FUNCS = "OHOS_ETS_Ability_RegisterFuncs"; +ETSAbilityFuncs *g_etsFFIFuncs = nullptr; + +bool RegisterETSAbilityFuncs() +{ + if (g_etsFFIFuncs != nullptr) { + return true; + } + auto handle = dlopen(ETS_FFI_LIBNAME, RTLD_NOW); + if (!handle) { + TAG_LOGE(AAFwkTag::UIABILITY, "dlopen failed %{public}s, %{public}s", ETS_FFI_LIBNAME, dlerror()); + return false; + } + auto symbol = dlsym(handle, ETS_FFI_REGISTER_FUNCS); + if (!symbol) { + TAG_LOGE(AAFwkTag::UIABILITY, "dlsym failed %{public}s, %{public}s", ETS_FFI_REGISTER_FUNCS, dlerror()); + dlclose(handle); + return false; + } + auto func = reinterpret_cast(symbol); + g_etsFFIFuncs = func(); + return true; +} +} // namespace + +bool ETSAbilityObject::Init(AbilityHandle ability, RuntimeHandle runtime) +{ + if (!RegisterETSAbilityFuncs()) { + TAG_LOGE(AAFwkTag::UIABILITY, "RegisterETSAbilityFuncs failed"); + return false; + } + + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->CreateEtsFFI == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or CreateEtsFFI"); + return false; + } + ffi_ = g_etsFFIFuncs->CreateEtsFFI(ability, runtime); + return true; +} + +ETSAbilityObject::~ETSAbilityObject() +{ + if (ffi_ != nullptr) { + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->DeleteEtsFFI == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or DeleteEtsFFI"); + return; + } + g_etsFFIFuncs->DeleteEtsFFI(ffi_); + } +} + +bool ETSAbilityObject::LoadModule(const std::string &moduleName, const std::string &modulePath, + const std::string &hapPath, bool esmodule, bool useCommonChunk, const std::string &srcEntrance) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->LoadModule == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or LoadModule"); + return false; + } + return g_etsFFIFuncs->LoadModule(ffi_, moduleName, modulePath, hapPath, + esmodule, useCommonChunk, srcEntrance); +} + +bool ETSAbilityObject::BindNativeMethods() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->BindNativeMethods == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or BindNativeMethods"); + return false; + } + return g_etsFFIFuncs->BindNativeMethods(ffi_); +} + +void ETSAbilityObject::CreateEtsContext(int32_t screenMode, + const std::shared_ptr &application, + const std::shared_ptr &abilityContext) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->CreateEtsContext == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or CreateEtsContext"); + return; + } + g_etsFFIFuncs->CreateEtsContext(ffi_, screenMode, application, abilityContext); +} + +void ETSAbilityObject::OnStart(const AAFwk::Want &want, const AAFwk::LaunchParam &launch) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnStart == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or OnStart"); + return; + } + g_etsFFIFuncs->OnStart(ffi_, want, launch); +} + +void ETSAbilityObject::OnStop() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnStop == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or OnStop"); + return; + } + g_etsFFIFuncs->OnStop(ffi_); +} + +bool ETSAbilityObject::CallOnDestroy(AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->CallOnDestroy == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or CallOnDestroy"); + return false; + } + return g_etsFFIFuncs->CallOnDestroy(ffi_, callbackInfo, isAsyncCallback); +} + +void ETSAbilityObject::OnWindowStageCreate() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnWindowStageCreate == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or OnWindowStageCreate"); + return; + } + g_etsFFIFuncs->OnWindowStageCreate(ffi_); +} + +void ETSAbilityObject::OnWindowStageDestroy() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnWindowStageDestroy == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or OnWindowStageDestroy"); + return; + } + g_etsFFIFuncs->OnWindowStageDestroy(ffi_); +} + +void ETSAbilityObject::OnForeground(const AAFwk::Want &want) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnForeground == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or OnForeground"); + return; + } + g_etsFFIFuncs->OnForeground(ffi_, want); +} + +void ETSAbilityObject::OnBackground() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnBackground == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or OnBackground"); + return; + } + g_etsFFIFuncs->OnBackground(ffi_); +} + +void ETSAbilityObject::OnNewWant(const AAFwk::Want &want, const AAFwk::LaunchParam &launch) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnNewWant == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or OnNewWant"); + return; + } + g_etsFFIFuncs->OnNewWant(ffi_, want, launch); +} + +std::weak_ptr ETSAbilityObject::GetAbilityObject() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->GetAbilityObject == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null g_etsFFIFuncs or GetAbilityObject"); + return {}; + } + return g_etsFFIFuncs->GetAbilityObject(ffi_); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/ability/native/ability_runtime/ets_ui_ability.cpp b/frameworks/native/ability/native/ability_runtime/ets_ui_ability.cpp index a2c11640acf..5315ee9c4dc 100644 --- a/frameworks/native/ability/native/ability_runtime/ets_ui_ability.cpp +++ b/frameworks/native/ability/native/ability_runtime/ets_ui_ability.cpp @@ -18,22 +18,16 @@ #include #include "ability_delegator_registry.h" -#include "ani_common_want.h" -#ifdef SUPPORT_SCREEN -#include "ani_window_stage.h" -#endif #include "app_recovery.h" #include "connection_manager.h" +#include "ets_ability_object.h" #include "display_util.h" -#include "ets_ability_context.h" -#include "ets_data_struct_converter.h" #include "hilog_tag_wrapper.h" #include "hitrace_meter.h" #include "string_wrapper.h" namespace OHOS { namespace AbilityRuntime { -std::once_flag EtsUIAbility::singletonFlag_; namespace { #ifdef SUPPORT_GRAPHICS const std::string PAGE_STACK_PROPERTY_NAME = "pageStack"; @@ -43,33 +37,6 @@ const std::string METHOD_NAME = "WindowScene::GoForeground"; #ifdef SUPPORT_SCREEN constexpr int32_t BASE_DISPLAY_ID_NUM(10); #endif -constexpr const char *UI_ABILITY_CLASS_NAME = "L@ohos/app/ability/UIAbility/UIAbility;"; - -void OnDestroyPromiseCallback(ani_env *env, ani_object aniObj) -{ - TAG_LOGI(AAFwkTag::UIABILITY, "OnDestroyPromiseCallback called"); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return; - } - ani_long destroyCallbackPtr = 0; - ani_status status = ANI_ERROR; - if ((status = env->Object_GetFieldByName_Long(aniObj, "destroyCallbackPoint", &destroyCallbackPtr)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Object_GetFieldByName_Long status: %{public}d", status); - return; - } - if (destroyCallbackPtr == 0) { - TAG_LOGE(AAFwkTag::UIABILITY, "null destroyCallbackPtr"); - return; - } - auto *callbackInfo = reinterpret_cast *>(destroyCallbackPtr); - if (callbackInfo == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null callbackInfo"); - return; - } - callbackInfo->Call(); - AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo); -} } // namespace UIAbility *EtsUIAbility::Create(const std::unique_ptr &runtime) @@ -79,23 +46,13 @@ UIAbility *EtsUIAbility::Create(const std::unique_ptr &runtime) EtsUIAbility::EtsUIAbility(ETSRuntime &etsRuntime) : etsRuntime_(etsRuntime) { + etsAbilityObj_ = std::make_shared(); TAG_LOGD(AAFwkTag::UIABILITY, "EtsUIAbility called"); } EtsUIAbility::~EtsUIAbility() { TAG_LOGI(AAFwkTag::UIABILITY, "~EtsUIAbility called"); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return; - } - if (shellContextRef_ && shellContextRef_->aniRef) { - env->GlobalReference_Delete(shellContextRef_->aniRef); - } - if (etsWindowStageObj_ && etsWindowStageObj_->aniRef) { - env->GlobalReference_Delete(etsWindowStageObj_->aniRef); - } } void EtsUIAbility::Init(std::shared_ptr record, @@ -103,6 +60,15 @@ void EtsUIAbility::Init(std::shared_ptr record, const sptr &token) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + if (!etsAbilityObj_->Init(reinterpret_cast(this), reinterpret_cast(&etsRuntime_))) { + TAG_LOGE(AAFwkTag::UIABILITY, "Init failed"); + return; + } + if (record == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null localAbilityRecord"); return; @@ -140,40 +106,21 @@ void EtsUIAbility::Init(std::shared_ptr record, SetAbilityContext(abilityInfo, record->GetWant(), moduleName, srcPath, application); } -bool EtsUIAbility::BindNativeMethods() -{ - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return false; - } - ani_class cls = nullptr; - ani_status status = env->FindClass(UI_ABILITY_CLASS_NAME, &cls); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "FindClass failed status: %{public}d", status); - return false; - } - std::call_once(singletonFlag_, [&status, env, cls]() { - std::array functions = { - ani_native_function { "nativeOnDestroyCallback", ":V", reinterpret_cast(OnDestroyPromiseCallback) }, - }; - status = env->Class_BindNativeMethods(cls, functions.data(), functions.size()); - }); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Class_BindNativeMethods failed status: %{public}d", status); - return false; - } - return true; -} - void EtsUIAbility::UpdateAbilityObj( std::shared_ptr abilityInfo, const std::string &moduleName, const std::string &srcPath) { - std::string key = moduleName + "::" + srcPath; - std::unique_ptr moduleObj = nullptr; - etsAbilityObj_ = etsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->hapPath, - abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE, false, abilityInfo->srcEntrance); - if (!BindNativeMethods()) { + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + + if (!etsAbilityObj_->LoadModule(moduleName, srcPath, abilityInfo->hapPath, + abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE, false, abilityInfo->srcEntrance)) { + TAG_LOGE(AAFwkTag::UIABILITY, "LoadModule failed"); + return; + } + + if (!etsAbilityObj_->BindNativeMethods()) { TAG_LOGE(AAFwkTag::UIABILITY, "BindNativeMethods failed"); return; } @@ -189,34 +136,7 @@ void EtsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, s return; } int32_t screenMode = want->GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::ScreenMode::IDLE_SCREEN_MODE); - CreateEtsContext(screenMode, application); -} - -void EtsUIAbility::CreateEtsContext(int32_t screenMode, const std::shared_ptr &application) -{ - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return; - } - if (screenMode == AAFwk::IDLE_SCREEN_MODE) { - ani_object contextObj = CreateEtsAbilityContext(env, abilityContext_, application); - if (contextObj == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null contextObj"); - return; - } - ani_ref contextGlobalRef = nullptr; - env->GlobalReference_Create(contextObj, &contextGlobalRef); - ani_status status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "context", contextGlobalRef); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); - return; - } - shellContextRef_ = std::make_shared(); - shellContextRef_->aniObj = contextObj; - shellContextRef_->aniRef = contextGlobalRef; - } - // to be done: CreateAniEmbeddableUIAbilityContext + etsAbilityObj_->CreateEtsContext(screenMode, application, abilityContext_); } void EtsUIAbility::OnStart(const Want &want, sptr sessionInfo) @@ -225,39 +145,11 @@ void EtsUIAbility::OnStart(const Want &want, sptr sessionInf TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); UIAbility::OnStart(want, sessionInfo); - if (!etsAbilityObj_) { - TAG_LOGE(AAFwkTag::UIABILITY, "not found Ability.js"); - return; - } - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return; - } - ani_object wantObj = OHOS::AppExecFwk::WrapWant(env, want); - if (wantObj == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); - return; - } - ani_status status = ANI_ERROR; - if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "launchWant", wantObj)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "launchWant Object_SetFieldByName_Ref status: %{public}d", status); - return; - } - if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantObj)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); - return; - } - auto launchParam = GetLaunchParam(); - if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) { - launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT; - } - ani_object launchParamObj = nullptr; - if (!WrapLaunchParam(env, launchParam, launchParamObj)) { - TAG_LOGE(AAFwkTag::UIABILITY, "WrapLaunchParam failed"); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); return; } - CallObjectMethod(false, "onCreate", nullptr, wantObj, launchParamObj); + etsAbilityObj_->OnStart(want, GetLaunchParam()); auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator( AbilityRuntime::Runtime::Language::ETS); if (delegator) { @@ -277,7 +169,11 @@ void EtsUIAbility::OnStop() } UIAbility::OnStop(); - CallObjectMethod(false, "onDestroy", nullptr); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + etsAbilityObj_->OnStop(); OnStopCallback(); TAG_LOGD(AAFwkTag::UIABILITY, "OnStop end"); } @@ -307,22 +203,15 @@ void EtsUIAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callback }; callbackInfo->Push(asyncCallback); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr || etsAbilityObj_ == nullptr) { - isAsyncCallback = false; - OnStop(); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); return; } - - ani_long destroyCallbackPoint = reinterpret_cast(callbackInfo); - ani_status status = - env->Object_SetFieldByName_Long(etsAbilityObj_->aniObj, "destroyCallbackPoint", destroyCallbackPoint); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Long status: %{public}d", status); + if (!etsAbilityObj_->CallOnDestroy(callbackInfo, isAsyncCallback)) { + TAG_LOGE(AAFwkTag::UIABILITY, "CallOnDestroy failed"); return; } - isAsyncCallback = CallObjectMethod(true, "callOnDestroy", ":Z"); - TAG_LOGD(AAFwkTag::UIABILITY, "callOnDestroy isAsyncCallback: %{public}d", isAsyncCallback); + TAG_LOGD(AAFwkTag::UIABILITY, "CallOnDestroy isAsyncCallback: %{public}d", isAsyncCallback); if (!isAsyncCallback) { OnStopCallback(); return; @@ -352,23 +241,12 @@ void EtsUIAbility::OnSceneCreated() HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); UIAbility::OnSceneCreated(); - auto etsAppWindowStage = CreateAppWindowStage(); - if (etsAppWindowStage == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null etsAppWindowStage"); - return; - } - UpdateEtsWindowStage(reinterpret_cast(etsAppWindowStage)); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + + if (!etsAbilityObj_) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); return; } - etsWindowStageObj_ = std::make_shared(); - etsWindowStageObj_->aniObj = etsAppWindowStage; - ani_ref entryObjectRef = nullptr; - env->GlobalReference_Create(etsAppWindowStage, &entryObjectRef); - etsWindowStageObj_->aniRef = entryObjectRef; - CallObjectMethod(false, "onWindowStageCreate", nullptr, etsAppWindowStage); + etsAbilityObj_->OnWindowStageCreate(); auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator( AbilityRuntime::Runtime::Language::ETS); if (delegator) { @@ -382,8 +260,11 @@ void EtsUIAbility::onSceneDestroyed() { TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); UIAbility::onSceneDestroyed(); - UpdateEtsWindowStage(nullptr); - CallObjectMethod(false, "onWindowStageDestroy", nullptr); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + etsAbilityObj_->OnWindowStageDestroy(); if (scene_ != nullptr) { auto window = scene_->GetMainWindow(); if (window != nullptr) { @@ -414,26 +295,11 @@ void EtsUIAbility::OnForeground(const Want &want) void EtsUIAbility::CallOnForegroundFunc(const Want &want) { - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return; - } if (etsAbilityObj_ == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); return; } - ani_status status = ANI_ERROR; - ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); - if (wantRef == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); - return; - } - if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantRef)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); - return; - } - CallObjectMethod(false, "onForeground", nullptr, wantRef); + etsAbilityObj_->OnForeground(want); auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator( AbilityRuntime::Runtime::Language::ETS); if (delegator) { @@ -447,7 +313,11 @@ void EtsUIAbility::OnBackground() { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); - CallObjectMethod(false, "onBackground", nullptr); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + etsAbilityObj_->OnBackground(); UIAbility::OnBackground(); auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator( AbilityRuntime::Runtime::Language::ETS); @@ -458,27 +328,6 @@ void EtsUIAbility::OnBackground() TAG_LOGD(AAFwkTag::UIABILITY, "OnBackground end"); } -ani_object EtsUIAbility::CreateAppWindowStage() -{ - HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return nullptr; - } - auto scene = GetScene(); - if (scene == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "scene not found"); - return nullptr; - } - ani_object etsWindowStage = CreateAniWindowStage(env, scene); - if (etsWindowStage == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null etsWindowStage"); - return nullptr; - } - return etsWindowStage; -} - void EtsUIAbility::GetPageStackFromWant(const Want &want, std::string &pageStack) { auto stringObj = AAFwk::IString::Query(want.GetParams().GetParam(PAGE_STACK_PROPERTY_NAME)); @@ -617,35 +466,6 @@ void EtsUIAbility::ContinuationRestore(const Want &want) RestorePageStack(want); NotifyContinuationResult(want, true); } - -void EtsUIAbility::UpdateEtsWindowStage(ani_ref windowStage) -{ - TAG_LOGD(AAFwkTag::UIABILITY, "UpdateEtsWindowStage called"); - if (shellContextRef_ == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null shellContextRef_"); - return; - } - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return; - } - ani_status status = ANI_ERROR; - if (windowStage == nullptr) { - ani_ref undefinedRef = nullptr; - env->GetUndefined(&undefinedRef); - if ((status = env->Object_SetFieldByName_Ref(shellContextRef_->aniObj, "windowStage", undefinedRef)) != - ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); - return; - } - return; - } - if ((status = env->Object_SetFieldByName_Ref(shellContextRef_->aniObj, "windowStage", windowStage)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); - return; - } -} #endif void EtsUIAbility::OnNewWant(const Want &want) @@ -658,36 +478,11 @@ void EtsUIAbility::OnNewWant(const Want &want) scene_->OnNewWant(want); } #endif - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return; - } if (etsAbilityObj_ == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); return; } - ani_object wantObj = OHOS::AppExecFwk::WrapWant(env, want); - if (wantObj == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); - return; - } - ani_status status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantObj); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); - return; - } - auto launchParam = GetLaunchParam(); - if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) { - launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT; - } - ani_object launchParamObj = nullptr; - if (!WrapLaunchParam(env, launchParam, launchParamObj)) { - TAG_LOGE(AAFwkTag::UIABILITY, "WrapLaunchParam failed"); - return; - } - std::string methodName = "OnNewWant"; - CallObjectMethod(false, "onNewWant", nullptr, wantObj, launchParamObj); + etsAbilityObj_->OnNewWant(want, GetLaunchParam()); TAG_LOGD(AAFwkTag::UIABILITY, "OnNewWant end"); } @@ -703,53 +498,6 @@ void EtsUIAbility::OnAbilityResult(int requestCode, int resultCode, const Want & TAG_LOGD(AAFwkTag::UIABILITY, "OnAbilityResult end"); } -bool EtsUIAbility::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) -{ - HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); - TAG_LOGI(AAFwkTag::UIABILITY, "EtsUIAbility call ets, name: %{public}s", name); - if (etsAbilityObj_ == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj"); - return false; - } - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null env"); - return false; - } - auto obj = etsAbilityObj_->aniObj; - auto cls = etsAbilityObj_->aniCls; - - ani_method method = nullptr; - ani_status status = env->Class_FindMethod(cls, name, signature, &method); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Class_FindMethod status: %{public}d", status); - env->ResetError(); - return false; - } - if (withResult) { - ani_boolean res = ANI_FALSE; - va_list args; - va_start(args, signature); - if ((status = env->Object_CallMethod_Boolean_V(obj, method, &res, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Object_CallMethod_Boolean_V status: %{public}d", status); - etsRuntime_.HandleUncaughtError(); - return false; - } - va_end(args); - return res; - } - va_list args; - va_start(args, signature); - if ((status = env->Object_CallMethod_Void_V(obj, method, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "Object_CallMethod_Void_V status: %{public}d", status); - etsRuntime_.HandleUncaughtError(); - return false; - } - va_end(args); - TAG_LOGI(AAFwkTag::UIABILITY, "CallObjectMethod end, name: %{public}s", name); - return false; -} - std::shared_ptr EtsUIAbility::CreateADelegatorAbilityProperty() { if (abilityContext_ == nullptr) { @@ -771,7 +519,7 @@ std::shared_ptr EtsUIAbility::CreateADe } } property->lifecycleState_ = GetState(); - property->object_ = etsAbilityObj_; + property->object_ = etsAbilityObj_->GetAbilityObject(); return property; } } // namespace AbilityRuntime diff --git a/interfaces/kits/native/ability/native/ability_runtime/ets_ability_object.h b/interfaces/kits/native/ability/native/ability_runtime/ets_ability_object.h new file mode 100644 index 00000000000..09f5d6ac35d --- /dev/null +++ b/interfaces/kits/native/ability/native/ability_runtime/ets_ability_object.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_ETS_ABILITY_OBJECT_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_OBJECT_H + +#include + +#include "ets_runtime.h" + +using FFIHandle = void *; +using AbilityHandle = void *; +using RuntimeHandle = void *; + +namespace OHOS { +namespace AppExecFwk { +class OHOSApplication; +template class AbilityTransactionCallbackInfo; +} + +namespace AAFwk { +class Want; +struct LaunchParam; +} + +namespace EtsEnv { +struct ETSNativeReference; +} + +namespace AbilityRuntime { +class AbilityContext; +class ETSAbilityObject { +public: + explicit ETSAbilityObject() {} + ~ETSAbilityObject(); + + bool Init(AbilityHandle ability, RuntimeHandle runtime); + bool LoadModule(const std::string &moduleName, const std::string &modulePath, const std::string &hapPath, + bool esmodule, bool useCommonChunk, const std::string &srcEntrance); + bool BindNativeMethods(); + void CreateEtsContext(int32_t screenMode, + const std::shared_ptr &application, + const std::shared_ptr &abilityContext); + void OnStart(const AAFwk::Want &want, const AAFwk::LaunchParam &launch); + void OnStop(); + bool CallOnDestroy(AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsyncCallback); + void OnWindowStageCreate(); + void OnWindowStageDestroy(); + void OnForeground(const AAFwk::Want &want); + void OnBackground(); + void OnNewWant(const AAFwk::Want &want, const AAFwk::LaunchParam &launch); + std::weak_ptr GetAbilityObject(); + +private: + FFIHandle ffi_ = nullptr; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_OBJECT_H diff --git a/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability.h b/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability.h index fc559230dfd..678c27eeada 100644 --- a/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability.h +++ b/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability.h @@ -26,6 +26,7 @@ using AbilityHandler = AppExecFwk::AbilityHandler; using AbilityInfo = AppExecFwk::AbilityInfo; using OHOSApplication = AppExecFwk::OHOSApplication; using Want = AppExecFwk::Want; +class ETSAbilityObject; class EtsUIAbility : public UIAbility { public: @@ -143,28 +144,21 @@ private: void RestorePageStack(const Want &want); void GetPageStackFromWant(const Want &want, std::string &pageStack); void AbilityContinuationOrRecover(const Want &want); - void UpdateEtsWindowStage(ani_ref windowStage); std::shared_ptr etsWindowStageObj_; int32_t windowMode_ = 0; #endif private: - bool CallObjectMethod(bool withResult, const char *name, const char *signature, ...); - ani_object CreateAppWindowStage(); std::shared_ptr CreateADelegatorAbilityProperty(); void SetAbilityContext(std::shared_ptr abilityInfo, std::shared_ptr want, const std::string &moduleName, const std::string &srcPath, const std::shared_ptr &application); void DoOnForegroundForSceneIsNull(const Want &want); void UpdateAbilityObj(std::shared_ptr abilityInfo, const std::string &moduleName, const std::string &srcPath); - void CreateEtsContext(int32_t screenMode, const std::shared_ptr &application); - bool BindNativeMethods(); ETSRuntime &etsRuntime_; - std::shared_ptr shellContextRef_; - std::shared_ptr etsAbilityObj_; - static std::once_flag singletonFlag_; + std::shared_ptr etsAbilityObj_; }; } // namespace AbilityRuntime } // namespace OHOS -- Gitee