diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index 2c324d61cda792943193201386f8abcfce228003..6a545f70ae00d9166c977752d12d20d1cb9630e5 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -17,9 +17,11 @@ import("//foundation/ability/ability_runtime/ability_runtime.gni") group("ani_packages") { deps = [ "${ability_runtime_path}/frameworks/ets/ani/ability_delegator:ability_delegator_registry_ani_kit", + "${ability_runtime_path}/frameworks/ets/ani/ability_stage_ffi:ability_stage_ani", "${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/uri_permission_manager:uri_permission_manager_abc_etc", "${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_ani_kit", + "${ability_runtime_path}/frameworks/ets/ani/service_extension_ffi:service_extension_ani", ] } diff --git a/frameworks/ets/ani/ability_stage_ffi/BUILD.gn b/frameworks/ets/ani/ability_stage_ffi/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..67aee85ee4bdfc7a810cd901e1af5967784e958c --- /dev/null +++ b/frameworks/ets/ani/ability_stage_ffi/BUILD.gn @@ -0,0 +1,95 @@ +# 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_stage_config") { + include_dirs = [ + "include", + ] +} + +ohos_shared_library("ability_stage_ani") { + defines = [] + + branch_protector_ret = "pac_ret" + + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "include", + "${ability_runtime_path}/ets_environment/interfaces/inner_api", + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/interfaces/inner_api/error_utils/include", + "${ability_runtime_path}/interfaces/kits/native/appkit", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_bundle_manager_helper", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", + "${ability_runtime_path}/interfaces/kits/native/appkit/app", + "${ability_runtime_path}/interfaces/kits/native/ability/native", + "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime", + ] + + public_configs = [ ":ets_ability_stage_config" ] + + deps = [ + "${ability_runtime_abilitymgr_path}/:abilityms", + "${ability_runtime_innerkits_path}/ability_manager:ability_manager", + "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", + "${ability_runtime_innerkits_path}/app_manager:app_manager", + "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_napi_path}/inner/napi_common:napi_common", + "${ability_runtime_native_path}/ability/native:ability_thread", + "${ability_runtime_native_path}/ability/native:abilitykit_native", + "${ability_runtime_native_path}/ability/native:configuration_helper", + "${ability_runtime_native_path}/ability/native:extensionkit_native", + "${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_path}/frameworks/ets/ani/ani_common:ani_common", + ] + + external_deps = [ + "ability_base:base", + "ability_base:configuration", + "ability_base:want", + "bundle_framework:appexecfwk_base", + "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", + ] + + sources = [ + "src/ets_ability_stage_context.cpp", + "src/ets_ability_stage_ffi.cpp", + ] + + subsystem_name = "ability" + innerapi_tags = [ "platformsdk" ] + part_name = "ability_runtime" +} diff --git a/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage_context.h b/frameworks/ets/ani/ability_stage_ffi/include/ets_ability_stage_context.h similarity index 94% rename from interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage_context.h rename to frameworks/ets/ani/ability_stage_ffi/include/ets_ability_stage_context.h index c88a608735adef6c990485b47be03c54b9fe45bd..40ff4f7ce780d669bbb70a8b6be50ea760a5ddc5 100644 --- a/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage_context.h +++ b/frameworks/ets/ani/ability_stage_ffi/include/ets_ability_stage_context.h @@ -48,7 +48,6 @@ private: std::weak_ptr context_; static ani_ref etsAbilityStageContextObj_; }; - -} // namespace AbilityRuntime -} // namespace OHOS -#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_STAGE_CONTEXT_H +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_STAGE_CONTEXT_H diff --git a/frameworks/ets/ani/ability_stage_ffi/include/ets_ability_stage_ffi.h b/frameworks/ets/ani/ability_stage_ffi/include/ets_ability_stage_ffi.h new file mode 100644 index 0000000000000000000000000000000000000000..2bb6ce01395987811ec8b595bea538ce73500e2e --- /dev/null +++ b/frameworks/ets/ani/ability_stage_ffi/include/ets_ability_stage_ffi.h @@ -0,0 +1,110 @@ +/* + * 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_STAGE_FFI_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_STAGE_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; +class Configuration; +} + +namespace AAFwk { +class Want; +struct LaunchParam; +} + +namespace AbilityRuntime { +class Context; +} +} // namespace OHOS + +using FFIHandle = void *; +using StageHandle = void *; +using RuntimeHandle = void *; + +extern "C" { +struct ETSAbilityStageFuncs { + FFIHandle (*CreateEtsFFI)(StageHandle stage, 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; + void (*OnCreate)(FFIHandle ffi) = nullptr; + void (*OnDestroy)(FFIHandle ffi) = nullptr; + void (*OnConfigurationUpdated)(FFIHandle ffi, const std::shared_ptr &fullConfig, + const OHOS::AppExecFwk::Configuration &configuration) = nullptr; + void (*SetEtsAbilityStage)(FFIHandle ffi, const std::shared_ptr &context) = 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 EtsAbilityStage; +class ETSRuntime; +class Context; + +class EtsAbilityStageFFI { +public: + EtsAbilityStageFFI(StageHandle stage, RuntimeHandle runtime); + ~EtsAbilityStageFFI() {}; + + static ETSAbilityStageFuncs *RegisterFuncs(); + static FFIHandle FFICreate(StageHandle stage, 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 void FFIOnCreate(FFIHandle ffi); + static void FFIOnDestroy(FFIHandle ffi); + static void FFIOnConfigurationUpdated(FFIHandle ffi, + const std::shared_ptr &fullConfig, + const OHOS::AppExecFwk::Configuration &configuration); + static void FFISetEtsAbilityStage(FFIHandle ffi, const std::shared_ptr &context); + + bool LoadModule(const std::string &moduleName, const std::string &modulePath, + const std::string &hapPath, bool esmodule, bool useCommonChunk, const std::string &srcEntrance); + void OnCreate(); + void OnDestroy(); + void OnConfigurationUpdated(const std::shared_ptr &fullConfig, + const OHOS::AppExecFwk::Configuration &configuration); + void SetEtsAbilityStage(const std::shared_ptr &context); + +private: + bool CallObjectMethod(bool withResult, const char* name, const char* signature, ...) const; + + AbilityRuntime::EtsAbilityStage *stage_ = nullptr; + AbilityRuntime::ETSRuntime *runtime_ = nullptr; + std::shared_ptr etsAbilityStageObj_; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_STAGE_FFI_H diff --git a/frameworks/native/appkit/ability_runtime/app/ets_ability_stage_context.cpp b/frameworks/ets/ani/ability_stage_ffi/src/ets_ability_stage_context.cpp similarity index 100% rename from frameworks/native/appkit/ability_runtime/app/ets_ability_stage_context.cpp rename to frameworks/ets/ani/ability_stage_ffi/src/ets_ability_stage_context.cpp diff --git a/frameworks/ets/ani/ability_stage_ffi/src/ets_ability_stage_ffi.cpp b/frameworks/ets/ani/ability_stage_ffi/src/ets_ability_stage_ffi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ec8317dc7ab368ee2da14e2eafd9e2e1e1a6b07 --- /dev/null +++ b/frameworks/ets/ani/ability_stage_ffi/src/ets_ability_stage_ffi.cpp @@ -0,0 +1,249 @@ +/* + * 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_stage_ffi.h" + +#include "ani_common_configuration.h" +#include "context.h" +#include "ets_ability_stage_context.h" +#include "ets_envsetup.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" + +namespace OHOS { +namespace AbilityRuntime { + +EtsAbilityStageFFI::EtsAbilityStageFFI(StageHandle stage, RuntimeHandle runtime) +{ + stage_ = reinterpret_cast(stage); + runtime_ = reinterpret_cast(runtime); +} + +bool EtsAbilityStageFFI::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::APPKIT, "null runtime_"); + return false; + } + etsAbilityStageObj_ = runtime_->LoadModule(moduleName, modulePath, hapPath, esmodule, useCommonChunk, srcEntrance); + if (etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "LoadModule failed"); + return false; + } + return true; +} + +void EtsAbilityStageFFI::OnCreate() +{ + CallObjectMethod(false, "onCreate", ":V"); +} + +void EtsAbilityStageFFI::OnDestroy() +{ + CallObjectMethod(false, "onDestroy", ":V"); +} + +void EtsAbilityStageFFI::OnConfigurationUpdated(const std::shared_ptr &fullConfig, + const OHOS::AppExecFwk::Configuration &configuration) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null runtime_"); + return; + } + + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env"); + return; + } + + ETSAbilityStageContext::ConfigurationUpdated(env, fullConfig); + ani_object configObj = OHOS::AppExecFwk::WrapConfiguration(env, configuration); + if (configObj == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null configObj"); + return; + } + CallObjectMethod(false, "onConfigurationUpdate", "L@ohos/app/ability/Configuration/Configuration;:V", configObj); +} + +bool EtsAbilityStageFFI::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) const +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); + TAG_LOGD(AAFwkTag::APPKIT, "CallObjectMethod: name:%{public}s", name); + if (runtime_ == nullptr || etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null runtime_ or etsAbilityStageObj_"); + return false; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env"); + return false; + } + ani_status status = ANI_OK; + ani_method method = nullptr; + if ((status = env->Class_FindMethod(etsAbilityStageObj_->aniCls, name, signature, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status); + return false; + } + env->ResetError(); + if (withResult) { + ani_boolean res = ANI_FALSE; + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Boolean(etsAbilityStageObj_->aniObj, method, &res, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status); + runtime_->HandleUncaughtError(); + } + va_end(args); + return res; + } + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Void_V(etsAbilityStageObj_->aniObj, method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status); + runtime_->HandleUncaughtError(); + return false; + } + va_end(args); + return false; +} + +void EtsAbilityStageFFI::SetEtsAbilityStage(const std::shared_ptr &context) +{ + if (context == nullptr || etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null context or etsAbilityStageObj_"); + return; + } + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null runtime_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env"); + return; + } + ani_object stageCtxObj = ETSAbilityStageContext::CreateEtsAbilityStageContext(env, context); + if (stageCtxObj == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "CreateEtsAbilityStageContext failed"); + return; + } + + ani_status status = ANI_OK; + ani_field contextField; + status = env->Class_FindField(etsAbilityStageObj_->aniCls, "context", &contextField); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_GetField context failed"); + return; + } + ani_ref stageCtxObjRef = nullptr; + if (env->GlobalReference_Create(stageCtxObj, &stageCtxObjRef) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "GlobalReference_Create stageCtxObj failed"); + return; + } + if (env->Object_SetField_Ref(etsAbilityStageObj_->aniObj, contextField, stageCtxObjRef) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Ref stageCtxObj failed"); + } +} + +FFIHandle EtsAbilityStageFFI::FFICreate(StageHandle stage, RuntimeHandle runtime) +{ + return new (std::nothrow) EtsAbilityStageFFI(stage, runtime); +} + +void EtsAbilityStageFFI::FFIDelete(FFIHandle ffi) +{ + if (ffi != nullptr) { + delete reinterpret_cast(ffi); + } +} + +bool EtsAbilityStageFFI::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::APPKIT, "null ffi"); + return false; + } + EtsAbilityStageFFI *pFFI = reinterpret_cast(ffi); + return pFFI->LoadModule(moduleName, modulePath, hapPath, esmodule, useCommonChunk, srcEntrance); +} + +void EtsAbilityStageFFI::FFIOnCreate(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null ffi"); + return; + } + EtsAbilityStageFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnCreate(); +} + +void EtsAbilityStageFFI::FFIOnDestroy(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null ffi"); + return; + } + EtsAbilityStageFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnDestroy(); +} + +void EtsAbilityStageFFI::FFIOnConfigurationUpdated(FFIHandle ffi, + const std::shared_ptr &fullConfig, + const OHOS::AppExecFwk::Configuration &configuration) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null ffi"); + return; + } + EtsAbilityStageFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnConfigurationUpdated(fullConfig, configuration); +} + +void EtsAbilityStageFFI::FFISetEtsAbilityStage(FFIHandle ffi, + const std::shared_ptr &context) +{ + if (ffi == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null ffi"); + return; + } + EtsAbilityStageFFI *pFFI = reinterpret_cast(ffi); + return pFFI->SetEtsAbilityStage(context); +} + +ETSAbilityStageFuncs *EtsAbilityStageFFI::RegisterFuncs() +{ + static ETSAbilityStageFuncs funcs = { + .CreateEtsFFI = EtsAbilityStageFFI::FFICreate, + .DeleteEtsFFI = EtsAbilityStageFFI::FFIDelete, + .LoadModule = EtsAbilityStageFFI::FFILoadModule, + .OnCreate = EtsAbilityStageFFI::FFIOnCreate, + .OnDestroy = EtsAbilityStageFFI::FFIOnDestroy, + .OnConfigurationUpdated = EtsAbilityStageFFI::FFIOnConfigurationUpdated, + .SetEtsAbilityStage = EtsAbilityStageFFI::FFISetEtsAbilityStage, + }; + + return &funcs; +} +} // namespace AbilityRuntime +} // namespace OHOS + +ETS_EXPORT extern "C" ETSAbilityStageFuncs *OHOS_ETS_Ability_Stage_RegisterFuncs() +{ + return OHOS::AbilityRuntime::EtsAbilityStageFFI::RegisterFuncs(); +} \ No newline at end of file diff --git a/frameworks/ets/ani/ani_common/BUILD.gn b/frameworks/ets/ani/ani_common/BUILD.gn index eeb2538c60c4903e600cf43d5c7267decae8d9fb..92df4b4576c205e7d3897693f0a412c3183f75f7 100644 --- a/frameworks/ets/ani/ani_common/BUILD.gn +++ b/frameworks/ets/ani/ani_common/BUILD.gn @@ -30,6 +30,7 @@ ohos_shared_library("ani_common") { include_dirs = [ "./include", + "${ability_runtime_path}/ets_environment/interfaces/inner_api", "${ability_runtime_path}/frameworks/ets/ani/enum_convert", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", @@ -45,6 +46,10 @@ ohos_shared_library("ani_common") { "src/ani_common_start_options.cpp", "src/ani_common_util.cpp", "src/ani_common_want.cpp", + "src/ets_application_context_utils.cpp", + "src/ets_context_utils.cpp", + "src/ets_data_struct_converter.cpp", + "src/ets_error_utils.cpp", ] cflags = [] @@ -56,7 +61,9 @@ ohos_shared_library("ani_common") { "${ability_runtime_innerkits_path}/ability_manager:ability_manager", "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_native_path}/ability/native:ability_business_error", "${ability_runtime_native_path}/appkit:app_context", + "${ability_runtime_native_path}/appkit:application_context_manager", ] external_deps = [ @@ -65,6 +72,7 @@ ohos_shared_library("ani_common") { "ability_base:want", "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base", + "bundle_framework:bms_ani_common", "c_utils:utils", "common_event_service:cesfwk_innerkits", "eventhandler:libeventhandler", @@ -73,6 +81,9 @@ ohos_shared_library("ani_common") { "ipc:ipc_napi", "json:nlohmann_json_static", "napi:ace_napi", + "resource_management:global_resmgr", + "resource_management:resmgr_napi_core", + "resource_management:resourceManager_ani", "runtime_core:ani", ] diff --git a/interfaces/kits/native/appkit/ability_runtime/context/ets_application_context_utils.h b/frameworks/ets/ani/ani_common/include/ets_application_context_utils.h similarity index 100% rename from interfaces/kits/native/appkit/ability_runtime/context/ets_application_context_utils.h rename to frameworks/ets/ani/ani_common/include/ets_application_context_utils.h diff --git a/interfaces/kits/native/appkit/ability_runtime/context/ets_context_utils.h b/frameworks/ets/ani/ani_common/include/ets_context_utils.h similarity index 100% rename from interfaces/kits/native/appkit/ability_runtime/context/ets_context_utils.h rename to frameworks/ets/ani/ani_common/include/ets_context_utils.h diff --git a/interfaces/inner_api/runtime/include/ets_data_struct_converter.h b/frameworks/ets/ani/ani_common/include/ets_data_struct_converter.h similarity index 100% rename from interfaces/inner_api/runtime/include/ets_data_struct_converter.h rename to frameworks/ets/ani/ani_common/include/ets_data_struct_converter.h diff --git a/interfaces/inner_api/runtime/include/ets_error_utils.h b/frameworks/ets/ani/ani_common/include/ets_error_utils.h similarity index 100% rename from interfaces/inner_api/runtime/include/ets_error_utils.h rename to frameworks/ets/ani/ani_common/include/ets_error_utils.h diff --git a/frameworks/native/appkit/ability_runtime/context/ets_application_context_utils.cpp b/frameworks/ets/ani/ani_common/src/ets_application_context_utils.cpp similarity index 100% rename from frameworks/native/appkit/ability_runtime/context/ets_application_context_utils.cpp rename to frameworks/ets/ani/ani_common/src/ets_application_context_utils.cpp diff --git a/frameworks/native/appkit/ability_runtime/context/ets_context_utils.cpp b/frameworks/ets/ani/ani_common/src/ets_context_utils.cpp similarity index 100% rename from frameworks/native/appkit/ability_runtime/context/ets_context_utils.cpp rename to frameworks/ets/ani/ani_common/src/ets_context_utils.cpp diff --git a/frameworks/native/runtime/ets_data_struct_converter.cpp b/frameworks/ets/ani/ani_common/src/ets_data_struct_converter.cpp similarity index 97% rename from frameworks/native/runtime/ets_data_struct_converter.cpp rename to frameworks/ets/ani/ani_common/src/ets_data_struct_converter.cpp index 17ef61e0e9a0321ee5cead43e22bf5fe3d45ab70..cbc75e33cbaa2ef5f080bd88db5992e15c5041e0 100644 --- a/frameworks/native/runtime/ets_data_struct_converter.cpp +++ b/frameworks/ets/ani/ani_common/src/ets_data_struct_converter.cpp @@ -96,7 +96,7 @@ bool WrapLaunchParam(ani_env *env, const AAFwk::LaunchParam &launchParam, ani_ob return false; } if ((status = env->Object_SetPropertyByName_Ref( - object, "lastExitMessage", GetAniString(env, launchParam.lastExitMessage))) != ANI_OK) { + object, "lastExitMessage", GetAniString(env, launchParam.lastExitMessage))) != ANI_OK) { TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to set lastExitMessage"); return false; } diff --git a/frameworks/native/runtime/ets_error_utils.cpp b/frameworks/ets/ani/ani_common/src/ets_error_utils.cpp similarity index 100% rename from frameworks/native/runtime/ets_error_utils.cpp rename to frameworks/ets/ani/ani_common/src/ets_error_utils.cpp diff --git a/frameworks/ets/ani/service_extension_ability/include/ets_service_extension.h b/frameworks/ets/ani/service_extension_ability/include/ets_service_extension.h index ee550a541b47a29f5ec81257076335d0ec8fd65e..4e4f6fe4fe01e627fed9c1ebf109cee4534c3cf8 100644 --- a/frameworks/ets/ani/service_extension_ability/include/ets_service_extension.h +++ b/frameworks/ets/ani/service_extension_ability/include/ets_service_extension.h @@ -139,11 +139,9 @@ public: private: void ConfigurationUpdated(); - ani_ref CallObjectMethod(bool withResult, const char *name, const char *signature, ...); - sptr OnConnectInner(ani_env *env, ani_object &aniRemoteobj, bool &isAsyncCallback); ETSRuntime &etsRuntime_; - std::unique_ptr etsObj_; + std::shared_ptr etsAbilityObj_; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/ets/ani/service_extension_ability/include/ets_service_extension_object.h b/frameworks/ets/ani/service_extension_ability/include/ets_service_extension_object.h new file mode 100644 index 0000000000000000000000000000000000000000..d82e27b75bc37c67790408db9b2785572e98923a --- /dev/null +++ b/frameworks/ets/ani/service_extension_ability/include/ets_service_extension_object.h @@ -0,0 +1,65 @@ +/* + * 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_SERVICE_EXTENSION_OBJECT_H +#define OHOS_ABILITY_RUNTIME_ETS_SERVICE_EXTENSION_OBJECT_H + +#include + +#include "ets_runtime.h" + +using FFIHandle = void *; +using AbilityHandle = void *; +using RuntimeHandle = void *; + +namespace OHOS { +class IRemoteObject; +template class sptr; +namespace AppExecFwk { +class OHOSApplication; +template class AbilityTransactionCallbackInfo; +} + +namespace AAFwk { +class Want; +struct LaunchParam; +} + +namespace AbilityRuntime { +class AbilityContext; +class ETSServiceExtensionObject { +public: + explicit ETSServiceExtensionObject() {} + ~ETSServiceExtensionObject(); + + 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); + void OnStart(const AAFwk::Want &want); + void OnStop(); + sptr OnConnect(const AAFwk::Want &want); + sptr OnConnectCallback(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, bool &isAsyncCallback); + void OnDisconnect(const AAFwk::Want &want); + void OnDisconnectCallback(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsyncCallback); + void OnCommand(const AAFwk::Want &want, int startId); + +private: + FFIHandle ffi_ = nullptr; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_SERVICE_EXTENSION_OBJECT_H diff --git a/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp b/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp index a588108632048c36eeed4ef98c0feee5341dcf49..2e7682e11809541e2077fcb047edb24affa9b863 100644 --- a/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp +++ b/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp @@ -17,9 +17,8 @@ #include "ability_info.h" #include "ability_manager_client.h" -#include "ani_common_want.h" -#include "ani_remote_object.h" #include "configuration_utils.h" +#include "ets_service_extension_object.h" #include "hilog_tag_wrapper.h" #include "hitrace_meter.h" #include "js_service_extension_context.h" @@ -27,76 +26,17 @@ namespace OHOS { namespace AbilityRuntime { using namespace OHOS::AppExecFwk; -namespace { -constexpr const char *CLASSNAME_SERVICE_ABILITY = - "L@ohos/app/ability/ServiceExtensionAbility/ServiceExtensionAbility;"; -constexpr const char *NATIVE_ONCONNECT_CALLBACK_SIGNATURE = "L@ohos/rpc/rpc/RemoteObject;:Z"; -constexpr const char *ON_CREATE_SIGNATURE = "L@ohos/app/ability/Want/Want;:V"; -constexpr const char *VOID_SIGNATURE = ":V"; -constexpr const char *ON_CONNECT_SIGNATURE = "L@ohos/app/ability/Want/Want;:Lstd/core/Object;"; -constexpr const char *CHECK_PROMISE_SIGNATURE = "Lstd/core/Object;:Z"; -constexpr const char *CALL_PROMISE_SIGNATURE = "Lstd/core/Object;:Z"; -constexpr const char *ON_DISCONNECT_SIGNATURE = "L@ohos/app/ability/Want/Want;:V"; -constexpr const char *ON_REQUEST_SIGNATURE = "L@ohos/app/ability/Want/Want;D:V"; -void DisconnectPromiseCallback(ani_env *env, ani_object aniObj) -{ - TAG_LOGD(AAFwkTag::SERVICE_EXT, "DisconnectPromiseCallback"); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return; - } - ani_long disconnectCallbackPoint = 0; - ani_status status = ANI_ERROR; - if ((status = env->Object_GetFieldByName_Long(aniObj, "disconnectCallbackPoint", &disconnectCallbackPoint)) != - ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return; - } - auto *callbackInfo = reinterpret_cast *>(disconnectCallbackPoint); - if (callbackInfo == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null callbackInfo"); - return; - } - callbackInfo->Call(); - AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo); -} - -void ConnectPromiseCallback(ani_env *env, ani_object aniObj, ani_object obj) +EtsServiceExtension *EtsServiceExtension::Create(const std::unique_ptr &runtime) { - TAG_LOGD(AAFwkTag::SERVICE_EXT, "ConnectPromiseCallback"); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return; - } - ani_long connectCallbackPoint = 0; - ani_status status = ANI_ERROR; - if ((status = env->Object_GetFieldByName_Long(aniObj, "connectCallbackPoint", &connectCallbackPoint)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return; - } - auto remoteObject = AniGetNativeRemoteObject(env, obj); - if (remoteObject == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null remoteObject"); - } - auto *callbackInfo = - reinterpret_cast> *>(connectCallbackPoint); - if (callbackInfo == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null callbackInfo"); - return; - } - - callbackInfo->Call(remoteObject); - AppExecFwk::AbilityTransactionCallbackInfo>::Destroy(callbackInfo); + return new EtsServiceExtension(static_cast(*runtime)); } -} // namespace -EtsServiceExtension *EtsServiceExtension::Create(const std::unique_ptr &runtime) +EtsServiceExtension::EtsServiceExtension(ETSRuntime &etsRuntime) : etsRuntime_(etsRuntime) { - return new EtsServiceExtension(static_cast(*runtime)); + etsAbilityObj_ = std::make_shared(); } -EtsServiceExtension::EtsServiceExtension(ETSRuntime &etsRuntime) : etsRuntime_(etsRuntime) {} EtsServiceExtension::~EtsServiceExtension() { TAG_LOGD(AAFwkTag::SERVICE_EXT, "EtsServiceExtension destory"); @@ -115,6 +55,14 @@ void EtsServiceExtension::Init(const std::shared_ptr &record TAG_LOGE(AAFwkTag::SERVICE_EXT, "init failed, some obj null"); return; } + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); + return; + } + if (!etsAbilityObj_->Init(reinterpret_cast(this), reinterpret_cast(&etsRuntime_))) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "Init failed"); + return; + } Extension::Init(record, application, handler, token); if (Extension::abilityInfo_ == nullptr || Extension::abilityInfo_->srcEntrance.empty()) { TAG_LOGE(AAFwkTag::SERVICE_EXT, "EtsServiceExtension Init abilityInfo error"); @@ -129,31 +77,9 @@ void EtsServiceExtension::Init(const std::shared_ptr &record } std::string moduleName(Extension::abilityInfo_->moduleName); moduleName.append("::").append(abilityInfo_->name); - etsObj_ = etsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, - abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE, false, abilityInfo_->srcEntrance); - if (etsObj_ == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsObj"); - return; - } - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return; - } - std::array functions = { - ani_native_function { - "nativeOnDisconnectCallback", VOID_SIGNATURE, reinterpret_cast(DisconnectPromiseCallback) }, - ani_native_function { "nativeOnConnectCallback", NATIVE_ONCONNECT_CALLBACK_SIGNATURE, - reinterpret_cast(ConnectPromiseCallback) }, - }; - ani_class cls = nullptr; - ani_status status = ANI_ERROR; - if ((status = env->FindClass(CLASSNAME_SERVICE_ABILITY, &cls)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status: %{public}d", status); - return; - } - if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "Class_BindNativeMethods is fail %{public}d", status); + if (!etsAbilityObj_->LoadModule(moduleName, srcPath, abilityInfo_->hapPath, + abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE, false, abilityInfo_->srcEntrance)) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "LoadModule failed"); return; } } @@ -162,18 +88,12 @@ void EtsServiceExtension::OnStart(const AAFwk::Want &want) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnStart"); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "env not found Ability.ets"); - return; - } - ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); - if (wantRef == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); return; } - - CallObjectMethod(false, "onCreate", ON_CREATE_SIGNATURE, wantRef); + etsAbilityObj_->OnStart(want); TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); } @@ -182,7 +102,12 @@ void EtsServiceExtension::OnStop() HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnStop"); ServiceExtension::OnStop(); - CallObjectMethod(false, "onDestroy", VOID_SIGNATURE); + + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); + return; + } + etsAbilityObj_->OnStop(); TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); } @@ -191,23 +116,12 @@ sptr EtsServiceExtension::OnConnect(const AAFwk::Want &want) HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnConnect"); Extension::OnConnect(want); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return nullptr; - } - ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); - if (wantRef == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); - return nullptr; - } - ani_ref result = CallObjectMethod(true, "onConnect", ON_CONNECT_SIGNATURE, wantRef); - auto obj = reinterpret_cast(result); - auto remoteObj = AniGetNativeRemoteObject(env, obj); - if (remoteObj == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "remoteObj null"); + + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); return nullptr; } + auto remoteObj = etsAbilityObj_->OnConnect(want); TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); return remoteObj; } @@ -218,82 +132,24 @@ sptr EtsServiceExtension::OnConnect(const AAFwk::Want &want, HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnConnect"); Extension::OnConnect(want); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return nullptr; - } - ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); - if (wantRef == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); - return nullptr; - } - ani_long connectCallbackPoint = (ani_long)callbackInfo; - ani_status status = ANI_ERROR; - ani_field callbackField = nullptr; - if ((status = env->Class_FindField(etsObj_->aniCls, "connectCallbackPoint", &callbackField)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return nullptr; - } - if ((status = env->Object_SetField_Long(etsObj_->aniObj, callbackField, connectCallbackPoint)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return nullptr; - } - ani_ref aniRemoteRef = CallObjectMethod(true, "onConnect", ON_CONNECT_SIGNATURE, wantRef); - auto aniRemoteobj = reinterpret_cast(aniRemoteRef); - ani_method method {}; - if ((status = env->Class_FindMethod(etsObj_->aniCls, "checkPromise", CHECK_PROMISE_SIGNATURE, &method)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return nullptr; - } - ani_boolean isPromise = ANI_FALSE; - if ((status = env->Object_CallMethod_Boolean(etsObj_->aniObj, method, &isPromise, aniRemoteobj)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return nullptr; - } - if (!isPromise) { - isAsyncCallback = false; - auto remoteObj = AniGetNativeRemoteObject(env, aniRemoteobj); - if (remoteObj == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null remoteObj"); - } - return remoteObj; - } - return OnConnectInner(env, aniRemoteobj, isAsyncCallback); -} -sptr EtsServiceExtension::OnConnectInner(ani_env *env, ani_object &aniRemoteobj, bool &isAsyncCallback) -{ - ani_status status = ANI_ERROR; - ani_method method {}; - if ((status = env->Class_FindMethod(etsObj_->aniCls, "callPromise", CALL_PROMISE_SIGNATURE, &method)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return nullptr; - } - ani_boolean callResult = ANI_FALSE; - if ((status = env->Object_CallMethod_Boolean(etsObj_->aniObj, method, &callResult, aniRemoteobj)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); return nullptr; } - isAsyncCallback = callResult; - return nullptr; + return etsAbilityObj_->OnConnectCallback(want, callbackInfo, isAsyncCallback); } void EtsServiceExtension::OnDisconnect(const AAFwk::Want &want) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnDisconnect"); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return; - } - ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); - if (wantRef == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); return; } - CallObjectMethod(false, "onDisconnect", ON_DISCONNECT_SIGNATURE, wantRef); + etsAbilityObj_->OnDisconnect(want); TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); } @@ -302,89 +158,28 @@ void EtsServiceExtension::OnDisconnect( { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnDisconnect"); - auto env = etsRuntime_.GetAniEnv(); - if (env) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return; - } - ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); - if (wantRef == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); - return; - } - if (callbackInfo == nullptr) { - isAsyncCallback = false; - OnDisconnect(want); - return; - } - ani_long disconnectCallbackPoint = (ani_long)callbackInfo; - ani_status status = ANI_ERROR; - ani_field field = nullptr; - if ((status = env->Class_FindField(etsObj_->aniCls, "disconnectCallbackPoint", &field)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return; - } - if ((status = env->Object_SetField_Long(etsObj_->aniObj, field, disconnectCallbackPoint)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); return; } - CallObjectMethod(false, "callOnDisconnect", ON_DISCONNECT_SIGNATURE, wantRef); + etsAbilityObj_->OnDisconnectCallback(want, callbackInfo, isAsyncCallback); } void EtsServiceExtension::OnCommand(const AAFwk::Want &want, bool restart, int startId) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnCommand"); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return; - } - ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); - if (wantRef == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); return; } - ani_int iStartId = static_cast(startId); - CallObjectMethod(false, "onRequest", ON_REQUEST_SIGNATURE, wantRef, iStartId); + etsAbilityObj_->OnCommand(want, startId); TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); return; } -ani_ref EtsServiceExtension::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) -{ - HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); - ani_status status = ANI_ERROR; - ani_method method = nullptr; - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); - return nullptr; - } - if ((status = env->Class_FindMethod(etsObj_->aniCls, name, signature, &method)) != ANI_OK) { - return nullptr; - } - if (method == nullptr) { - return nullptr; - } - ani_ref res = nullptr; - va_list args; - if (withResult) { - va_start(args, signature); - if ((status = env->Object_CallMethod_Ref_V(etsObj_->aniObj, method, &res, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - return nullptr; - } - va_end(args); - return res; - } - va_start(args, signature); - if ((status = env->Object_CallMethod_Void_V(etsObj_->aniObj, method, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); - } - va_end(args); - return nullptr; -} void EtsServiceExtension::OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) {} void EtsServiceExtension::ConfigurationUpdated() {} diff --git a/frameworks/ets/ani/service_extension_ability/src/ets_service_extension_object.cpp b/frameworks/ets/ani/service_extension_ability/src/ets_service_extension_object.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b620b675f4679ea2bd33af8f071edf102074f5cb --- /dev/null +++ b/frameworks/ets/ani/service_extension_ability/src/ets_service_extension_object.cpp @@ -0,0 +1,166 @@ +/* + * 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_service_extension_object.h" + +#include +#include + +#include "ets_service_extension_ffi.h" +#include "hilog_tag_wrapper.h" +#include "want_params_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +const char *ETS_FFI_LIBNAME = "libservice_extension_ani.z.so"; +const char *ETS_FFI_REGISTER_FUNCS = "OHOS_ETS_Service_Extension_RegisterFuncs"; +ETSServiceExtensionFuncs *g_etsFFIFuncs = nullptr; + +bool RegisterETSAbilityFuncs() +{ + if (g_etsFFIFuncs != nullptr) { + return true; + } + auto handle = dlopen(ETS_FFI_LIBNAME, RTLD_NOW); + if (!handle) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "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::SERVICE_EXT, "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 ETSServiceExtensionObject::Init(AbilityHandle ability, RuntimeHandle runtime) +{ + if (!RegisterETSAbilityFuncs()) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "RegisterETSAbilityFuncs failed"); + return false; + } + + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->CreateEtsFFI == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or CreateEtsFFI"); + return false; + } + ffi_ = g_etsFFIFuncs->CreateEtsFFI(ability, runtime); + return true; +} + +ETSServiceExtensionObject::~ETSServiceExtensionObject() +{ + if (ffi_ != nullptr) { + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->DeleteEtsFFI == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or DeleteEtsFFI"); + return; + } + g_etsFFIFuncs->DeleteEtsFFI(ffi_); + } +} + +bool ETSServiceExtensionObject::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::SERVICE_EXT, "null g_etsFFIFuncs or LoadModule"); + return false; + } + return g_etsFFIFuncs->LoadModule(ffi_, moduleName, modulePath, hapPath, + esmodule, useCommonChunk, srcEntrance); +} + +void ETSServiceExtensionObject::OnStart(const AAFwk::Want &want) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnStart == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or OnStart"); + return; + } + g_etsFFIFuncs->OnStart(ffi_, want); +} + +void ETSServiceExtensionObject::OnStop() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnStop == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or OnStop"); + return; + } + g_etsFFIFuncs->OnStop(ffi_); +} + +sptr ETSServiceExtensionObject::OnConnect(const AAFwk::Want &want) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnConnect == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or OnConnect"); + return nullptr; + } + return g_etsFFIFuncs->OnConnect(ffi_, want); +} + +sptr ETSServiceExtensionObject::OnConnectCallback(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, bool &isAsyncCallback) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnConnectCallback == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or OnConnectCallback"); + return nullptr; + } + return g_etsFFIFuncs->OnConnectCallback(ffi_, want, callbackInfo, isAsyncCallback); +} + +void ETSServiceExtensionObject::OnDisconnect(const AAFwk::Want &want) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnDisconnect == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or OnDisconnect"); + return; + } + g_etsFFIFuncs->OnDisconnect(ffi_, want); +} + +void ETSServiceExtensionObject::OnDisconnectCallback(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsyncCallback) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnDisconnectCallback == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or OnDisconnectCallback"); + return; + } + g_etsFFIFuncs->OnDisconnectCallback(ffi_, want, callbackInfo, isAsyncCallback); +} + +void ETSServiceExtensionObject::OnCommand(const AAFwk::Want &want, int startId) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnCommand == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null g_etsFFIFuncs or OnCommand"); + return; + } + g_etsFFIFuncs->OnCommand(ffi_, want, startId); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/service_extension_ffi/BUILD.gn b/frameworks/ets/ani/service_extension_ffi/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..75e1ab6b947653d09408ad0dc9ef3dcb52120d90 --- /dev/null +++ b/frameworks/ets/ani/service_extension_ffi/BUILD.gn @@ -0,0 +1,91 @@ +# 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") + +config("ani_service_extension_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_shared_library("service_extension_ani") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "./include", + "${ability_runtime_path}/ets_environment/interfaces/inner_api", + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", + "${ability_runtime_path}/frameworks/ets/ani/service_extension_ability/include", + "${ability_runtime_path}/interfaces/kits/native/ability/native", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime", + "${ability_runtime_path}/utils/global/freeze/include", + ] + + public_configs = [ ":ani_service_extension_config" ] + + sources = [ + "src/ets_service_extension_ffi.cpp", + ] + + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + deps = [ + "${ability_runtime_innerkits_path}/ability_manager:ability_manager", + "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_native_path}/appkit:app_context", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + ] + + external_deps = [ + "ability_base:configuration", + "ability_base:want", + "ability_base:zuri", + "bundle_framework:libappexecfwk_common", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "eventhandler:libeventhandler", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "ipc:ipc_napi", + "ipc:rpc_ani", + "napi:ace_napi", + "runtime_core:ani", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + if (ability_runtime_graphics) { + external_deps += [ + "image_framework:image", + "window_manager:libdm", + "window_manager:libwm", + "window_manager:libwsutils", + ] + } + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/frameworks/ets/ani/service_extension_ffi/include/ets_service_extension_ffi.h b/frameworks/ets/ani/service_extension_ffi/include/ets_service_extension_ffi.h new file mode 100644 index 0000000000000000000000000000000000000000..b353bc20d64e4b7a0681409b01c3332dd4dca17e --- /dev/null +++ b/frameworks/ets/ani/service_extension_ffi/include/ets_service_extension_ffi.h @@ -0,0 +1,126 @@ +/* + * 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_SERVICE_EXTENSION_FFI_H +#define OHOS_ABILITY_RUNTIME_ETS_SERVICE_EXTENSION_FFI_H + +#include + +#ifdef WINDOWS_PLATFORM +#define ETS_EXPORT __declspec(dllexport) +#else +#define ETS_EXPORT __attribute__((visibility("default"))) +#endif + +namespace OHOS { +class IRemoteObject; +template class sptr; +namespace AppExecFwk { +class OHOSApplication; +template class AbilityTransactionCallbackInfo; +} + +namespace AAFwk { +class Want; +struct LaunchParam; +} +} // namespace OHOS + +using FFIHandle = void *; +using AbilityHandle = void *; +using RuntimeHandle = void *; + +extern "C" { +struct ETSServiceExtensionFuncs { + 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; + void (*OnStart)(FFIHandle ffi, const OHOS::AAFwk::Want &want) = nullptr; + void (*OnStop)(FFIHandle ffi) = nullptr; + OHOS::sptr (*OnConnect)(FFIHandle ffi, const OHOS::AAFwk::Want &want) = nullptr; + OHOS::sptr (*OnConnectCallback)(FFIHandle ffi, const OHOS::AAFwk::Want &want, + OHOS::AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, + bool &isAsyncCallback) = nullptr; + void (*OnDisconnect)(FFIHandle ffi, const OHOS::AAFwk::Want &want) = nullptr; + void (*OnDisconnectCallback)(FFIHandle ffi, const OHOS::AAFwk::Want &want, + OHOS::AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback) = nullptr; + void (*OnCommand)(FFIHandle ffi, const OHOS::AAFwk::Want &want, int startId) = nullptr; +}; +} + +class __ani_ref; +using ani_ref = __ani_ref *; +class __ani_object; +using ani_object = __ani_object *; +struct __ani_env; +using ani_env = __ani_env; + +namespace OHOS { +namespace EtsEnv { +struct ETSNativeReference; +} + +namespace AbilityRuntime { +class EtsServiceExtension; +class ETSRuntime; + +class EtsServiceExtensionFFI { +public: + EtsServiceExtensionFFI(AbilityHandle ability, RuntimeHandle runtime); + ~EtsServiceExtensionFFI(); + + static ETSServiceExtensionFuncs *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 void FFIOnStart(FFIHandle ffi, const OHOS::AAFwk::Want &want); + static void FFIOnStop(FFIHandle ffi); + static OHOS::sptr FFIOnConnect(FFIHandle ffi, const OHOS::AAFwk::Want &want); + static OHOS::sptr FFIOnConnectCallback(FFIHandle ffi, const OHOS::AAFwk::Want &want, + OHOS::AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, + bool &isAsyncCallback); + static void FFIOnDisconnect(FFIHandle ffi, const OHOS::AAFwk::Want &want); + static void FFIOnDisconnectCallback(FFIHandle ffi, const OHOS::AAFwk::Want &want, + OHOS::AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback); + static void FFIOnCommand(FFIHandle ffi, const OHOS::AAFwk::Want &want, int startId); + static void DisconnectPromiseCallback(ani_env *env, ani_object aniObj); + static void ConnectPromiseCallback(ani_env *env, ani_object aniObj, ani_object obj); + + bool LoadModule(const std::string &moduleName, const std::string &modulePath, + const std::string &hapPath, bool esmodule, bool useCommonChunk, const std::string &srcEntrance); + void OnStart(const AAFwk::Want &want); + void OnStop(); + sptr OnConnect(const OHOS::AAFwk::Want &want); + sptr OnConnectCallback(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, bool &isAsyncCallback); + void OnDisconnect(const OHOS::AAFwk::Want &want); + void OnDisconnectCallback(const AAFwk::Want &want, AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback); + void OnCommand(const AAFwk::Want &want, int startId); + +private: + ani_ref CallObjectMethod(bool withResult, const char *name, const char *signature, ...); + sptr OnConnectInner(ani_env *env, ani_object &aniRemoteobj, bool &isAsyncCallback); + AbilityRuntime::EtsServiceExtension *ability_ = nullptr; + AbilityRuntime::ETSRuntime *runtime_ = nullptr; + std::shared_ptr etsAbilityObj_ = nullptr; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_SERVICE_EXTENSION_FFI_H diff --git a/frameworks/ets/ani/service_extension_ffi/src/ets_service_extension_ffi.cpp b/frameworks/ets/ani/service_extension_ffi/src/ets_service_extension_ffi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7aa0d90982b24575973442cb0a4a3f2bd7ebd046 --- /dev/null +++ b/frameworks/ets/ani/service_extension_ffi/src/ets_service_extension_ffi.cpp @@ -0,0 +1,508 @@ +/* + * 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_service_extension_ffi.h" + +#include +#include +#include + +#include "ability_info.h" +#include "ability_manager_client.h" +#include "ani_common_want.h" +#include "ani_remote_object.h" +#include "configuration_utils.h" +#include "ets_envsetup.h" +#include "ets_runtime.h" +#include "ets_service_extension.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "js_service_extension_context.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +constexpr const char *CLASSNAME_SERVICE_ABILITY = + "L@ohos/app/ability/ServiceExtensionAbility/ServiceExtensionAbility;"; +constexpr const char *NATIVE_ONCONNECT_CALLBACK_SIGNATURE = "L@ohos/rpc/rpc/RemoteObject;:Z"; +constexpr const char *ON_CREATE_SIGNATURE = "L@ohos/app/ability/Want/Want;:V"; +constexpr const char *VOID_SIGNATURE = ":V"; +constexpr const char *ON_CONNECT_SIGNATURE = "L@ohos/app/ability/Want/Want;:Lstd/core/Object;"; +constexpr const char *CHECK_PROMISE_SIGNATURE = "Lstd/core/Object;:Z"; +constexpr const char *CALL_PROMISE_SIGNATURE = "Lstd/core/Object;:Z"; +constexpr const char *ON_DISCONNECT_SIGNATURE = "L@ohos/app/ability/Want/Want;:V"; +constexpr const char *ON_REQUEST_SIGNATURE = "L@ohos/app/ability/Want/Want;D:V"; +} // namespace + +void EtsServiceExtensionFFI::DisconnectPromiseCallback(ani_env *env, ani_object aniObj) +{ + TAG_LOGD(AAFwkTag::SERVICE_EXT, "DisconnectPromiseCallback"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_long disconnectCallbackPoint = 0; + ani_status status = ANI_ERROR; + if ((status = env->Object_GetFieldByName_Long(aniObj, "disconnectCallbackPoint", &disconnectCallbackPoint)) != + ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + auto *callbackInfo = reinterpret_cast *>(disconnectCallbackPoint); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null callbackInfo"); + return; + } + callbackInfo->Call(); + AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo); +} + +void EtsServiceExtensionFFI::ConnectPromiseCallback(ani_env *env, ani_object aniObj, ani_object obj) +{ + TAG_LOGD(AAFwkTag::SERVICE_EXT, "ConnectPromiseCallback"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_long connectCallbackPoint = 0; + ani_status status = ANI_ERROR; + if ((status = env->Object_GetFieldByName_Long(aniObj, "connectCallbackPoint", &connectCallbackPoint)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + auto remoteObject = AniGetNativeRemoteObject(env, obj); + if (remoteObject == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null remoteObject"); + } + auto *callbackInfo = + reinterpret_cast> *>(connectCallbackPoint); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null callbackInfo"); + return; + } + + callbackInfo->Call(remoteObject); + AppExecFwk::AbilityTransactionCallbackInfo>::Destroy(callbackInfo); +} + +EtsServiceExtensionFFI::EtsServiceExtensionFFI(AbilityHandle ability, RuntimeHandle runtime) +{ + ability_ = reinterpret_cast(ability); + runtime_ = reinterpret_cast(runtime); +} + +EtsServiceExtensionFFI::~EtsServiceExtensionFFI() +{ +} + +bool EtsServiceExtensionFFI::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::SERVICE_EXT, "null runtime_"); + return false; + } + + etsAbilityObj_ = runtime_->LoadModule(moduleName, modulePath, hapPath, esmodule, useCommonChunk, srcEntrance); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsAbilityObj_"); + return false; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return false; + } + std::array functions = { + ani_native_function { + "nativeOnDisconnectCallback", VOID_SIGNATURE, + reinterpret_cast(EtsServiceExtensionFFI::DisconnectPromiseCallback) }, + ani_native_function { "nativeOnConnectCallback", NATIVE_ONCONNECT_CALLBACK_SIGNATURE, + reinterpret_cast(EtsServiceExtensionFFI::ConnectPromiseCallback) }, + }; + ani_class cls = nullptr; + ani_status status = ANI_ERROR; + if ((status = env->FindClass(CLASSNAME_SERVICE_ABILITY, &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status: %{public}d", status); + return false; + } + if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "Class_BindNativeMethods is fail %{public}d", status); + return false; + } + return true; +} + +void EtsServiceExtensionFFI::OnStart(const AAFwk::Want &want) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null runtime_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + + CallObjectMethod(false, "onCreate", ON_CREATE_SIGNATURE, wantRef); +} + +void EtsServiceExtensionFFI::OnStop() +{ + CallObjectMethod(false, "onDestroy", VOID_SIGNATURE); +} + +sptr EtsServiceExtensionFFI::OnConnect(const OHOS::AAFwk::Want &want) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null runtime_"); + return nullptr; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return nullptr; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return nullptr; + } + ani_ref result = CallObjectMethod(true, "onConnect", ON_CONNECT_SIGNATURE, wantRef); + auto obj = reinterpret_cast(result); + auto remoteObj = AniGetNativeRemoteObject(env, obj); + if (remoteObj == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "remoteObj null"); + return nullptr; + } + return remoteObj; +} + +sptr EtsServiceExtensionFFI::OnConnectCallback(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, bool &isAsyncCallback) +{ + if (runtime_ == nullptr || etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null runtime_ or etsAbilityObj_"); + return nullptr; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return nullptr; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return nullptr; + } + ani_long connectCallbackPoint = (ani_long)callbackInfo; + ani_status status = ANI_ERROR; + ani_field callbackField = nullptr; + if ((status = env->Class_FindField(etsAbilityObj_->aniCls, "connectCallbackPoint", &callbackField)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + if ((status = env->Object_SetField_Long(etsAbilityObj_->aniObj, callbackField, connectCallbackPoint)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + ani_ref aniRemoteRef = CallObjectMethod(true, "onConnect", ON_CONNECT_SIGNATURE, wantRef); + auto aniRemoteobj = reinterpret_cast(aniRemoteRef); + ani_method method {}; + if ((status = env->Class_FindMethod(etsAbilityObj_->aniCls, "checkPromise", + CHECK_PROMISE_SIGNATURE, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + ani_boolean isPromise = ANI_FALSE; + if ((status = env->Object_CallMethod_Boolean(etsAbilityObj_->aniObj, method, &isPromise, aniRemoteobj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + if (!isPromise) { + isAsyncCallback = false; + auto remoteObj = AniGetNativeRemoteObject(env, aniRemoteobj); + if (remoteObj == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null remoteObj"); + } + return remoteObj; + } + return OnConnectInner(env, aniRemoteobj, isAsyncCallback); +} + +sptr EtsServiceExtensionFFI::OnConnectInner(ani_env *env, ani_object &aniRemoteobj, + bool &isAsyncCallback) +{ + ani_status status = ANI_ERROR; + ani_method method {}; + if ((status = env->Class_FindMethod(etsAbilityObj_->aniCls, "callPromise", + CALL_PROMISE_SIGNATURE, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + ani_boolean callResult = ANI_FALSE; + if ((status = env->Object_CallMethod_Boolean(etsAbilityObj_->aniObj, method, + &callResult, aniRemoteobj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + isAsyncCallback = callResult; + return nullptr; +} + +void EtsServiceExtensionFFI::OnDisconnect(const OHOS::AAFwk::Want &want) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null runtime_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + CallObjectMethod(false, "onDisconnect", ON_DISCONNECT_SIGNATURE, wantRef); +} + +void EtsServiceExtensionFFI::OnDisconnectCallback(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback) +{ + if (runtime_ == nullptr || etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null runtime_ or etsAbilityObj_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + if (callbackInfo == nullptr) { + isAsyncCallback = false; + OnDisconnect(want); + return; + } + ani_long disconnectCallbackPoint = (ani_long)callbackInfo; + ani_status status = ANI_ERROR; + ani_field field = nullptr; + if ((status = env->Class_FindField(etsAbilityObj_->aniCls, "disconnectCallbackPoint", &field)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + if ((status = env->Object_SetField_Long(etsAbilityObj_->aniObj, field, disconnectCallbackPoint)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + CallObjectMethod(false, "callOnDisconnect", ON_DISCONNECT_SIGNATURE, wantRef); +} + +void EtsServiceExtensionFFI::OnCommand(const AAFwk::Want &want, int startId) +{ + if (runtime_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null runtime_"); + return; + } + auto env = runtime_->GetAniEnv(); + if (env) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + ani_int iStartId = static_cast(startId); + CallObjectMethod(false, "onRequest", ON_REQUEST_SIGNATURE, wantRef, iStartId); +} + +ani_ref EtsServiceExtensionFFI::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); + if (runtime_ == nullptr || etsAbilityObj_ != nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null runtime_"); + return nullptr; + } + ani_status status = ANI_ERROR; + ani_method method = nullptr; + auto env = runtime_->GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return nullptr; + } + if ((status = env->Class_FindMethod(etsAbilityObj_->aniCls, name, signature, &method)) != ANI_OK) { + return nullptr; + } + if (method == nullptr) { + return nullptr; + } + ani_ref res = nullptr; + va_list args; + if (withResult) { + va_start(args, signature); + if ((status = env->Object_CallMethod_Ref_V(etsAbilityObj_->aniObj, method, &res, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + va_end(args); + return res; + } + va_start(args, signature); + if ((status = env->Object_CallMethod_Void_V(etsAbilityObj_->aniObj, method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + } + va_end(args); + return nullptr; +} + +FFIHandle EtsServiceExtensionFFI::FFICreate(AbilityHandle ability, RuntimeHandle runtime) +{ + return new (std::nothrow) EtsServiceExtensionFFI(ability, runtime); +} + +void EtsServiceExtensionFFI::FFIDelete(FFIHandle ffi) +{ + if (ffi != nullptr) { + delete reinterpret_cast(ffi); + } +} + +bool EtsServiceExtensionFFI::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_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return false; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + return pFFI->LoadModule(moduleName, modulePath, hapPath, esmodule, useCommonChunk, srcEntrance); +} + +void EtsServiceExtensionFFI::FFIOnStart(FFIHandle ffi, const OHOS::AAFwk::Want &want) +{ + if (ffi == nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnStart(want); +} + +void EtsServiceExtensionFFI::FFIOnStop(FFIHandle ffi) +{ + if (ffi == nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + pFFI->OnStop(); +} + +OHOS::sptr EtsServiceExtensionFFI::FFIOnConnect(FFIHandle ffi, const OHOS::AAFwk::Want &want) +{ + if (ffi == nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return nullptr; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnConnect(want); +} + +OHOS::sptr EtsServiceExtensionFFI::FFIOnConnectCallback(FFIHandle ffi, + const OHOS::AAFwk::Want &want, + OHOS::AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, + bool &isAsyncCallback) +{ + if (ffi == nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return nullptr; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnConnectCallback(want, callbackInfo, isAsyncCallback); +} + +void EtsServiceExtensionFFI::FFIOnDisconnect(FFIHandle ffi, const OHOS::AAFwk::Want &want) +{ + if (ffi == nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnDisconnect(want); +} + +void EtsServiceExtensionFFI::FFIOnDisconnectCallback(FFIHandle ffi, const OHOS::AAFwk::Want &want, + OHOS::AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsyncCallback) +{ + if (ffi == nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnDisconnectCallback(want, callbackInfo, isAsyncCallback); +} + +void EtsServiceExtensionFFI::FFIOnCommand(FFIHandle ffi, const OHOS::AAFwk::Want &want, int startId) +{ + if (ffi == nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "null ffi"); + return; + } + EtsServiceExtensionFFI *pFFI = reinterpret_cast(ffi); + return pFFI->OnCommand(want, startId); +} + +ETSServiceExtensionFuncs *EtsServiceExtensionFFI::RegisterFuncs() +{ + static ETSServiceExtensionFuncs funcs = { + .CreateEtsFFI = EtsServiceExtensionFFI::FFICreate, + .DeleteEtsFFI = EtsServiceExtensionFFI::FFIDelete, + .LoadModule = EtsServiceExtensionFFI::FFILoadModule, + .OnStart = EtsServiceExtensionFFI::FFIOnStart, + .OnStop = EtsServiceExtensionFFI::FFIOnStop, + .OnConnect = EtsServiceExtensionFFI::FFIOnConnect, + .OnConnectCallback = EtsServiceExtensionFFI::FFIOnConnectCallback, + .OnDisconnect = EtsServiceExtensionFFI::FFIOnDisconnect, + .OnDisconnectCallback = EtsServiceExtensionFFI::FFIOnDisconnectCallback, + .OnCommand = EtsServiceExtensionFFI::FFIOnCommand, + }; + + return &funcs; +} +} // namespace AbilityRuntime +} // namespace OHOS + +ETS_EXPORT extern "C" ETSServiceExtensionFuncs *OHOS_ETS_Service_Extension_RegisterFuncs() +{ + return OHOS::AbilityRuntime::EtsServiceExtensionFFI::RegisterFuncs(); +} \ No newline at end of file diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index e68e098980d4181eb36f2f5058bc8c61f096b3c2..312baa1104fb5d7b659b4ef0a723df4c6cf6b35c 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -1172,7 +1172,7 @@ ohos_shared_library("service_extension") { defines = [ "AMS_LOG_TAG = \"Ability\"" ] defines += [ "AMS_LOG_DOMAIN = 0xD001300" ] include_dirs = [ - "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/service_extension_ffi/include", "${ability_runtime_path}/frameworks/ets/ani/service_extension_ability/include", "${ability_runtime_path}/interfaces/kits/native/ability/native", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime", @@ -1185,6 +1185,7 @@ ohos_shared_library("service_extension") { "${ability_runtime_native_path}/ability/native/service_extension.cpp", "${ability_runtime_native_path}/appkit/ability_runtime/service_extension_context.cpp", "${ability_runtime_path}/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp", + "${ability_runtime_path}/frameworks/ets/ani/service_extension_ability/src/ets_service_extension_object.cpp", ] deps = [ @@ -1201,7 +1202,6 @@ ohos_shared_library("service_extension") { "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/insight_intent/insight_intent_context:insightintentcontext", "${ability_runtime_path}/utils/global/freeze:freeze_util", - "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] external_deps = [ diff --git a/frameworks/native/appkit/BUILD.gn b/frameworks/native/appkit/BUILD.gn index ebb0dc003b6e85a297bd22606425801a45c44ee9..18edce48e2087eebf132d52a0ed68c7344b72383 100644 --- a/frameworks/native/appkit/BUILD.gn +++ b/frameworks/native/appkit/BUILD.gn @@ -76,7 +76,7 @@ config("appkit_public_config") { ohos_shared_library("appkit_native") { include_dirs = [ "native", - "${ability_runtime_path}/ets_environment/interfaces/inner_api", + "${ability_runtime_path}/frameworks/ets/ani/ability_stage_ffi/include", "${ability_runtime_path}/interfaces/inner_api/error_utils/include", "${ability_runtime_path}/interfaces/kits/native/appkit", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_bundle_manager_helper", @@ -107,7 +107,7 @@ ohos_shared_library("appkit_native") { sources = [ "${ability_runtime_native_path}/appkit/ability_runtime/app/ability_stage.cpp", "${ability_runtime_native_path}/appkit/ability_runtime/app/ets_ability_stage.cpp", - "${ability_runtime_native_path}/appkit/ability_runtime/app/ets_ability_stage_context.cpp", + "${ability_runtime_native_path}/appkit/ability_runtime/app/ets_ability_stage_object.cpp", "${ability_runtime_native_path}/appkit/ability_runtime/app/js_ability_stage.cpp", "${ability_runtime_native_path}/appkit/ability_runtime/app/js_ability_stage_context.cpp", "${ability_runtime_native_path}/appkit/app/ability_record_mgr.cpp", @@ -171,8 +171,6 @@ ohos_shared_library("appkit_native") { "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:app_context_utils", "${ability_runtime_native_path}/appkit:appkit_manager_helper", - "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", - "${ability_runtime_path}/ets_environment/frameworks/ets_environment:ets_environment", "${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment", "${ability_runtime_path}/utils/global/freeze:freeze_util", "${ability_runtime_services_path}/common:app_util", @@ -214,7 +212,6 @@ ohos_shared_library("appkit_native") { "napi:ace_napi", "preferences:native_preferences", "resource_management:global_resmgr", - "runtime_core:ani", "safwk:system_ability_fwk", "samgr:samgr_proxy", "storage_service:storage_manager_acl", @@ -410,7 +407,6 @@ ohos_shared_library("app_context_utils") { branch_protector_ret = "pac_ret" include_dirs = [ - "${ability_runtime_path}/frameworks/ets/ani/enum_convert", "${ability_runtime_napi_path}/ability_auto_startup_callback", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", @@ -421,8 +417,6 @@ ohos_shared_library("app_context_utils") { public_configs = [ ":appkit_public_config" ] sources = [ - "ability_runtime/context/ets_application_context_utils.cpp", - "ability_runtime/context/ets_context_utils.cpp", "ability_runtime/context/js_application_context_utils.cpp", "ability_runtime/context/js_context_utils.cpp", "ability_runtime/context/js_resource_manager_utils.cpp", @@ -442,7 +436,6 @@ ohos_shared_library("app_context_utils") { "${ability_runtime_native_path}/ability/native:auto_startup_callback", "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:application_context_manager", - "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] external_deps = [ @@ -451,7 +444,6 @@ ohos_shared_library("app_context_utils") { "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", - "bundle_framework:bms_ani_common", "bundle_framework:libappexecfwk_common", "c_utils:utils", "hilog:libhilog", @@ -461,8 +453,6 @@ ohos_shared_library("app_context_utils") { "napi:ace_napi", "resource_management:global_resmgr", "resource_management:resmgr_napi_core", - "resource_management:resourceManager_ani", - "runtime_core:ani", ] public_external_deps = [ "ability_base:configuration" ] if (ability_runtime_graphics) { diff --git a/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp b/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp index b90646835398acdc78aed26bc0f6e0308a4588e8..e640f7227d3aa850694b45669a684964ad3e0870 100644 --- a/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp +++ b/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp @@ -18,8 +18,6 @@ #include "freeze_util.h" #include "hilog_tag_wrapper.h" #include "configuration_convertor.h" -#include "ets_ability_stage_context.h" -#include "ani_common_configuration.h" #include "ohos_application.h" #include "startup_manager.h" #include "hitrace_meter.h" @@ -73,18 +71,21 @@ std::shared_ptr ETSAbilityStage::Create( srcPath.append(".abc"); } } - std::unique_ptr moduleObj; - if (!hapModuleInfo.srcEntrance.empty()) { - TAG_LOGD(AAFwkTag::APPKIT, "entry path: %{public}s", hapModuleInfo.srcEntrance.c_str()); - moduleObj = etsRuntime.LoadModule(moduleName, srcPath, hapModuleInfo.hapPath, - hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, commonChunkFlag, - hapModuleInfo.srcEntrance); + + etsAbilityStageObj_ = std::make_shared(); + if (etsAbilityStageObj_->Init(reinterpret_cast(this), reinterpret_cast(&etsRuntime))) { + if (!hapModuleInfo.srcEntrance.empty()) { + TAG_LOGD(AAFwkTag::APPKIT, "entry path: %{public}s", hapModuleInfo.srcEntrance.c_str()); + etsAbilityStageObj_->LoadModule(moduleName, srcPath, hapModuleInfo.hapPath, + hapModuleInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE, commonChunkFlag, + hapModuleInfo.srcEntrance); + } } - return std::make_shared(etsRuntime, std::move(moduleObj)); + return std::make_shared(etsRuntime); } -ETSAbilityStage::ETSAbilityStage(ETSRuntime & etsRuntime, std::unique_ptr&& etsAbilityStageObj) - : etsRuntime_(etsRuntime), etsAbilityStageObj_(std::move(etsAbilityStageObj)) +ETSAbilityStage::ETSAbilityStage(ETSRuntime & etsRuntime) + : etsRuntime_(etsRuntime) {} ETSAbilityStage::~ETSAbilityStage() @@ -104,7 +105,12 @@ void ETSAbilityStage::Init(const std::shared_ptr &context, TAG_LOGE(AAFwkTag::APPKIT, "null stage"); return; } - SetEtsAbilityStage(context); + + if (etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null etsAbilityStageObj_"); + return; + } + etsAbilityStageObj_->SetEtsAbilityStage(context); } void ETSAbilityStage::OnCreate(const AAFwk::Want &want) const @@ -112,8 +118,12 @@ void ETSAbilityStage::OnCreate(const AAFwk::Want &want) const TAG_LOGD(AAFwkTag::APPKIT, "OnCreate called"); AbilityStage::OnCreate(want); + if (etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null etsAbilityStageObj_"); + return; + } FreezeUtil::GetInstance().AddAppLifecycleEvent(0, "ETSAbilityStage::OnCreate begin"); - CallObjectMethod(false, "onCreate", ":V"); + etsAbilityStageObj_->OnCreate(); FreezeUtil::GetInstance().AddAppLifecycleEvent(0, "ETSAbilityStage::OnCreate end"); auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); @@ -124,18 +134,21 @@ void ETSAbilityStage::OnCreate(const AAFwk::Want &want) const void ETSAbilityStage::OnDestroy() const { + if (etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null etsAbilityStageObj_"); + return; + } TAG_LOGD(AAFwkTag::APPKIT, "OnDestroy called"); AbilityStage::OnDestroy(); - CallObjectMethod(false, "onDestroy", ":V"); + etsAbilityStageObj_->OnDestroy(); } void ETSAbilityStage::OnConfigurationUpdated(const AppExecFwk::Configuration& configuration) { TAG_LOGD(AAFwkTag::APPKIT, "OnConfigurationUpdated called"); AbilityStage::OnConfigurationUpdated(configuration); - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "env nullptr"); + if (etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null etsAbilityStageObj_"); return; } auto application = application_.lock(); @@ -148,55 +161,7 @@ void ETSAbilityStage::OnConfigurationUpdated(const AppExecFwk::Configuration& co TAG_LOGE(AAFwkTag::APPKIT, "null fullConfig"); return; } - ETSAbilityStageContext::ConfigurationUpdated(env, fullConfig); - ani_object configObj = OHOS::AppExecFwk::WrapConfiguration(env, configuration); - if (configObj == nullptr) { - TAG_LOGE(AAFwkTag::APPKIT, "null configObj"); - return; - } - CallObjectMethod(false, "onConfigurationUpdate", "L@ohos/app/ability/Configuration/Configuration;:V", configObj); -} - -bool ETSAbilityStage::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) const -{ - HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); - TAG_LOGD(AAFwkTag::ABILITY, "CallObjectMethod: name:%{public}s", name); - if (etsAbilityStageObj_ == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "etsAbilityStageObj_ nullptr"); - return false; - } - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "env nullptr"); - return false; - } - ani_status status = ANI_OK; - ani_method method = nullptr; - if ((status = env->Class_FindMethod(etsAbilityStageObj_->aniCls, name, signature, &method)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "status: %{public}d", status); - return false; - } - env->ResetError(); - if (withResult) { - ani_boolean res = ANI_FALSE; - va_list args; - va_start(args, signature); - if ((status = env->Object_CallMethod_Boolean(etsAbilityStageObj_->aniObj, method, &res, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "status: %{public}d", status); - etsRuntime_.HandleUncaughtError(); - } - va_end(args); - return res; - } - va_list args; - va_start(args, signature); - if ((status = env->Object_CallMethod_Void_V(etsAbilityStageObj_->aniObj, method, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "status: %{public}d", status); - etsRuntime_.HandleUncaughtError(); - return false; - } - va_end(args); - return false; + etsAbilityStageObj_->OnConfigurationUpdated(fullConfig, configuration); } std::shared_ptr ETSAbilityStage::CreateStageProperty() const @@ -228,41 +193,5 @@ std::string ETSAbilityStage::GetHapModuleProp(const std::string &propName) const TAG_LOGD(AAFwkTag::APPKIT, "name = %{public}s", propName.c_str()); return std::string(); } - -void ETSAbilityStage::SetEtsAbilityStage(const std::shared_ptr &context) -{ - if (context == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "context nullptr"); - return; - } - auto env = etsRuntime_.GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "env nullptr"); - return; - } - - ani_object stageCtxObj = ETSAbilityStageContext::CreateEtsAbilityStageContext(env, context); - if (stageCtxObj == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "CreateEtsAbilityStageContext failed"); - return; - } - - ani_status status = ANI_OK; - ani_field contextField; - status = env->Class_FindField(etsAbilityStageObj_->aniCls, "context", &contextField); - if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "Class_GetField context failed"); - return; - } - ani_ref stageCtxObjRef = nullptr; - if (env->GlobalReference_Create(stageCtxObj, &stageCtxObjRef) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "GlobalReference_Create stageCtxObj failed"); - return; - } - if (env->Object_SetField_Ref(etsAbilityStageObj_->aniObj, contextField, stageCtxObjRef) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "Object_SetField_Ref stageCtxObj failed"); - } -} - } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/appkit/ability_runtime/app/ets_ability_stage_object.cpp b/frameworks/native/appkit/ability_runtime/app/ets_ability_stage_object.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a376cd3089bab5f77a0eeda7692604ab0ccec99 --- /dev/null +++ b/frameworks/native/appkit/ability_runtime/app/ets_ability_stage_object.cpp @@ -0,0 +1,135 @@ +/* + * 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_stage_object.h" + +#include +#include + +#include "ets_ability_stage_ffi.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +const char *ETS_FFI_LIBNAME = "libability_stage_ani.z.so"; +const char *ETS_FFI_REGISTER_FUNCS = "OHOS_ETS_Ability_Stage_RegisterFuncs"; +ETSAbilityStageFuncs *g_etsFFIFuncs = nullptr; + +bool RegisterETSAbilityStageFuncs() +{ + if (g_etsFFIFuncs != nullptr) { + return true; + } + auto handle = dlopen(ETS_FFI_LIBNAME, RTLD_NOW); + if (!handle) { + TAG_LOGE(AAFwkTag::APPKIT, "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::APPKIT, "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 + +ETSAbilityStageObject::~ETSAbilityStageObject() +{ + if (ffi_ != nullptr) { + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->DeleteEtsFFI == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null g_etsFFIFuncs or DeleteEtsFFI"); + return; + } + g_etsFFIFuncs->DeleteEtsFFI(ffi_); + } +} + +bool ETSAbilityStageObject::Init(StageHandle ability, RuntimeHandle runtime) +{ + if (!RegisterETSAbilityStageFuncs()) { + TAG_LOGE(AAFwkTag::APPKIT, "RegisterETSAbilityStageFuncs failed"); + return false; + } + + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->CreateEtsFFI == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null g_etsFFIFuncs or CreateEtsFFI"); + return false; + } + ffi_ = g_etsFFIFuncs->CreateEtsFFI(ability, runtime); + return true; + +} + +bool ETSAbilityStageObject::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::APPKIT, "null g_etsFFIFuncs or LoadModule"); + return false; + } + return g_etsFFIFuncs->LoadModule(ffi_, moduleName, modulePath, hapPath, + esmodule, useCommonChunk, srcEntrance); +} + +void ETSAbilityStageObject::OnCreate() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnCreate == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null g_etsFFIFuncs or OnStart"); + return; + } + g_etsFFIFuncs->OnCreate(ffi_); +} + +void ETSAbilityStageObject::OnDestroy() +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnDestroy == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null g_etsFFIFuncs or OnDestroy"); + return; + } + g_etsFFIFuncs->OnDestroy(ffi_); +} + +void ETSAbilityStageObject::OnConfigurationUpdated(const std::shared_ptr &fullConfig, + const AppExecFwk::Configuration &configuration) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->OnConfigurationUpdated == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null g_etsFFIFuncs or OnConfigurationUpdated"); + return; + } + g_etsFFIFuncs->OnConfigurationUpdated(ffi_, fullConfig, configuration); +} + +void ETSAbilityStageObject::SetEtsAbilityStage(const std::shared_ptr &context) +{ + if (g_etsFFIFuncs == nullptr || + g_etsFFIFuncs->SetEtsAbilityStage == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null g_etsFFIFuncs or SetEtsAbilityStage"); + return; + } + g_etsFFIFuncs->SetEtsAbilityStage(ffi_, context); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_api/runtime/BUILD.gn b/interfaces/inner_api/runtime/BUILD.gn index 4e41d87d2f18e0b9c9f7762c195e7450550ccc6d..cde7d594405194de81072a2ced8388dddd0910b6 100644 --- a/interfaces/inner_api/runtime/BUILD.gn +++ b/interfaces/inner_api/runtime/BUILD.gn @@ -62,8 +62,6 @@ ohos_shared_library("runtime") { sources = [ "${ability_runtime_native_path}/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp", - "${ability_runtime_native_path}/runtime/ets_error_utils.cpp", - "${ability_runtime_native_path}/runtime/ets_data_struct_converter.cpp", "${ability_runtime_native_path}/runtime/ets_runtime.cpp", "${ability_runtime_native_path}/runtime/hdc_register.cpp", "${ability_runtime_native_path}/runtime/js_app_process_state.cpp", @@ -126,7 +124,6 @@ ohos_shared_library("runtime") { "ipc:ipc_core", "napi:ace_napi", "resource_management:global_resmgr", - "runtime_core:ani", "samgr:samgr_proxy", "zlib:shared_libz", "faultloggerd:libfaultloggerd", diff --git a/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h b/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h index 8d56d08942fa6d6a53cc894432c76b96b2706792..545c7e0480d667a135de1cb082c150ea092c4939 100644 --- a/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h +++ b/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h @@ -29,12 +29,13 @@ namespace OHOS { namespace AbilityRuntime { +class ETSAbilityStageObject; class ETSAbilityStage : public AbilityStage { public: static std::shared_ptr Create( const std::unique_ptr& runtime, const AppExecFwk::HapModuleInfo& hapModuleInfo); - ETSAbilityStage(ETSRuntime& etsRuntime, std::unique_ptr&& ETSAbilityStageObj); + ETSAbilityStage(ETSRuntime &etsRuntime); ~ETSAbilityStage() override; void Init(const std::shared_ptr &context, @@ -47,7 +48,6 @@ public: void OnConfigurationUpdated(const AppExecFwk::Configuration& configuration) override; private: - bool CallObjectMethod(bool withResult, const char* name, const char* signature, ...) const; std::shared_ptr CreateStageProperty() const; @@ -55,10 +55,8 @@ private: static bool UseCommonChunk(const AppExecFwk::HapModuleInfo& hapModuleInfo); - void SetEtsAbilityStage(const std::shared_ptr &context); - ETSRuntime& etsRuntime_; - std::unique_ptr etsAbilityStageObj_; + std::shared_ptr etsAbilityStageObj_ = nullptr; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage_object.h b/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage_object.h new file mode 100644 index 0000000000000000000000000000000000000000..c8554915cd8c687d78dff5854c709947e0b4fb3e --- /dev/null +++ b/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage_object.h @@ -0,0 +1,53 @@ +/* + * 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_STAGE_OBJECT_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_STAGE_OBJECT_H + +#include "ability_delegator_infos.h" +#include "configuration.h" + +using FFIHandle = void *; +using StageHandle = void *; +using RuntimeHandle = void *; + +namespace OHOS { +namespace AppExecFwk { +class OHOSApplication; +class Configuration; +} + +namespace AbilityRuntime { +class Context; +class ETSAbilityStageObject { +public: + explicit ETSAbilityStageObject() {} + ~ETSAbilityStageObject(); + + bool Init(StageHandle 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); + void OnCreate(); + void OnDestroy(); + void OnConfigurationUpdated(const std::shared_ptr &fullConfig, + const AppExecFwk::Configuration &configuration); + void SetEtsAbilityStage(const std::shared_ptr &context); + +private: + FFIHandle ffi_ = nullptr; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_STAGE_OBJECT_H