From 32deabce2b0d170cce57bc4eba75e5f4698ccc3b Mon Sep 17 00:00:00 2001 From: zhangzezhong Date: Mon, 9 Jun 2025 17:24:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=A1=86=E6=9E=B6=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=8E=A5=E5=8F=A3=E9=80=82=E9=85=8DETS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzezhong --- frameworks/ets/ani/BUILD.gn | 1 + frameworks/ets/ani/ability_delegator/BUILD.gn | 84 +++ .../include/ets_ability_delegator.h | 72 +++ .../include/ets_ability_delegator_registry.h | 26 + .../include/ets_ability_delegator_utils.h | 30 ++ .../include/ets_ability_monitor.h | 140 +++++ .../src/ets_ability_delegator.cpp | 510 ++++++++++++++++++ .../src/ets_ability_delegator_registry.cpp | 144 +++++ .../src/ets_ability_delegator_utils.cpp | 304 +++++++++++ .../src/ets_ability_monitor.cpp | 195 +++++++ .../ani/ani_common/include/ani_common_util.h | 2 + .../ani/ani_common/src/ani_common_util.cpp | 31 ++ ...s.app.ability.abilityDelegatorRegistry.ets | 28 + .../ets/ets/@ohos.application.testRunner.ets | 19 + frameworks/ets/ets/BUILD.gn | 107 ++++ .../ets/ets/application/AbilityDelegator.ets | 165 ++++++ .../ets/ets/application/AbilityMonitor.ets | 48 ++ .../ets/application/abilityDelegatorArgs.ets | 28 + .../ets/ets/application/shellCmdResult.ets | 26 + frameworks/ets/ets/utils/AbilityUtils.ets | 13 + .../js/napi/app/ability_delegator/BUILD.gn | 1 + .../app/ability_delegator/ability_monitor.cpp | 84 ++- .../app/ability_delegator/ability_monitor.h | 14 +- .../js_ability_delegator.cpp | 21 +- frameworks/native/ability/native/BUILD.gn | 1 + frameworks/native/appkit/BUILD.gn | 3 + .../ability_delegator/ability_delegator.cpp | 63 +-- .../ability_delegator/iability_monitor.cpp | 20 +- .../runner_runtime/ets_test_runner.cpp | 179 ++++++ frameworks/native/appkit/app/main_thread.cpp | 21 +- .../ability_delegator/ability_delegator.h | 34 +- .../ability_delegator_infos.h | 13 +- .../ability_delegator/iability_monitor.h | 22 +- .../runner_runtime/ets_test_runner.h | 71 +++ .../mock_iability_monitor.cpp | 16 +- .../ability_delegator/mock_iability_monitor.h | 16 +- .../ability_delegator_test/BUILD.gn | 5 + test/unittest/app_recovery_test/BUILD.gn | 1 + .../cj_ability_delegator_args_test/BUILD.gn | 1 + .../cj_ability_delegator_test/BUILD.gn | 1 + .../cj_application_context_test/BUILD.gn | 1 + test/unittest/cj_test_runner_test/BUILD.gn | 2 + .../ability_delegator/BUILD.gn | 4 + .../ability_delegator_test.cpp | 2 +- .../iability_monitor_test.cpp | 2 +- test/unittest/js_ui_ability_test/BUILD.gn | 1 + 46 files changed, 2440 insertions(+), 132 deletions(-) create mode 100644 frameworks/ets/ani/ability_delegator/BUILD.gn create mode 100644 frameworks/ets/ani/ability_delegator/include/ets_ability_delegator.h create mode 100644 frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_registry.h create mode 100644 frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_utils.h create mode 100644 frameworks/ets/ani/ability_delegator/include/ets_ability_monitor.h create mode 100644 frameworks/ets/ani/ability_delegator/src/ets_ability_delegator.cpp create mode 100644 frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_registry.cpp create mode 100644 frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_utils.cpp create mode 100644 frameworks/ets/ani/ability_delegator/src/ets_ability_monitor.cpp create mode 100644 frameworks/ets/ets/@ohos.app.ability.abilityDelegatorRegistry.ets create mode 100644 frameworks/ets/ets/@ohos.application.testRunner.ets create mode 100644 frameworks/ets/ets/application/AbilityDelegator.ets create mode 100644 frameworks/ets/ets/application/AbilityMonitor.ets create mode 100644 frameworks/ets/ets/application/abilityDelegatorArgs.ets create mode 100644 frameworks/ets/ets/application/shellCmdResult.ets create mode 100644 frameworks/native/appkit/ability_delegator/runner_runtime/ets_test_runner.cpp create mode 100644 interfaces/kits/native/appkit/ability_delegator/runner_runtime/ets_test_runner.h diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index c275c7ed5af..410f756edec 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -17,6 +17,7 @@ import("//foundation/ability/ability_runtime/ability_runtime.gni") group("ani_packages") { deps = [ "${ability_runtime_path}/frameworks/ets/ani/native_constructor:context_ani", + "${ability_runtime_path}/frameworks/ets/ani/ability_delegator:ability_delegator_registry_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] } diff --git a/frameworks/ets/ani/ability_delegator/BUILD.gn b/frameworks/ets/ani/ability_delegator/BUILD.gn new file mode 100644 index 00000000000..5e1733151b2 --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/BUILD.gn @@ -0,0 +1,84 @@ +# 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/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +ohos_shared_library("ability_delegator_registry_ani_kit") { + 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}/interfaces/kits/native/appkit/ability_runtime/app", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/ability_delegator/include", + "${ability_runtime_services_path}/common/include", + "${ability_runtime_path}/interfaces/kits/native/ability/native", + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", + "${ability_runtime_path}/frameworks/js/napi/app/ability_delegator", + "${ability_runtime_path}/interfaces/inner_api/runtime/include", + ] + + configs = [] + + public_configs = [] + + sources = [ + "./src/ets_ability_delegator.cpp", + "./src/ets_ability_delegator_registry.cpp", + "./src/ets_ability_delegator_utils.cpp", + "./src/ets_ability_monitor.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_native_path}/appkit:app_context_utils", + "${ability_runtime_native_path}/appkit:appkit_delegator", + "${ability_runtime_native_path}/appkit:delegator_mgmt", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + ] + + external_deps = [ + "ability_base:want", + "bundle_framework:appexecfwk_base", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "eventhandler:libeventhandler", + "hilog:libhilog", + "ipc:ipc_core", + "json:nlohmann_json_static", + "napi:ace_napi", + "runtime_core:ani", + ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator.h b/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator.h new file mode 100644 index 00000000000..c1c31f62179 --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator.h @@ -0,0 +1,72 @@ +/* +* 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_DELEGATOR_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_DELEGATOR_H + +#include +#include "ability_delegator.h" +#include "context.h" +#include "ets_ability_delegator_registry.h" +#include "ets_ability_monitor.h" +#include "iability_monitor.h" +#include "ets_runtime.h" +#include "want.h" +namespace OHOS { +namespace AbilityDelegatorEts { +using namespace OHOS::AbilityRuntime; +class EtsAbilityDelegator { +public: + static EtsAbilityDelegator& GetInstance() + { + static EtsAbilityDelegator instance; + return instance; + } + EtsAbilityDelegator(); + ~EtsAbilityDelegator(); + static void ExecuteShellCommand(ani_env* env, [[maybe_unused]]ani_object object, + ani_string cmd, ani_double timeoutSecs, ani_object callback); + + static void FinishTest(ani_env* env, [[maybe_unused]]ani_object object, + ani_string msg, ani_double code, ani_object callback); + + static ani_object CreateEtsBaseContext(ani_env* aniEnv, ani_class contextClass, + std::shared_ptr context); + + static ani_object GetAppContext(ani_env* env, [[maybe_unused]]ani_object object, ani_class clss); + + static void PrintSync(ani_env *env, [[maybe_unused]]ani_class aniClass, ani_string msg); + + static void AddAbilityMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass, + ani_object monitorObj, ani_object callback); + + static void StartAbility(ani_env* env, [[maybe_unused]]ani_object object, ani_object wantObj, ani_object callback); + +private: + [[maybe_unused]] void RetrieveStringFromAni(ani_env *env, ani_string string, std::string &resString); + + ani_object WrapShellCmdResult(ani_env* env, std::unique_ptr result); + + bool ParseMonitorPara(ani_env *env, ani_object monitorObj, + std::shared_ptr &monitorImpl); + + bool ParseMonitorParaInner(ani_env *env, ani_object monitorObj, + std::shared_ptr &monitorImpl); + +}; +} // namespace AbilityDelegatorEts +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_DELEGATOR_H diff --git a/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_registry.h b/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_registry.h new file mode 100644 index 00000000000..1b9a9dddc1a --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_registry.h @@ -0,0 +1,26 @@ +/* + * 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_DELEGATOR_REGISTRY_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_DELEGATOR_REGISTRY_H + +#include "ets_runtime.h" + +namespace OHOS { +namespace AbilityDelegatorEts { +void EtsAbilityDelegatorRegistryInit(ani_env *env); +} // namespace AbilityDelegatorEts +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_DELEGATOR_REGISTRY_H diff --git a/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_utils.h b/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_utils.h new file mode 100644 index 00000000000..8ad04530954 --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/include/ets_ability_delegator_utils.h @@ -0,0 +1,30 @@ +/* + * 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_DELEGATOR_UTILS_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_DELEGATOR_UTILS_H + +#include "ability_delegator.h" +#include "ability_delegator_args.h" +#include "ets_runtime.h" + +namespace OHOS { +namespace AbilityDelegatorEts { +ani_object CreateEtsAbilityDelegator(ani_env *env); +ani_object CreateEtsAbilityDelegatorArguments(ani_env *env, + const std::shared_ptr abilityDelegatorArgs); +} // namespace AbilityDelegatorEts +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_DELEGATOR_UTILS_H diff --git a/frameworks/ets/ani/ability_delegator/include/ets_ability_monitor.h b/frameworks/ets/ani/ability_delegator/include/ets_ability_monitor.h new file mode 100644 index 00000000000..8e01944c2fa --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/include/ets_ability_monitor.h @@ -0,0 +1,140 @@ +/* + * 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_MONITOR_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_MONITOR_H + +#include +#include +#include "iability_monitor.h" +#include "ets_runtime.h" + +namespace OHOS { +namespace AbilityDelegatorEts { +class EtsAbilityMonitor : public AppExecFwk::IAbilityMonitor { +public: + /** + * A constructor used to create a EtsAbilityMonitor instance with the input parameter passed. + * + * @param abilityName Indicates the specified ability name for monitoring the lifecycle state changes + * of the ability. + */ + explicit EtsAbilityMonitor(const std::string &abilityName); + + /** + * A constructor used to create a EtsAbilityMonitor instance with the input parameter passed. + * + * @param abilityName Indicates the specified ability name for monitoring the lifecycle state changes + * of the ability. + * + * @param moduleName Indicates the specified module name for monitoring the lifecycle state changes + * of the ability. + */ + explicit EtsAbilityMonitor(const std::string &abilityName, const std::string &moduleName); + + /** + * Default deconstructor used to deconstruct. + */ + virtual ~EtsAbilityMonitor() = default; + + /** + * Called when ability is started. + * Then call the corresponding method on the ets side through the saved ets object. + * + * @param abilityObj Indicates the ability object. + */ + void OnAbilityStart(const std::weak_ptr &abilityObj) override; + + /** + * Called when ability is in foreground. + * Then call the corresponding method on the ets side through the saved ets object. + * + * @param abilityObj Indicates the ability object. + */ + void OnAbilityForeground(const std::weak_ptr &abilityObj) override; + + /** + * Called when ability is in background. + * Then call the corresponding method on the ets side through the saved ets object. + * + * @param abilityObj Indicates the ability object. + */ + void OnAbilityBackground(const std::weak_ptr &abilityObj) override; + + /** + * Called when ability is stopped. + * Then call the corresponding method on the ets side through the saved ets object. + * + * @param abilityObj Indicates the ability object. + */ + void OnAbilityStop(const std::weak_ptr &abilityObj) override; + + /** + * Called when window stage is created. + * Then call the corresponding method on the ets side through the saved ets object. + * + * @param abilityObj Indicates the ability object. + */ + void OnWindowStageCreate(const std::weak_ptr &abilityObj) override; + + /** + * Called when window stage is restored. + * Then call the corresponding method on the ets side through the saved ets object. + * + * @param abilityObj Indicates the ability object. + */ + void OnWindowStageRestore(const std::weak_ptr &abilityObj) override; + + /** + * Called when window stage is destroyed. + * Then call the corresponding method on the ets side through the saved ets object. + * + * @param abilityObj Indicates the ability object. + */ + void OnWindowStageDestroy(const std::weak_ptr &abilityObj) override; + + /** + * Sets the ets object. + * + * @param abilityMonitorObj Indicates the ets object. + */ + void SetEtsAbilityMonitor(ani_env *env, ani_object &abilityMonitorObj); + + /** + * Obtains the saved ets object. + * + * @return the saved ets object. + */ + std::unique_ptr &GetEtsAbilityMonitor() + { + return etsAbilityMonitor_; + } + +private: + void CallLifecycleCBFunction(const std::string &functionName, + const std::shared_ptr &abilityObj); + ani_env* GetAniEnv(); + std::shared_ptr GetRuntimeObject( + const std::weak_ptr &abilityObj); + +private: + ani_vm* vm_ = nullptr; + std::string abilityName_; + std::string moduleName_; + std::unique_ptr etsAbilityMonitor_; +}; +} // namespace AbilityDelegatorJs +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_MONITOR_H diff --git a/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator.cpp b/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator.cpp new file mode 100644 index 00000000000..a21efe7f008 --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator.cpp @@ -0,0 +1,510 @@ +/* + * 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_delegator.h" + +#include +#include +#include "ability_delegator_registry.h" +#include "ability_stage_monitor.h" +#include "ani_common_want.h" +#include "ani_enum_convert.h" +#include "ets_ability_monitor.h" +#include "ets_context_utils.h" +#include "ets_error_utils.h" +#include "hilog_tag_wrapper.h" +#include "shell_cmd_result.h" + +namespace OHOS { +namespace AbilityDelegatorEts { + +using namespace OHOS::AbilityRuntime; + +std::map, std::shared_ptr> g_monitorRecord; +std::map, sptr, std::owner_less<>> g_abilityRecord; +std::mutex g_mtxMonitorRecord; +std::mutex g_mutexAbilityRecord; + +enum ERROR_CODE { + INCORRECT_PARAMETERS = 401, +}; + +#ifdef ENABLE_ERRCODE +constexpr int COMMON_FAILED = 16000100; +#else +constexpr int COMMON_FAILED = -1; +#endif + +namespace { +constexpr const char* AREA_MODE_ENUM_NAME = "L@ohos/app/ability/contextConstant/contextConstant/AreaMode;"; +constexpr const char* CONTEXT_CLASS_NAME = "Lapplication/Context/Context;"; +constexpr const char* SHELL_CMD_RESULT_CLASS_NAME = "Lapplication/shellCmdResult/ShellCmdResultImpl;"; +constexpr const char* ABILITY_MONITOR_INNER_CLASS_NAME = "Lapplication/AbilityMonitor/AbilityMonitorInner;"; +} + +EtsAbilityDelegator::EtsAbilityDelegator() +{ + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + if (delegator) { + auto clearFunc = [](const std::shared_ptr &baseProperty) { + auto property = std::static_pointer_cast(baseProperty); + if (!property) { + TAG_LOGE(AAFwkTag::DELEGATOR, "invalid property type"); + return; + } + + std::unique_lock lck(g_mutexAbilityRecord); + for (auto it = g_abilityRecord.begin(); it != g_abilityRecord.end();) { + if (it->second == property->token_) { + it = g_abilityRecord.erase(it); + continue; + } + ++it; + } + }; + + delegator->RegisterClearFunc(clearFunc); + } +} + +EtsAbilityDelegator::~EtsAbilityDelegator() = default; + +ani_object EtsAbilityDelegator::CreateEtsBaseContext(ani_env* aniEnv, ani_class contextClass, + std::shared_ptr context) +{ + if (aniEnv == nullptr || context == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv or context"); + return {}; + } + ani_object contextObj = nullptr; + ani_method method = nullptr; + ani_status status = aniEnv->Class_FindMethod(contextClass, "", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status); + return {}; + } + if ((status = aniEnv->Object_New(contextClass, method, &contextObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status); + return {}; + } + ani_field areaField = nullptr; + if (aniEnv->Class_FindField(contextClass, "area", &areaField) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find area failed"); + return {}; + } + ani_enum_item areaModeItem {}; + OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts(aniEnv, + AREA_MODE_ENUM_NAME, context->GetArea(), areaModeItem); + if (aniEnv->Object_SetField_Ref(contextObj, areaField, (ani_ref)areaModeItem) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_SetField_Int failed"); + return {}; + } + ani_field filesDirField = nullptr; + if (aniEnv->Class_FindField(contextClass, "filesDir", &filesDirField) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find filesDir failed"); + return {}; + } + auto filesDir = context->GetFilesDir(); + ani_string filesDir_string{}; + aniEnv->String_NewUTF8(filesDir.c_str(), filesDir.size(), &filesDir_string); + if (aniEnv->Object_SetField_Ref(contextObj, filesDirField, reinterpret_cast(filesDir_string)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_SetField_Ref failed"); + return {}; + } + ani_field tempDirField = nullptr; + if (aniEnv->Class_FindField(contextClass, "tempDir", &tempDirField) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find find tempDir failed"); + return {}; + } + auto tempDir = context->GetTempDir(); + ani_string tempDirString{}; + aniEnv->String_NewUTF8(tempDir.c_str(), tempDir.size(), &tempDirString); + if (aniEnv->Object_SetField_Ref(contextObj, tempDirField, reinterpret_cast(tempDirString)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_SetField_Ref failed"); + return {}; + } + ContextUtil::BindApplicationInfo(aniEnv, contextClass, contextObj, context); + ContextUtil::BindResourceManager(aniEnv, contextClass, contextObj, context); + return contextObj; +} + +ani_object EtsAbilityDelegator::WrapShellCmdResult(ani_env* env, std::unique_ptr result) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "WrapShellCmdResult called"); + if (result == nullptr || env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "result or env is null"); + return {}; + } + ani_class cls = nullptr; + ani_status status = ANI_ERROR; + status = env->FindClass(SHELL_CMD_RESULT_CLASS_NAME, &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find AbilityDelegator failed status: %{public}d", status); + return {}; + } + ani_method method = nullptr; + status = env->Class_FindMethod(cls, "", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status); + return {}; + } + ani_object object = nullptr; + if (env->Object_New(cls, method, &object) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status); + return {}; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Object_New success"); + ani_field filed = nullptr; + status = env->Class_FindField(cls, "stdResult", &filed); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindField failed status: %{public}d", status); + } + ani_string aniStringVal {}; + std::string strResult = result->GetStdResult(); + status = env->String_NewUTF8(strResult.c_str(), strResult.size(), &aniStringVal); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status); + } + status = env->Object_SetField_Ref(object, filed, aniStringVal); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "set strResult failed status: %{public}d", status); + } + int32_t exitCode = result->GetExitCode(); + status = env->Object_SetPropertyByName_Double(object, "exitCode", exitCode); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "set exitCode failed status: %{public}d", status); + } + return object; +} + +ani_object EtsAbilityDelegator::GetAppContext(ani_env* env, [[maybe_unused]]ani_object object, ani_class clss) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "GetAppContext call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr"); + return {}; + } + ani_class cls; + ani_object nullobj = nullptr; + if (ANI_OK != env->FindClass(CONTEXT_CLASS_NAME, &cls)) { + TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass Context Failed"); + return nullobj; + } + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + if (!delegator) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator"); + return nullobj; + } + std::shared_ptr context = delegator->GetAppContext(); + if (!context) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null context"); + return nullobj; + } + ani_object objectContext = CreateEtsBaseContext(env, cls, context); + TAG_LOGD(AAFwkTag::DELEGATOR, "GetAppContext end"); + return objectContext; +} + +void EtsAbilityDelegator::ExecuteShellCommand(ani_env *env, [[maybe_unused]]ani_object object, + ani_string cmd, ani_double timeoutSecs, ani_object callback) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "ExecuteShellCommand called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return; + } + std::string stdCmd = ""; + if (!OHOS::AppExecFwk::GetStdString(env, cmd, stdCmd)) { + TAG_LOGE(AAFwkTag::DELEGATOR, "GetStdString Failed"); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return; + } + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + if (!delegator) { + TAG_LOGE(AAFwkTag::DELEGATOR, "delegator is nullptr"); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + int resultCode = 0; + auto result = delegator->ExecuteShellCommand(stdCmd, static_cast(timeoutSecs)); + ani_object objValue = GetInstance().WrapShellCmdResult(env, std::move(result)); + if (objValue == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null objValue"); + resultCode = COMMON_FAILED; + ani_class cls = nullptr; + ani_status status = env->FindClass(SHELL_CMD_RESULT_CLASS_NAME, &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find AbilityDelegator failed status: %{public}d", status); + } + ani_method method = nullptr; + status = env->Class_FindMethod(cls, "", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status); + } + if (env->Object_New(cls, method, &objValue) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status); + } + } + ani_ref callbackRef = nullptr; + ani_status createStatus = env->GlobalReference_Create(callback, &callbackRef); + if (createStatus != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Create Gloabl ref for delegator failed %{public}d", createStatus); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + OHOS::AppExecFwk::AsyncCallback(env, reinterpret_cast(callbackRef), + OHOS::AbilityRuntime::CreateEtsErrorByNativeErr(env, resultCode), + objValue); + return; +} + +void EtsAbilityDelegator::FinishTest(ani_env* env, [[maybe_unused]]ani_object object, + ani_string msg, ani_double code, ani_object callback) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return; + } + std::string stdMsg = ""; + if (!OHOS::AppExecFwk::GetStdString(env, msg, stdMsg)) { + TAG_LOGE(AAFwkTag::DELEGATOR, "GetStdString Failed"); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return; + } + int resultCode = 0; + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + if (!delegator) { + TAG_LOGE(AAFwkTag::DELEGATOR, "FinishTest delegator is null"); + resultCode = COMMON_FAILED; + } else { + delegator->FinishUserTest(stdMsg, static_cast(code)); + } + ani_ref callbackRef = nullptr; + auto status = env->GlobalReference_Create(callback, &callbackRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Create Gloabl ref for delegator failed %{public}d", status); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + OHOS::AppExecFwk::AsyncCallback(env, reinterpret_cast(callbackRef), + OHOS::AbilityRuntime::CreateEtsErrorByNativeErr(env, resultCode), + nullptr); + TAG_LOGD(AAFwkTag::DELEGATOR, "FinishTest END"); + return; +} + +void EtsAbilityDelegator::PrintSync(ani_env *env, [[maybe_unused]]ani_class aniClass, ani_string msg) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "PrintSync"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr"); + return; + } + std::string msgStr; + ani_size sz {}; + env->String_GetUTF8Size(msg, &sz); + msgStr.resize(sz + 1); + env->String_GetUTF8SubString(msg, 0, sz, msgStr.data(), msgStr.size(), &sz); + TAG_LOGD(AAFwkTag::DELEGATOR, "PrintSync %{public}s", msgStr.c_str()); + + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + if (delegator == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator"); + return; + } + + delegator->Print(msgStr); + return; +} + +void EtsAbilityDelegator::RetrieveStringFromAni(ani_env *env, ani_string str, std::string &res) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr"); + return; + } + ani_size sz {}; + ani_status status = ANI_ERROR; + if ((status = env->String_GetUTF8Size(str, &sz)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "status: %{public}d", status); + return; + } + res.resize(sz + 1); + if ((status = env->String_GetUTF8SubString(str, 0, sz, res.data(), res.size(), &sz)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "status: %{public}d", status); + return; + } + res.resize(sz); +} + +void EtsAbilityDelegator::AddAbilityMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass, + ani_object monitorObj, ani_object callback) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr"); + return; + } + std::shared_ptr monitorImpl = nullptr; + if (!GetInstance().ParseMonitorPara(env, monitorObj, monitorImpl)) { + TAG_LOGE(AAFwkTag::DELEGATOR, "ParseMonitorPara failed"); + AbilityRuntime::ThrowEtsError(env, INCORRECT_PARAMETERS, + "Parse param monitor failed, monitor must be Monitor."); + return; + } + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + int resultCode = 0; + if (delegator == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator"); + resultCode = COMMON_FAILED; + } else { + delegator->AddAbilityMonitor(monitorImpl); + } + ani_ref callbackRef = nullptr; + ani_status status = env->GlobalReference_Create(callback, &callbackRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Create Gloabl ref for delegator failed %{public}d", status); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + OHOS::AppExecFwk::AsyncCallback(env, reinterpret_cast(callbackRef), + OHOS::AbilityRuntime::CreateEtsErrorByNativeErr(env, resultCode), + nullptr); + return; +} +void EtsAbilityDelegator::StartAbility(ani_env* env, [[maybe_unused]]ani_object object, + ani_object wantObj, ani_object callback) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "StartAbility"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr"); + return; + } + AAFwk::Want want; + if (!AppExecFwk::UnwrapWant(env, wantObj, want)) { + TAG_LOGE(AAFwkTag::DELEGATOR, "UnwrapWant failed"); + AbilityRuntime::ThrowEtsError(env, (int32_t)AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM, + "Parse want failed, want must be Want."); + return; + } + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + if (delegator == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator"); + AbilityRuntime::ThrowEtsError(env, COMMON_FAILED); + return; + } + int resultCode = 0; + int result = delegator->StartAbility(want); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "start ability failed: %{public}d", result); + resultCode = result; + } + ani_ref callbackRef = nullptr; + auto status = env->GlobalReference_Create(callback, &callbackRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Create Gloabl ref for delegator failed %{public}d", status); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + OHOS::AppExecFwk::AsyncCallback(env, reinterpret_cast(callbackRef), + OHOS::AbilityRuntime::CreateEtsErrorByNativeErr(env, resultCode), + nullptr); + return; +} +bool EtsAbilityDelegator::ParseMonitorPara(ani_env *env, ani_object monitorObj, + std::shared_ptr &monitorImpl) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "monitorRecord size: %{public}zu", g_monitorRecord.size()); + if (env == nullptr || monitorObj == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "env or monitorObj is nullptr"); + return false; + } + { + std::unique_lock lck(g_mtxMonitorRecord); + for (auto iter = g_monitorRecord.begin(); iter != g_monitorRecord.end(); ++iter) { + std::shared_ptr etsMonitor = iter->first; + ani_boolean result = false; + ani_status status = env->Reference_StrictEquals(reinterpret_cast(monitorObj), + reinterpret_cast(etsMonitor->aniObj), &result); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status); + } + if (result) { + monitorImpl = iter->second; + return monitorImpl ? true : false; + } + } + } + if (!ParseMonitorParaInner(env, monitorObj, monitorImpl)) { + TAG_LOGE(AAFwkTag::DELEGATOR, "ParseMonitorParaInner failed"); + return false; + } + return true; +} + +bool EtsAbilityDelegator::ParseMonitorParaInner(ani_env *env, ani_object monitorObj, + std::shared_ptr &monitorImpl) +{ + if (env == nullptr || monitorObj == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "env or monitorObj is nullptr"); + return false; + } + ani_class monitorCls; + ani_status status = env->FindClass(ABILITY_MONITOR_INNER_CLASS_NAME, &monitorCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass failed status: %{public}d", status); + return false; + } + ani_ref moduleNameRef; + status = env->Object_GetPropertyByName_Ref(monitorObj, "moduleName", &moduleNameRef); + if (ANI_OK != status) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetField_Ref "); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return false; + } + std::string strModuleName; + ani_string aniModuleString = static_cast(moduleNameRef); + GetInstance().RetrieveStringFromAni(env, aniModuleString, strModuleName); + ani_ref abilityNameRef; + status = env->Object_GetPropertyByName_Ref(monitorObj, "abilityName", &abilityNameRef); + if (ANI_OK != status) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetField_Ref "); + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return false; + } + std::string strAbilityName; + ani_string aniAbilityName = static_cast(abilityNameRef); + GetInstance().RetrieveStringFromAni(env, aniAbilityName, strAbilityName); + + std::shared_ptr abilityMonitor = nullptr; + if (strModuleName.empty()) { + abilityMonitor = std::make_shared(strAbilityName); + abilityMonitor->SetEtsAbilityMonitor(env, monitorObj); + } else { + abilityMonitor = std::make_shared(strAbilityName, strModuleName); + abilityMonitor->SetEtsAbilityMonitor(env, monitorObj); + } + monitorImpl = abilityMonitor; + std::shared_ptr reference = std::make_shared(); + if (reference != nullptr) { + reference->aniObj = monitorObj; + } + std::unique_lock lck(g_mtxMonitorRecord); + g_monitorRecord.emplace(reference, monitorImpl); + return true; +} + +} // namespace AbilityDelegatorEts +} // namespace OHOS diff --git a/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_registry.cpp b/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_registry.cpp new file mode 100644 index 00000000000..da840f60a1a --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_registry.cpp @@ -0,0 +1,144 @@ +/* + * 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_delegator_registry.h" + +#include +#include "ability_delegator.h" +#include "ability_delegator_registry.h" +#include "ets_ability_delegator.h" +#include "ets_ability_delegator_utils.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityDelegatorEts { +std::unique_ptr etsReference; +std::mutex etsReferenceMutex; + +static ani_object GetAbilityDelegator(ani_env *env, [[maybe_unused]]ani_class aniClass) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return {}; + } + + std::lock_guard lock(etsReferenceMutex); + auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS); + if (delegator == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator"); + return {}; + } + + if (etsReference == nullptr) { + ani_object value = CreateEtsAbilityDelegator(env); + if (value == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "value is nullptr"); + return {}; + } + ani_boolean isValue; + env->Reference_IsNullishValue(value, &isValue); + if (isValue) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_IsNullishValue"); + return {}; + } + etsReference = std::make_unique(); + ani_ref result; + auto status = env->GlobalReference_Create(value, &(result)); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Create Gloabl ref for delegator failed %{public}d", status); + return {}; + } + etsReference->aniObj = static_cast(result); + return etsReference->aniObj; + } else { + return etsReference->aniObj; + } +} + +static ani_object GetArguments(ani_env *env, [[maybe_unused]]ani_class aniClass) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return {}; + } + + auto abilityDelegatorArgs = AppExecFwk::AbilityDelegatorRegistry::GetArguments(); + if (abilityDelegatorArgs == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "get argument failed"); + return {}; + } + + return CreateEtsAbilityDelegatorArguments(env, abilityDelegatorArgs); +} + +void EtsAbilityDelegatorRegistryInit(ani_env *env) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "EtsAbilityDelegatorRegistryInit call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return; + } + ani_status status = ANI_ERROR; + if (env->ResetError() != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "ResetError failed"); + } + + ani_namespace ns; + status = env->FindNamespace("L@ohos/app/ability/abilityDelegatorRegistry/abilityDelegatorRegistry;", &ns); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "FindNamespace abilityDelegatorRegistry failed status: %{public}d", status); + return; + } + + std::array kitFunctions = { + ani_native_function {"getAbilityDelegator", nullptr, reinterpret_cast(GetAbilityDelegator)}, + ani_native_function {"getArguments", nullptr, reinterpret_cast(GetArguments)}, + }; + + status = env->Namespace_BindNativeFunctions(ns, kitFunctions.data(), kitFunctions.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Namespace_BindNativeFunctions failed status: %{public}d", status); + } + + if (env->ResetError() != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "ResetError failed"); + } + TAG_LOGD(AAFwkTag::DELEGATOR, "EtsAbilityDelegatorRegistryInit end"); +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "ANI_Constructor"); + ani_env *env = nullptr; + ani_status status = ANI_ERROR; + if (vm == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null vm"); + return ANI_ERROR; + } + status = vm->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "GetEnv failed status: %{public}d", status); + return ANI_NOT_FOUND; + } + + EtsAbilityDelegatorRegistryInit(env); + *result = ANI_VERSION_1; + TAG_LOGD(AAFwkTag::DELEGATOR, "ANI_Constructor finish"); + return ANI_OK; +} +} +} // namespace AbilityDelegatorEts +} // namespace OHOS diff --git a/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_utils.cpp b/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_utils.cpp new file mode 100644 index 00000000000..6d7aed80ad5 --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/src/ets_ability_delegator_utils.cpp @@ -0,0 +1,304 @@ +/* + * 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_delegator_utils.h" + +#include +#include "ets_ability_delegator.h" +#include "hilog_tag_wrapper.h" + + +namespace OHOS { +namespace AbilityDelegatorEts { +namespace { +constexpr const char* ABILITY_DELEGATOR_CLASS_NAME = "Lapplication/AbilityDelegator/AbilityDelegatorInner;"; +constexpr const char* RECORD_CLASS_NAME = "Lescompat/Record;"; +constexpr const char* ARGS_ABILITY_DELEGATOR_CLASS_NAME = + "Lapplication/abilityDelegatorArgs/AbilityDelegatorArgsInner;"; +} + +bool BindFunctions(ani_env *aniEnv, ani_class abilityDelegator) +{ + if (aniEnv == nullptr) { + return false; + } + std::array functions = { + ani_native_function {"getAppContext", nullptr, reinterpret_cast(EtsAbilityDelegator::GetAppContext)}, + ani_native_function {"nativeExecuteShellCommand", nullptr, + reinterpret_cast(EtsAbilityDelegator::ExecuteShellCommand)}, + ani_native_function {"nativeFinishTest", nullptr, reinterpret_cast(EtsAbilityDelegator::FinishTest)}, + ani_native_function {"printSync", nullptr, reinterpret_cast(EtsAbilityDelegator::PrintSync)}, + ani_native_function {"nativeAddAbilityMonitor", nullptr, + reinterpret_cast(EtsAbilityDelegator::AddAbilityMonitor)}, + ani_native_function {"nativeStartAbility", + "L@ohos/app/ability/Want/Want;Lutils/AbilityUtils/AsyncCallbackWrapper;:V", + reinterpret_cast(EtsAbilityDelegator::StartAbility)}, + }; + ani_status status = aniEnv->Class_BindNativeMethods(abilityDelegator, functions.data(), functions.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_BindNativeMethods failed status: %{public}d", status); + return false; + } + return true; +} + +ani_object CreateEtsAbilityDelegator(ani_env *aniEnv) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "CreateEtsAbilityDelegator"); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv"); + return {}; + } + ani_class abilityDelegator = nullptr; + ani_status status = ANI_ERROR; + status = aniEnv->FindClass(ABILITY_DELEGATOR_CLASS_NAME, &abilityDelegator); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find AbilityDelegatorInner failed status: %{public}d", status); + return {}; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "find AbilityDelegator success"); + + if (!BindFunctions(aniEnv, abilityDelegator)) { + TAG_LOGE(AAFwkTag::DELEGATOR, "BindFunctions failed"); + return {}; + } + + ani_method method = nullptr; + status = aniEnv->Class_FindMethod(abilityDelegator, "", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status); + return {}; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod ctor success"); + + ani_object object = nullptr; + if (aniEnv->Object_New(abilityDelegator, method, &object) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status); + return {}; + } + + TAG_LOGD(AAFwkTag::DELEGATOR, "CreateEtsAbilityDelegator success"); + return object; +} + +void SetBundleName(ani_env *aniEnv, ani_class arguments, ani_object argumentObject, const std::string &bundleName) +{ + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv"); + return; + } + ani_status status = ANI_ERROR; + ani_string aniStr; + // Get a ani_string from std::string + status = aniEnv->String_NewUTF8(bundleName.c_str(), bundleName.length(), &aniStr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "String_NewUTF8 success"); + + // find the setter method + ani_method nameSetter; + status = aniEnv->Class_FindMethod(arguments, "bundleName", nullptr, &nameSetter); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod success"); + + // call set bundleName(n:string) + status = aniEnv->Object_CallMethod_Void(argumentObject, nameSetter, aniStr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Object_CallMethod_Void success"); +} + +void SetParameters(ani_env *aniEnv, ani_class arguments, ani_object argumentObject, + const std::map ¶s) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "SetParameters begin"); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv"); + return; + } + ani_status status = ANI_ERROR; + ani_class recordCls; + status = aniEnv->FindClass(RECORD_CLASS_NAME, &recordCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass failed status: %{public}d", status); + return; + } + ani_method recordGetMethod; + status = aniEnv->Class_FindMethod(recordCls, "$_get", "Lstd/core/Object;:Lstd/core/Object;", &recordGetMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status); + return; + } + ani_method recordSetMethod; + status = aniEnv->Class_FindMethod(recordCls, "$_set", "Lstd/core/Object;Lstd/core/Object;:V", &recordSetMethod); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status); + return; + } + ani_ref parameterRef; + status = aniEnv->Object_CallMethodByName_Ref(argumentObject, "parameters", ":Lescompat/Record;", + ¶meterRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethodByName_Ref failed status: %{public}d", status); + return; + } + ani_object parameterObject = static_cast(parameterRef); + for (auto iter = paras.begin(); iter != paras.end(); ++iter) { + std::string key = iter->first; + std::string value = iter->second; + ani_string ani_key; + ani_string ani_value; + status = aniEnv->String_NewUTF8(key.c_str(), key.length(), &ani_key); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 key failed status: %{public}d", status); + return; + } + status = aniEnv->String_NewUTF8(value.c_str(), value.length(), &ani_value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 value failed status: %{public}d", status); + return; + } + status = aniEnv->Object_CallMethod_Void(parameterObject, recordSetMethod, ani_key, ani_value); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status); + return; + } + } + TAG_LOGD(AAFwkTag::DELEGATOR, "SetParameters end"); +} + +void SetTestCaseNames(ani_env *aniEnv, ani_class arguments, ani_object argumentObject, const std::string &testcaseNames) +{ + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv"); + return; + } + ani_status status = ANI_ERROR; + ani_string aniStr; + status = aniEnv->String_NewUTF8(testcaseNames.c_str(), testcaseNames.length(), &aniStr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "String_NewUTF8 success"); + + // find the setter method + ani_method nameSetter; + status = aniEnv->Class_FindMethod(arguments, "testCaseNames", nullptr, &nameSetter); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod success"); + + // call set testcaseNames(n:string) + status = aniEnv->Object_CallMethod_Void(argumentObject, nameSetter, aniStr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Object_CallMethod_Void success"); +} + +void SetTestRunnerClassName(ani_env *aniEnv, ani_class arguments, ani_object argumentObject, + const std::string &className) +{ + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv"); + return; + } + ani_status status = ANI_ERROR; + ani_string aniStr; + status = aniEnv->String_NewUTF8(className.c_str(), className.length(), &aniStr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "String_NewUTF8 success"); + + // find the setter method + ani_method nameSetter; + status = aniEnv->Class_FindMethod(arguments, "testRunnerClassName", nullptr, &nameSetter); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod success"); + + // call set testRunnerClassName(n:string) + status = aniEnv->Object_CallMethod_Void(argumentObject, nameSetter, aniStr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status); + return; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Object_CallMethod_Void success"); +} + +ani_object CreateEtsAbilityDelegatorArguments( + ani_env *aniEnv, const std::shared_ptr abilityDelegatorArgs) +{ + TAG_LOGD(AAFwkTag::DELEGATOR, "CreateJsAbilityDelegatorArguments"); + if (aniEnv == nullptr || abilityDelegatorArgs == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv or abilityDelegatorArgs"); + return {}; + } + ani_class arguments = nullptr; + ani_status status = ANI_ERROR; + status = aniEnv->FindClass(ARGS_ABILITY_DELEGATOR_CLASS_NAME, &arguments); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find abilityDelegatorArgs failed status: %{public}d", status); + return {}; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "find AbilityDelegatorArgs success"); + + ani_method method = nullptr; + status = aniEnv->Class_FindMethod(arguments, "", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status); + return {}; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod ctor success"); + + ani_object argumentObject = nullptr; + status = aniEnv->Object_New(arguments, method, &argumentObject); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status); + return {}; + } + TAG_LOGD(AAFwkTag::DELEGATOR, "Object_New success"); + + std::string bundleName = abilityDelegatorArgs->GetTestBundleName(); + SetBundleName(aniEnv, arguments, argumentObject, bundleName); + + std::string testcaseName = abilityDelegatorArgs->GetTestCaseName(); + SetTestCaseNames(aniEnv, arguments, argumentObject, testcaseName); + + std::string className = abilityDelegatorArgs->GetTestRunnerClassName(); + SetTestRunnerClassName(aniEnv, arguments, argumentObject, className); + + auto parameters = abilityDelegatorArgs->GetTestParam(); + SetParameters(aniEnv, arguments, argumentObject, parameters); + + return argumentObject; +} +} // namespace AbilityDelegatorEts +} // namespace OHOS diff --git a/frameworks/ets/ani/ability_delegator/src/ets_ability_monitor.cpp b/frameworks/ets/ani/ability_delegator/src/ets_ability_monitor.cpp new file mode 100644 index 00000000000..9ce5b78aa6d --- /dev/null +++ b/frameworks/ets/ani/ability_delegator/src/ets_ability_monitor.cpp @@ -0,0 +1,195 @@ +/* + * 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 "ability_delegator_registry.h" +#include "ets_ability_monitor.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityDelegatorEts { +using namespace OHOS::AbilityRuntime; +EtsAbilityMonitor::EtsAbilityMonitor(const std::string &abilityName) + : IAbilityMonitor(abilityName), abilityName_(abilityName) +{} + +EtsAbilityMonitor::EtsAbilityMonitor(const std::string &abilityName, const std::string &moduleName) + : IAbilityMonitor(abilityName), abilityName_(abilityName), moduleName_(moduleName) +{} + +void EtsAbilityMonitor::OnAbilityStart(const std::weak_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityStart"); + auto runtimeObj = GetRuntimeObject(abilityObj); + if (!runtimeObj) { + return; + } + CallLifecycleCBFunction("onAbilityCreate", runtimeObj); +} + +void EtsAbilityMonitor::OnAbilityForeground(const std::weak_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityForeground"); + auto runtimeObj = GetRuntimeObject(abilityObj); + if (!runtimeObj) { + return; + } + CallLifecycleCBFunction("onAbilityForeground", runtimeObj); +} + +void EtsAbilityMonitor::OnAbilityBackground(const std::weak_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityBackground"); + auto runtimeObj = GetRuntimeObject(abilityObj); + if (!runtimeObj) { + return; + } + CallLifecycleCBFunction("onAbilityBackground", runtimeObj); +} + +void EtsAbilityMonitor::OnAbilityStop(const std::weak_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called OnAbilityStop"); + auto runtimeObj = GetRuntimeObject(abilityObj); + if (!runtimeObj) { + return; + } + CallLifecycleCBFunction("onAbilityDestroy", runtimeObj); +} + +void EtsAbilityMonitor::OnWindowStageCreate(const std::weak_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called OnWindowStageCreate"); + auto runtimeObj = GetRuntimeObject(abilityObj); + if (!runtimeObj) { + return; + } + CallLifecycleCBFunction("onWindowStageCreate", runtimeObj); +} + +void EtsAbilityMonitor::OnWindowStageRestore(const std::weak_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called OnWindowStageRestore"); + auto runtimeObj = GetRuntimeObject(abilityObj); + if (!runtimeObj) { + return; + } + CallLifecycleCBFunction("onWindowStageRestore", runtimeObj); +} + +void EtsAbilityMonitor::OnWindowStageDestroy(const std::weak_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called OnWindowStageDestroy"); + auto runtimeObj = GetRuntimeObject(abilityObj); + if (!runtimeObj) { + return; + } + CallLifecycleCBFunction("onWindowStageDestroy", runtimeObj); +} + +void EtsAbilityMonitor::SetEtsAbilityMonitor(ani_env *env, ani_object &abilityMonitorObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "called SetEtsAbilityMonitor"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return; + } + etsAbilityMonitor_ = std::make_unique(); + ani_ref objRef = nullptr; + if (env->GlobalReference_Create(abilityMonitorObj, &objRef) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "GlobalReference_Create failed"); + return; + } + + ani_vm *aniVM = nullptr; + if (env->GetVM(&aniVM) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "GetVM failed"); + return; + } + vm_ = aniVM; + if (etsAbilityMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null etsAbilityMonitor_"); + return; + } + etsAbilityMonitor_->aniObj = abilityMonitorObj; + etsAbilityMonitor_->aniRef = objRef; +} + +void EtsAbilityMonitor::CallLifecycleCBFunction(const std::string &functionName, + const std::shared_ptr &abilityObj) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "CallLifecycleCBFunction, name: %{public}s start", functionName.c_str()); + if (functionName.empty()) { + TAG_LOGE(AAFwkTag::DELEGATOR, "empty funcName"); + return; + } + + if (abilityObj == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null EtsAbilityMonitor"); + return; + } + + ani_env *env = GetAniEnv(); + if (env == nullptr || etsAbilityMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env or etsAbilityMonitor_"); + return; + } + + ani_status status = ANI_OK; + ani_object monitorObj = reinterpret_cast(etsAbilityMonitor_->aniRef); + ani_ref funRef; + status = env->Object_GetPropertyByName_Ref(monitorObj, functionName.c_str(), &funRef); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetField_Ref failed status: %{public}d", status); + return; + } + + ani_fn_object onFn = reinterpret_cast(funRef); + ani_ref resutlt; + std::vector argv = { abilityObj->aniRef }; + if ((status = env->FunctionalObject_Call(onFn, 1, argv.data(), &resutlt)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "FunctionalObject_Call failed, status: %{public}d", status); + return; + } +} + +ani_env* EtsAbilityMonitor::GetAniEnv() +{ + if (vm_ == nullptr) { + return nullptr; + } + ani_env* aniEnv = nullptr; + if (vm_->GetEnv(ANI_VERSION_1, &aniEnv) != ANI_OK) { + return nullptr; + } + return aniEnv; +} + +std::shared_ptr EtsAbilityMonitor::GetRuntimeObject( + const std::weak_ptr &abilityObj) +{ + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return nullptr; + } + auto etsbaseProperty = std::static_pointer_cast(baseProperty); + auto runtimeObj = etsbaseProperty->object_.lock(); + if (!runtimeObj) { + TAG_LOGE(AAFwkTag::DELEGATOR, "runtimeObj is nullptr"); + return nullptr; + } + return runtimeObj; +} +} // namespace AbilityDelegatorJs +} // namespace OHOS diff --git a/frameworks/ets/ani/ani_common/include/ani_common_util.h b/frameworks/ets/ani/ani_common/include/ani_common_util.h index 38d34f0a202..a601a0493a0 100644 --- a/frameworks/ets/ani/ani_common/include/ani_common_util.h +++ b/frameworks/ets/ani/ani_common/include/ani_common_util.h @@ -51,6 +51,8 @@ bool GetStringOrUndefined(ani_env *env, ani_object param, const char *name, std: ani_object CreateDouble(ani_env *env, ani_double value); ani_object CreateBoolean(ani_env *env, ani_boolean value); + +bool AsyncCallback(ani_env *env, ani_object call, ani_object error, ani_object result); } // namespace AppExecFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_ANI_COMMON_UTIL_H diff --git a/frameworks/ets/ani/ani_common/src/ani_common_util.cpp b/frameworks/ets/ani/ani_common/src/ani_common_util.cpp index 85a7a6dab7d..5442d8faf50 100644 --- a/frameworks/ets/ani/ani_common/src/ani_common_util.cpp +++ b/frameworks/ets/ani/ani_common/src/ani_common_util.cpp @@ -24,6 +24,7 @@ namespace AppExecFwk { constexpr const char* CLASSNAME_DOUBLE = "Lstd/core/Double;"; constexpr const char* CLASSNAME_BOOL = "Lstd/core/Boolean;"; constexpr const char* CLASSNAME_ARRAY = "Lescompat/Array;"; +constexpr const char* CLASSNAME_ASYNC_CALLBACK_WRAPPER = "Lutils/AbilityUtils/AsyncCallbackWrapper;"; bool GetFieldDoubleByName(ani_env *env, ani_object object, const char *name, double &value) { @@ -502,5 +503,35 @@ bool GetStringOrUndefined(ani_env *env, ani_object param, const char *name, std: } return true; } + +bool AsyncCallback(ani_env *env, ani_object call, ani_object error, ani_object result) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null env"); + return false; + } + ani_status status = ANI_ERROR; + ani_class clsCall = nullptr; + if ((status = env->FindClass(CLASSNAME_ASYNC_CALLBACK_WRAPPER, &clsCall)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "status: %{public}d", status); + return false; + } + ani_method method = nullptr; + if ((status = env->Class_FindMethod( + clsCall, "invoke", "L@ohos/base/BusinessError;Lstd/core/Object;:V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "status: %{public}d", status); + return false; + } + if (result == nullptr) { + ani_ref nullRef = nullptr; + env->GetNull(&nullRef); + result = reinterpret_cast(nullRef); + } + if ((status = env->Object_CallMethod_Void(call, method, error, result)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ANI, "status: %{public}d", status); + return false; + } + return true; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/ets/ets/@ohos.app.ability.abilityDelegatorRegistry.ets b/frameworks/ets/ets/@ohos.app.ability.abilityDelegatorRegistry.ets new file mode 100644 index 00000000000..039352f8371 --- /dev/null +++ b/frameworks/ets/ets/@ohos.app.ability.abilityDelegatorRegistry.ets @@ -0,0 +1,28 @@ +/* + * 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 { AbilityDelegator as _AbilityDelegator } from 'application.AbilityDelegator'; +import { AbilityDelegatorArgs as _AbilityDelegatorArgs } from 'application.abilityDelegatorArgs'; + +export default namespace abilityDelegatorRegistry { + loadLibrary("ability_delegator_registry_ani_kit.z") + + export native function getAbilityDelegator(): AbilityDelegator; + + export native function getArguments(): AbilityDelegatorArgs; + + export type AbilityDelegator = _AbilityDelegator; + export type AbilityDelegatorArgs = _AbilityDelegatorArgs; +} diff --git a/frameworks/ets/ets/@ohos.application.testRunner.ets b/frameworks/ets/ets/@ohos.application.testRunner.ets new file mode 100644 index 00000000000..b79b270eac8 --- /dev/null +++ b/frameworks/ets/ets/@ohos.application.testRunner.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ + +export default interface TestRunner { + onPrepare(): void; + onRun(): void; +} diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index d6d73e18eec..97f61848994 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -210,6 +210,106 @@ ohos_prebuilt_etc("ability_runtime_ability_result_abc_etc") { deps = [ ":ability_runtime_ability_result_abc" ] } +generate_static_abc("ability_delegator_application_testRunner_abc") { + base_url = "./" + files = [ "./@ohos.application.testRunner.ets" ] + + is_boot_abc = "True" + device_dst_file = + "/system/framework/ability_delegator_application_testRunner_abc.abc" +} + +ohos_prebuilt_etc("ability_delegator_application_testRunner_abc_etc") { + source = "$target_out_dir/ability_delegator_application_testRunner_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_delegator_application_testRunner_abc" ] +} + +generate_static_abc("ability_delegator_registry_abc") { + base_url = "./" + files = [ "./@ohos.app.ability.abilityDelegatorRegistry.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_delegator_registry_abc.abc" +} + +ohos_prebuilt_etc("ability_delegator_registry_abc_etc") { + source = "$target_out_dir/ability_delegator_registry_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_delegator_registry_abc" ] +} + +generate_static_abc("ability_delegator_abc") { + base_url = "./" + files = [ "./application/AbilityDelegator.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_delegator_abc.abc" +} + +ohos_prebuilt_etc("ability_delegator_abc_etc") { + source = "$target_out_dir/ability_delegator_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_delegator_abc" ] +} + +generate_static_abc("ability_delegator_args_abc") { + base_url = "./" + files = [ "./application/abilityDelegatorArgs.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_delegator_args_abc.abc" +} + +ohos_prebuilt_etc("ability_delegator_args_abc_etc") { + source = "$target_out_dir/ability_delegator_args_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_delegator_args_abc" ] +} + +generate_static_abc("ability_delegator_ability_monitor_abc") { + base_url = "." + files = [ "./application/AbilityMonitor.ets" ] + + is_boot_abc = "True" + device_dst_file = + "/system/framework/ability_delegator_ability_monitor_abc.abc" +} + +ohos_prebuilt_etc("ability_delegator_ability_monitor_abc_etc") { + source = "$target_out_dir/ability_delegator_ability_monitor_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_delegator_ability_monitor_abc" ] +} + +generate_static_abc("ability_runtime_shell_cmd_result_abc") { + base_url = "./" + files = [ "./application/shellCmdResult.ets" ] + + is_boot_abc = "True" + device_dst_file = + "/system/framework/ability_runtime_shell_cmd_result_abc.abc" +} + +ohos_prebuilt_etc("ability_runtime_shell_cmd_result_abc_etc") { + source = "$target_out_dir/ability_runtime_shell_cmd_result_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_runtime_shell_cmd_result_abc" ] +} + + group("ets_packages") { deps = [ ":ability_runtime_ability_result_abc_etc", @@ -224,5 +324,12 @@ group("ets_packages") { ":ability_runtime_want_abc_etc", ":ability_runtime_want_constant_abc_etc", ":ability_runtime_extension_context_abc_etc", + ":ability_delegator_abc_etc", + ":ability_delegator_ability_monitor_abc_etc", + ":ability_delegator_application_testRunner_abc_etc", + ":ability_delegator_args_abc_etc", + ":ability_delegator_registry_abc_etc", + ":ability_runtime_base_context_abc_etc", + ":ability_runtime_shell_cmd_result_abc_etc", ] } diff --git a/frameworks/ets/ets/application/AbilityDelegator.ets b/frameworks/ets/ets/application/AbilityDelegator.ets new file mode 100644 index 00000000000..568379f2c76 --- /dev/null +++ b/frameworks/ets/ets/application/AbilityDelegator.ets @@ -0,0 +1,165 @@ +/* + * 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 { AbilityMonitor } from 'application.AbilityMonitor'; +import Want from '@ohos.app.ability.Want'; +import Context from 'application.Context'; +import { BusinessError, AsyncCallback } from '@ohos.base'; +import { ShellCmdResult } from 'application.shellCmdResult'; +import AsyncCallbackWrapper from '../utils/AbilityUtils'; + +export interface AbilityDelegator { + printSync(msg: string): void; + + getAppContext(): Context; + + finishTest(msg: string, code: number, callback: AsyncCallback): void; + + finishTest(msg: string, code: number): Promise; + + executeShellCommand(cmd: String, callback: AsyncCallback): void; + + executeShellCommand(cmd: String, timeoutSecs: number, callback: AsyncCallback): void; + + executeShellCommand(cmd: string, timeoutSecs?: number): Promise; + + addAbilityMonitor(monitor: AbilityMonitor, callback: AsyncCallback): void; + + addAbilityMonitor(monitor: AbilityMonitor): Promise; + + startAbility(want: Want, callback: AsyncCallback): void; + + startAbility(want: Want): Promise; +} + +class AbilityDelegatorInner implements AbilityDelegator { + + public native printSync(msg: string): void; + + public native getAppContext(): Context; + + public native nativeFinishTest(msg: String, code: number, callback: AsyncCallbackWrapper): void; + + public native nativeExecuteShellCommand(cmd: string, timeoutSecs: number, + callback: AsyncCallbackWrapper): void; + + public native nativeAddAbilityMonitor(monitor: AbilityMonitor, callback: AsyncCallbackWrapper): void; + + public native nativeStartAbility(want: Want, callback: AsyncCallbackWrapper): void; + + finishTest(msg: string, code: number, callback: AsyncCallback): void { + let myCall = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeFinishTest(msg, code, myCall); + }); + } + finishTest(msg: string, code: number): Promise { + let p: Promise = + new Promise((resolve: (data: undefined) => void, reject: (err: BusinessError) => void): void => { + let myCall = new AsyncCallbackWrapper((err: BusinessError) => { + if (err.code == 0) { + resolve(undefined); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeFinishTest(msg, code, myCall); + }); + }); + return p; + } + + executeShellCommand(cmd: string, callback: AsyncCallback): void { + let timeoutSecs = 0; + let myCall = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeExecuteShellCommand(cmd, timeoutSecs, myCall); + }); + } + executeShellCommand(cmd: string, timeoutSecs: number, callback: AsyncCallback): void { + let myCall = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeExecuteShellCommand(cmd, timeoutSecs, myCall); + }); + } + executeShellCommand(cmd: string, timeoutSecs?: number): Promise { + let p = new Promise((resolve: (data: ShellCmdResult) => void, + reject: (err: BusinessError) => void): void => { + let myCall = new AsyncCallbackWrapper((err: BusinessError, data: ShellCmdResult) => { + if (err.code == 0) { + resolve(data); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + if (timeoutSecs == null) { + this.nativeExecuteShellCommand(cmd, 0, myCall); + } else { + this.nativeExecuteShellCommand(cmd, timeoutSecs as double, myCall); + } + }); + }); + return p; + } + + addAbilityMonitor(monitor: AbilityMonitor, callback: AsyncCallback): void { + let myCall = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeAddAbilityMonitor(monitor, myCall); + }); + } + addAbilityMonitor(monitor: AbilityMonitor): Promise { + let p = + new Promise((resolve: (data: undefined) => void, reject: (err: BusinessError) => void): void => { + let myCall = new AsyncCallbackWrapper((err: BusinessError) => { + if (err.code == 0) { + resolve(undefined); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeAddAbilityMonitor(monitor, myCall); + }); + }); + return p; + } + + startAbility(want: Want, callback: AsyncCallback): void { + let myCall = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartAbility(want, myCall); + }); + } + startAbility(want: Want): Promise { + let p: Promise = + new Promise((resolve: (data: undefined) => void, reject: (err: BusinessError) => void): void => { + let myCall = new AsyncCallbackWrapper((err: BusinessError) => { + if (err.code == 0) { + resolve(undefined); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeStartAbility(want, myCall); + }); + }); + return p; + } + +} diff --git a/frameworks/ets/ets/application/AbilityMonitor.ets b/frameworks/ets/ets/application/AbilityMonitor.ets new file mode 100644 index 00000000000..cccdd0e60f4 --- /dev/null +++ b/frameworks/ets/ets/application/AbilityMonitor.ets @@ -0,0 +1,48 @@ +/* + * 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 UIAbility from '@ohos.app.ability.UIAbility'; + +export default interface AbilityMonitor { + + moduleName: string; + abilityName: string; + onAbilityCreate: (ability: UIAbility) => void; + onAbilityForeground: (ability: UIAbility) => void; + onAbilityBackground: (ability: UIAbility) => void; + onAbilityDestroy: (ability: UIAbility) => void; + onWindowStageCreate: (ability: UIAbility) => void; + onWindowStageRestore: (ability: UIAbility) => void; + onWindowStageDestroy: (ability: UIAbility) => void; + +} + +class AbilityMonitorInner implements AbilityMonitor { + moduleName: string = ""; + abilityName: string = ""; + onAbilityCreate: (ability: UIAbility) => void = (ability: UIAbility) => { + }; + onAbilityForeground: (ability: UIAbility) => void = (ability: UIAbility) => { + }; + onAbilityBackground: (ability: UIAbility) => void = (ability: UIAbility) => { + }; + onAbilityDestroy: (ability: UIAbility) => void = (ability: UIAbility) => { + }; + onWindowStageCreate: (ability: UIAbility) => void = (ability: UIAbility) => { + }; + onWindowStageRestore: (ability: UIAbility) => void = (ability: UIAbility) => { + }; + onWindowStageDestroy: (ability: UIAbility) => void = (ability: UIAbility) => { + }; +} \ No newline at end of file diff --git a/frameworks/ets/ets/application/abilityDelegatorArgs.ets b/frameworks/ets/ets/application/abilityDelegatorArgs.ets new file mode 100644 index 00000000000..81c1bd06670 --- /dev/null +++ b/frameworks/ets/ets/application/abilityDelegatorArgs.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +export interface AbilityDelegatorArgs { + bundleName: string; + parameters: Record; + testCaseNames: string; + testRunnerClassName: string; + } + + class AbilityDelegatorArgsInner implements AbilityDelegatorArgs { + public bundleName: string = ''; + public parameters: Record = {}; + public testCaseNames: string = ''; + public testRunnerClassName: string = ''; + } diff --git a/frameworks/ets/ets/application/shellCmdResult.ets b/frameworks/ets/ets/application/shellCmdResult.ets new file mode 100644 index 00000000000..5250b377d4d --- /dev/null +++ b/frameworks/ets/ets/application/shellCmdResult.ets @@ -0,0 +1,26 @@ +/* + * 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. + */ + +interface ShellCmdResult { + stdResult: string; + exitCode: number; + } + + class ShellCmdResultImpl implements ShellCmdResult { + public stdResult: string = ''; + public exitCode: number = 0; + } + + export default ShellCmdResult; diff --git a/frameworks/ets/ets/utils/AbilityUtils.ets b/frameworks/ets/ets/utils/AbilityUtils.ets index 573c5d3a207..268648fb166 100644 --- a/frameworks/ets/ets/utils/AbilityUtils.ets +++ b/frameworks/ets/ets/utils/AbilityUtils.ets @@ -13,12 +13,25 @@ * limitations under the License. */ +import { BusinessError, AsyncCallback } from '@ohos.base'; import hilog from '@ohos.hilog' const DOMAIN_ID = 0xD001300; const TAG = 'AbilityUtils'; const LEVEL = 100; +export default class AsyncCallbackWrapper { + private myFun_:AsyncCallback = (err: BusinessError, data: T) => {} + + constructor(myFun:AsyncCallback){ + this.myFun_ = myFun; + } + + invoke(err: BusinessError, data: T) : void { + this.myFun_(err, data); + } +} + export class AbilityUtils { public static getClassType(obj: Object): ClassType | undefined { try { diff --git a/frameworks/js/napi/app/ability_delegator/BUILD.gn b/frameworks/js/napi/app/ability_delegator/BUILD.gn index 8a4fe681381..c94532cd49d 100644 --- a/frameworks/js/napi/app/ability_delegator/BUILD.gn +++ b/frameworks/js/napi/app/ability_delegator/BUILD.gn @@ -60,6 +60,7 @@ template("delegator") { "ipc:ipc_napi", "ipc:ipc_single", "napi:ace_napi", + "runtime_core:ani", ] cflags_cc = [] diff --git a/frameworks/js/napi/app/ability_delegator/ability_monitor.cpp b/frameworks/js/napi/app/ability_delegator/ability_monitor.cpp index 5eab898a5a9..950c81b07a0 100644 --- a/frameworks/js/napi/app/ability_delegator/ability_monitor.cpp +++ b/frameworks/js/napi/app/ability_delegator/ability_monitor.cpp @@ -32,82 +32,138 @@ AbilityMonitor::AbilityMonitor(const std::string &name, const std::string &modul : IAbilityMonitor(name, moduleName), jsMonitor_(jsAbilityMonitor) {} -void AbilityMonitor::OnAbilityStart(const std::weak_ptr &abilityObj) +void AbilityMonitor::OnAbilityStart(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return; + } + auto jsbaseProperty = std::static_pointer_cast(baseProperty); + if (jsMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "jsMonitor_ is nullptr"); return; } - jsMonitor_->OnAbilityCreate(abilityObj); + jsMonitor_->OnAbilityCreate(jsbaseProperty->object_); } -void AbilityMonitor::OnAbilityForeground(const std::weak_ptr &abilityObj) +void AbilityMonitor::OnAbilityForeground(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return; + } + auto jsbaseProperty = std::static_pointer_cast(baseProperty); + if (jsMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "jsMonitor_ is nullptr"); return; } - jsMonitor_->OnAbilityForeground(abilityObj); + jsMonitor_->OnAbilityForeground(jsbaseProperty->object_); } -void AbilityMonitor::OnAbilityBackground(const std::weak_ptr &abilityObj) +void AbilityMonitor::OnAbilityBackground(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return; + } + auto jsbaseProperty = std::static_pointer_cast(baseProperty); + if (jsMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "jsMonitor_ is nullptr"); return; } - jsMonitor_->OnAbilityBackground(abilityObj); + jsMonitor_->OnAbilityBackground(jsbaseProperty->object_); } -void AbilityMonitor::OnAbilityStop(const std::weak_ptr &abilityObj) +void AbilityMonitor::OnAbilityStop(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return; + } + auto jsbaseProperty = std::static_pointer_cast(baseProperty); + if (jsMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "jsMonitor_ is nullptr"); return; } - jsMonitor_->OnAbilityDestroy(abilityObj); + jsMonitor_->OnAbilityDestroy(jsbaseProperty->object_); } -void AbilityMonitor::OnWindowStageCreate(const std::weak_ptr &abilityObj) +void AbilityMonitor::OnWindowStageCreate(const std::weak_ptr &abilityObj) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGI(AAFwkTag::DELEGATOR, "called"); + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return; + } + auto jsbaseProperty = std::static_pointer_cast(baseProperty); + if (jsMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "jsMonitor_ is nullptr"); return; } - jsMonitor_->OnWindowStageCreate(abilityObj); + jsMonitor_->OnWindowStageCreate(jsbaseProperty->object_); } -void AbilityMonitor::OnWindowStageRestore(const std::weak_ptr &abilityObj) +void AbilityMonitor::OnWindowStageRestore(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return; + } + auto jsbaseProperty = std::static_pointer_cast(baseProperty); + if (jsMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "jsMonitor_ is nullptr"); return; } - jsMonitor_->OnWindowStageRestore(abilityObj); + jsMonitor_->OnWindowStageRestore(jsbaseProperty->object_); } -void AbilityMonitor::OnWindowStageDestroy(const std::weak_ptr &abilityObj) +void AbilityMonitor::OnWindowStageDestroy(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); + auto baseProperty = abilityObj.lock(); + if (!baseProperty) { + TAG_LOGE(AAFwkTag::DELEGATOR, "abilityObj is expired"); + return; + } + auto jsbaseProperty = std::static_pointer_cast(baseProperty); + if (jsMonitor_ == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "jsMonitor_ is nullptr"); return; } - jsMonitor_->OnWindowStageDestroy(abilityObj); + jsMonitor_->OnWindowStageDestroy(jsbaseProperty->object_); } } // namespace AbilityDelegatorJs } // namespace OHOS diff --git a/frameworks/js/napi/app/ability_delegator/ability_monitor.h b/frameworks/js/napi/app/ability_delegator/ability_monitor.h index 433a48b4828..37bb4b5b2fb 100644 --- a/frameworks/js/napi/app/ability_delegator/ability_monitor.h +++ b/frameworks/js/napi/app/ability_delegator/ability_monitor.h @@ -56,49 +56,49 @@ public: * * @param abilityObj Indicates the ability object. */ - void OnAbilityStart(const std::weak_ptr &abilityObj) override; + void OnAbilityStart(const std::weak_ptr &abilityObj) override; /** * Called when ability is in foreground. * * @param abilityObj Indicates the ability object. */ - void OnAbilityForeground(const std::weak_ptr &abilityObj) override; + void OnAbilityForeground(const std::weak_ptr &abilityObj) override; /** * Called when ability is in background. * * @param abilityObj Indicates the ability object. */ - void OnAbilityBackground(const std::weak_ptr &abilityObj) override; + void OnAbilityBackground(const std::weak_ptr &abilityObj) override; /** * Called when ability is stopped. * * @param abilityObj Indicates the ability object. */ - void OnAbilityStop(const std::weak_ptr &abilityObj) override; + void OnAbilityStop(const std::weak_ptr &abilityObj) override; /** * Called when window stage is created. * * @param abilityObj Indicates the ability object. */ - void OnWindowStageCreate(const std::weak_ptr &abilityObj) override; + void OnWindowStageCreate(const std::weak_ptr &abilityObj) override; /** * Called when window stage is restored. * * @param abilityObj Indicates the ability object. */ - void OnWindowStageRestore(const std::weak_ptr &abilityObj) override; + void OnWindowStageRestore(const std::weak_ptr &abilityObj) override; /** * Called when window stage is destroyed. * * @param abilityObj Indicates the ability object. */ - void OnWindowStageDestroy(const std::weak_ptr &abilityObj) override; + void OnWindowStageDestroy(const std::weak_ptr &abilityObj) override; private: std::shared_ptr jsMonitor_; diff --git a/frameworks/js/napi/app/ability_delegator/js_ability_delegator.cpp b/frameworks/js/napi/app/ability_delegator/js_ability_delegator.cpp index b150907480c..34e943e9bd0 100644 --- a/frameworks/js/napi/app/ability_delegator/js_ability_delegator.cpp +++ b/frameworks/js/napi/app/ability_delegator/js_ability_delegator.cpp @@ -127,7 +127,8 @@ JSAbilityDelegator::JSAbilityDelegator() { auto delegator = AbilityDelegatorRegistry::GetAbilityDelegator(); if (delegator) { - auto clearFunc = [](const std::shared_ptr &property) { + auto clearFunc = [](const std::shared_ptr &baseProperty) { + auto property = std::static_pointer_cast(baseProperty); TAG_LOGI(AAFwkTag::DELEGATOR, "clearFunc called"); if (!property) { TAG_LOGE(AAFwkTag::DELEGATOR, "null property"); @@ -524,16 +525,17 @@ napi_value JSAbilityDelegator::OnWaitAbilityMonitor(napi_env env, NapiCallbackIn return; } - std::shared_ptr property = opt.hasTimeoutPara ? + std::shared_ptr property = opt.hasTimeoutPara ? delegator->WaitAbilityMonitor(monitor, timeout) : delegator->WaitAbilityMonitor(monitor); - if (!property || property->object_.expired()) { + auto jsProperty = std::static_pointer_cast(property); + if (!jsProperty || jsProperty->object_.expired()) { TAG_LOGE(AAFwkTag::DELEGATOR, "invalid property"); return; } - abilityObjectBox->object_ = property->object_; + abilityObjectBox->object_ = jsProperty->object_; std::unique_lock lck(g_mutexAbilityRecord); - g_abilityRecord.emplace(property->object_, property->token_); + g_abilityRecord.emplace(jsProperty->object_, jsProperty->token_); }; NapiAsyncTask::CompleteCallback complete = [abilityObjectBox](napi_env env, NapiAsyncTask &task, int32_t status) { @@ -795,15 +797,16 @@ napi_value JSAbilityDelegator::OnGetCurrentTopAbility(napi_env env, NapiCallback } auto property = delegator->GetCurrentTopAbility(); - if (!property || property->object_.expired()) { - TAG_LOGE(AAFwkTag::DELEGATOR, "invalid property"); + auto jsProperty = std::static_pointer_cast(property); + if (!jsProperty || jsProperty->object_.expired()) { + TAG_LOGE(AAFwkTag::DELEGATOR, "invalid jsProperty"); task.Reject(env, CreateJsError(env, COMMON_FAILED, "Calling GetCurrentTopAbility failed.")); } else { { std::unique_lock lck(g_mutexAbilityRecord); - g_abilityRecord.emplace(property->object_, property->token_); + g_abilityRecord.emplace(jsProperty->object_, jsProperty->token_); } - ResolveWithNoError(env, task, property->object_.lock()->GetNapiValue()); + ResolveWithNoError(env, task, jsProperty->object_.lock()->GetNapiValue()); } }; diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index f250b62c7ee..4a62d026d09 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -823,6 +823,7 @@ ohos_shared_library("uiabilitykit_native") { "ipc:ipc_napi", "json:nlohmann_json_static", "resource_management:global_resmgr", + "runtime_core:ani", "samgr:samgr_proxy", ] public_external_deps = [ diff --git a/frameworks/native/appkit/BUILD.gn b/frameworks/native/appkit/BUILD.gn index 68083dd928c..b9ebeeceefc 100644 --- a/frameworks/native/appkit/BUILD.gn +++ b/frameworks/native/appkit/BUILD.gn @@ -474,6 +474,7 @@ ohos_shared_library("appkit_delegator") { include_dirs = [ "native", + "${ability_runtime_path}/ets_environment/interfaces/inner_api", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/ability_delegator/include", @@ -490,6 +491,7 @@ ohos_shared_library("appkit_delegator") { "${ability_runtime_native_path}/appkit/ability_delegator/ability_delegator_args.cpp", "${ability_runtime_native_path}/appkit/ability_delegator/ability_delegator_registry.cpp", "${ability_runtime_native_path}/appkit/ability_delegator/delegator_thread.cpp", + "${ability_runtime_native_path}/appkit/ability_delegator/runner_runtime/ets_test_runner.cpp", "${ability_runtime_native_path}/appkit/ability_delegator/iability_delegator.cpp", "${ability_runtime_native_path}/appkit/ability_delegator/iability_monitor.cpp", "${ability_runtime_native_path}/appkit/ability_delegator/iability_stage_monitor.cpp", @@ -525,6 +527,7 @@ ohos_shared_library("appkit_delegator") { "ipc:ipc_core", "json:nlohmann_json_static", "napi:ace_napi", + "runtime_core:ani", "samgr:samgr_proxy", ] diff --git a/frameworks/native/appkit/ability_delegator/ability_delegator.cpp b/frameworks/native/appkit/ability_delegator/ability_delegator.cpp index 1449f61557f..0c9ef8125c7 100644 --- a/frameworks/native/appkit/ability_delegator/ability_delegator.cpp +++ b/frameworks/native/appkit/ability_delegator/ability_delegator.cpp @@ -115,7 +115,7 @@ size_t AbilityDelegator::GetStageMonitorsNum() } -std::shared_ptr AbilityDelegator::WaitAbilityMonitor( +std::shared_ptr AbilityDelegator::WaitAbilityMonitor( const std::shared_ptr &monitor) { if (!monitor) { @@ -151,7 +151,7 @@ std::shared_ptr AbilityDelegator::WaitAbilityStag return stage; } -std::shared_ptr AbilityDelegator::WaitAbilityMonitor( +std::shared_ptr AbilityDelegator::WaitAbilityMonitor( const std::shared_ptr &monitor, const int64_t timeoutMs) { if (!monitor) { @@ -208,7 +208,7 @@ AbilityDelegator::AbilityState AbilityDelegator::GetAbilityState(const sptrlifecycleState_); } -std::shared_ptr AbilityDelegator::GetCurrentTopAbility() +std::shared_ptr AbilityDelegator::GetCurrentTopAbility() { AppExecFwk::ElementName elementName = AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility(); std::string bundleName = elementName.GetBundleName(); @@ -367,7 +367,7 @@ void AbilityDelegator::Print(const std::string &msg) testObserver->TestStatus(realMsg, 0); } -void AbilityDelegator::PostPerformStart(const std::shared_ptr &ability) +void AbilityDelegator::PostPerformStart(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); @@ -388,9 +388,8 @@ void AbilityDelegator::PostPerformStart(const std::shared_ptrMatch(ability, true)) { - monitor->OnAbilityStart(ability->object_); + monitor->OnAbilityStart(ability); } } } @@ -417,7 +416,7 @@ void AbilityDelegator::PostPerformStageStart(const std::shared_ptr &ability) +void AbilityDelegator::PostPerformScenceCreated(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); @@ -438,14 +437,13 @@ void AbilityDelegator::PostPerformScenceCreated(const std::shared_ptrMatch(ability)) { - monitor->OnWindowStageCreate(ability->object_); + if (monitor->Match(ability, true)) { + monitor->OnWindowStageCreate(ability); } } } -void AbilityDelegator::PostPerformScenceRestored(const std::shared_ptr &ability) +void AbilityDelegator::PostPerformScenceRestored(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); @@ -466,14 +464,13 @@ void AbilityDelegator::PostPerformScenceRestored(const std::shared_ptrMatch(ability)) { - monitor->OnWindowStageRestore(ability->object_); + if (monitor->Match(ability, true)) { + monitor->OnWindowStageRestore(ability); } } } -void AbilityDelegator::PostPerformScenceDestroyed(const std::shared_ptr &ability) +void AbilityDelegator::PostPerformScenceDestroyed(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); @@ -494,14 +491,13 @@ void AbilityDelegator::PostPerformScenceDestroyed(const std::shared_ptrMatch(ability)) { - monitor->OnWindowStageDestroy(ability->object_); + if (monitor->Match(ability, true)) { + monitor->OnWindowStageDestroy(ability); } } } -void AbilityDelegator::PostPerformForeground(const std::shared_ptr &ability) +void AbilityDelegator::PostPerformForeground(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); @@ -522,14 +518,13 @@ void AbilityDelegator::PostPerformForeground(const std::shared_ptrMatch(ability)) { - monitor->OnAbilityForeground(ability->object_); + if (monitor->Match(ability, true)) { + monitor->OnAbilityForeground(ability); } } } -void AbilityDelegator::PostPerformBackground(const std::shared_ptr &ability) +void AbilityDelegator::PostPerformBackground(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "called"); @@ -550,14 +545,13 @@ void AbilityDelegator::PostPerformBackground(const std::shared_ptrMatch(ability)) { - monitor->OnAbilityBackground(ability->object_); + if (monitor->Match(ability, true)) { + monitor->OnAbilityBackground(ability); } } } -void AbilityDelegator::PostPerformStop(const std::shared_ptr &ability) +void AbilityDelegator::PostPerformStop(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "Enter"); @@ -578,9 +572,8 @@ void AbilityDelegator::PostPerformStop(const std::shared_ptrMatch(ability)) { - monitor->OnAbilityStop(ability->object_); + if (monitor->Match(ability, true)) { + monitor->OnAbilityStop(ability); } } @@ -613,7 +606,7 @@ AbilityDelegator::AbilityState AbilityDelegator::ConvertAbilityState( return abilityState; } -void AbilityDelegator::ProcessAbilityProperties(const std::shared_ptr &ability) +void AbilityDelegator::ProcessAbilityProperties(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "Enter"); @@ -636,7 +629,7 @@ void AbilityDelegator::ProcessAbilityProperties(const std::shared_ptr &ability) +void AbilityDelegator::RemoveAbilityProperty(const std::shared_ptr &ability) { TAG_LOGD(AAFwkTag::DELEGATOR, "called"); @@ -654,7 +647,7 @@ void AbilityDelegator::RemoveAbilityProperty(const std::shared_ptr AbilityDelegator::FindPropertyByToken(const sptr &token) +std::shared_ptr AbilityDelegator::FindPropertyByToken(const sptr &token) { TAG_LOGI(AAFwkTag::DELEGATOR, "Enter"); @@ -678,7 +671,7 @@ std::shared_ptr AbilityDelegator::FindPropertyByToken return {}; } -std::shared_ptr AbilityDelegator::FindPropertyByName(const std::string &name) +std::shared_ptr AbilityDelegator::FindPropertyByName(const std::string &name) { TAG_LOGI(AAFwkTag::DELEGATOR, "find property by %{public}s", name.c_str()); @@ -741,7 +734,7 @@ void AbilityDelegator::RegisterClearFunc(ClearFunc func) clearFunc_ = func; } -inline void AbilityDelegator::CallClearFunc(const std::shared_ptr &ability) +inline void AbilityDelegator::CallClearFunc(const std::shared_ptr &ability) { TAG_LOGI(AAFwkTag::DELEGATOR, "Enter"); if (clearFunc_) { diff --git a/frameworks/native/appkit/ability_delegator/iability_monitor.cpp b/frameworks/native/appkit/ability_delegator/iability_monitor.cpp index 17bf4c740bd..4a6238cb047 100644 --- a/frameworks/native/appkit/ability_delegator/iability_monitor.cpp +++ b/frameworks/native/appkit/ability_delegator/iability_monitor.cpp @@ -27,7 +27,7 @@ IAbilityMonitor::IAbilityMonitor(const std::string &abilityName, const std::string &moduleName) : abilityName_(abilityName), moduleName_(moduleName) {} -bool IAbilityMonitor::Match(const std::shared_ptr &ability, bool isNotify) +bool IAbilityMonitor::Match(const std::shared_ptr &ability, bool isNotify) { if (!ability) { TAG_LOGW(AAFwkTag::DELEGATOR, "invalid ability property"); @@ -69,12 +69,12 @@ bool IAbilityMonitor::Match(const std::shared_ptr &ab return true; } -std::shared_ptr IAbilityMonitor::WaitForAbility() +std::shared_ptr IAbilityMonitor::WaitForAbility() { return WaitForAbility(MAX_TIME_OUT); } -std::shared_ptr IAbilityMonitor::WaitForAbility(const int64_t timeoutMs) +std::shared_ptr IAbilityMonitor::WaitForAbility(const int64_t timeoutMs) { auto realTime = timeoutMs; if (timeoutMs <= 0) { @@ -92,25 +92,25 @@ std::shared_ptr IAbilityMonitor::WaitForAbility(const return matchedAbility_; } -void IAbilityMonitor::OnAbilityStart(const std::weak_ptr &abilityObj) +void IAbilityMonitor::OnAbilityStart(const std::weak_ptr &abilityObj) {} -void IAbilityMonitor::OnAbilityForeground(const std::weak_ptr &abilityObj) +void IAbilityMonitor::OnAbilityForeground(const std::weak_ptr &abilityObj) {} -void IAbilityMonitor::OnAbilityBackground(const std::weak_ptr &abilityObj) +void IAbilityMonitor::OnAbilityBackground(const std::weak_ptr &abilityObj) {} -void IAbilityMonitor::OnAbilityStop(const std::weak_ptr &abilityObj) +void IAbilityMonitor::OnAbilityStop(const std::weak_ptr &abilityObj) {} -void IAbilityMonitor::OnWindowStageCreate(const std::weak_ptr &abilityObj) +void IAbilityMonitor::OnWindowStageCreate(const std::weak_ptr &abilityObj) {} -void IAbilityMonitor::OnWindowStageRestore(const std::weak_ptr &abilityObj) +void IAbilityMonitor::OnWindowStageRestore(const std::weak_ptr &abilityObj) {} -void IAbilityMonitor::OnWindowStageDestroy(const std::weak_ptr &abilityObj) +void IAbilityMonitor::OnWindowStageDestroy(const std::weak_ptr &abilityObj) {} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/native/appkit/ability_delegator/runner_runtime/ets_test_runner.cpp b/frameworks/native/appkit/ability_delegator/runner_runtime/ets_test_runner.cpp new file mode 100644 index 00000000000..79e99fb7333 --- /dev/null +++ b/frameworks/native/appkit/ability_delegator/runner_runtime/ets_test_runner.cpp @@ -0,0 +1,179 @@ +/* + * 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 + +#include "ability_delegator_registry.h" +#include "hilog_tag_wrapper.h" +#include "runner_runtime/ets_test_runner.h" + +namespace OHOS { +namespace RunnerRuntime { +namespace { +const std::string CAPITALTESTRUNNER = "/ets/TestRunner/"; +const std::string LOWERCASETESTRUNNER = "/ets/testrunner/"; +} // namespace + +std::unique_ptr ETSTestRunner::Create(const std::unique_ptr &runtime, + const std::shared_ptr &args, const AppExecFwk::BundleInfo &bundleInfo) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "ETSTestRunner Create"); + if (!runtime) { + TAG_LOGE(AAFwkTag::DELEGATOR, "invalid runtime"); + return nullptr; + } + + if (!args) { + TAG_LOGE(AAFwkTag::DELEGATOR, "invalid args"); + return nullptr; + } + + auto pTestRunner = new (std::nothrow) ETSTestRunner(static_cast(*runtime), args, bundleInfo); + if (!pTestRunner) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null testRunner"); + return nullptr; + } + + return std::unique_ptr(pTestRunner); +} + +ETSTestRunner::ETSTestRunner( + ETSRuntime &etsRuntime, const std::shared_ptr &args, const AppExecFwk::BundleInfo &bundleInfo) + : etsRuntime_(etsRuntime) +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "ETSTestRunner constructor"); + std::string moduleName; + if (args) { + std::string srcPath; + if (bundleInfo.hapModuleInfos.back().isModuleJson) { + srcPath.append(args->GetTestModuleName()); + if (args->GetTestRunnerClassName().find("/") == std::string::npos) { + srcPath.append(LOWERCASETESTRUNNER); + } + moduleName = args->GetTestModuleName(); + } else { + srcPath.append(args->GetTestPackageName()); + srcPath.append("/assets/sts/TestRunner/"); + moduleName = args->GetTestPackageName(); + } + srcPath.append(args->GetTestRunnerClassName()); + srcPath.append(".abc"); + srcPath_ = srcPath; + } + TAG_LOGI(AAFwkTag::DELEGATOR, "srcPath: %{public}s", srcPath_.c_str()); + + if (!moduleName.empty()) { + for (auto hapModuleInfo : bundleInfo.hapModuleInfos) { + if ((hapModuleInfo.isModuleJson && hapModuleInfo.name == moduleName) || + hapModuleInfo.package == moduleName) { + hapPath_ = hapModuleInfo.hapPath; + break; + } + } + } else { + hapPath_ = bundleInfo.hapModuleInfos.back().hapPath; + } + AppExecFwk::HapModuleInfo entryHapModuleInfo; + if (!bundleInfo.hapModuleInfos.empty()) { + for (auto hapModuleInfo : bundleInfo.hapModuleInfos) { + if (hapModuleInfo.moduleType == AppExecFwk::ModuleType::ENTRY) { + entryHapModuleInfo = hapModuleInfo; + break; + } + } + } + TAG_LOGI(AAFwkTag::DELEGATOR, "hapPath: %{public}s", hapPath_.c_str()); + moduleName.append("::").append("TestRunner"); + etsTestRunnerObj_ = etsRuntime_.LoadModule(moduleName, srcPath_, hapPath_, + bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE, + false, srcPath_); + if (!etsTestRunnerObj_ && srcPath_.find(LOWERCASETESTRUNNER) != std::string::npos) { + TAG_LOGI(AAFwkTag::DELEGATOR, "not found %{public}s , retry load capital address", srcPath_.c_str()); + std::regex src_pattern(LOWERCASETESTRUNNER); + srcPath_ = std::regex_replace(srcPath_, src_pattern, CAPITALTESTRUNNER); + TAG_LOGI(AAFwkTag::DELEGATOR, "capital address is %{public}s", srcPath_.c_str()); + etsTestRunnerObj_ = etsRuntime_.LoadModule(moduleName, srcPath_, hapPath_, + bundleInfo.hapModuleInfos.back().compileMode == AppExecFwk::CompileMode::ES_MODULE, + false, srcPath_); + } +} + +ETSTestRunner::~ETSTestRunner() = default; + +void ETSTestRunner::Prepare() +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "ETSTestRunner Prepare"); + if (etsTestRunnerObj_ != nullptr) { + TAG_LOGI(AAFwkTag::DELEGATOR, "use etsTestRunnerObj_"); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return; + } + if (env->ResetError() != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "ResetError failed"); + } + ani_method method; + ani_status status = ANI_ERROR; + status = env->Class_FindMethod(etsTestRunnerObj_->aniCls, "onPrepare", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "get onPrepare failed status : %{public}d", status); + return; + } + TAG_LOGI(AAFwkTag::DELEGATOR, "get onPrepare success"); + + ani_int result; + status = env->Object_CallMethod_Void(etsTestRunnerObj_->aniObj, method, &result); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void onPrepare failed status : %{public}d", status); + } else { + TAG_LOGI(AAFwkTag::DELEGATOR, "Object_CallMethod_Void onPrepare success"); + } + } +} + +void ETSTestRunner::Run() +{ + TAG_LOGI(AAFwkTag::DELEGATOR, "ETSTestRunner Run"); + if (etsTestRunnerObj_ != nullptr) { + TAG_LOGI(AAFwkTag::DELEGATOR, "use etsTestRunnerObj_"); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::DELEGATOR, "null env"); + return; + } + if (env->ResetError() != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "ResetError failed"); + } + ani_method method; + ani_status status = ANI_ERROR; + status = env->Class_FindMethod(etsTestRunnerObj_->aniCls, "onRun", ":V", &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "get onRun failed status : %{public}d", status); + return; + } + TAG_LOGI(AAFwkTag::DELEGATOR, "get onRun success"); + + ani_int result; + status = env->Object_CallMethod_Void(etsTestRunnerObj_->aniObj, method, &result); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void onRun failed status : %{public}d", status); + } else { + TAG_LOGI(AAFwkTag::DELEGATOR, "Object_CallMethod_Void onRun success"); + } + } +} +} // namespace RunnerRuntime +} // namespace OHOS diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index d15795546b2..04e2ba084c6 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -2461,23 +2461,23 @@ bool MainThread::PrepareAbilityDelegator(const std::shared_ptr & TAG_LOGD(AAFwkTag::APPKIT, "Stage model"); if (applicationCodeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0) { TAG_LOGI(AAFwkTag::DELEGATOR, "create 1.0 testrunner"); - auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); + auto& runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); auto testRunner = TestRunner::Create(runtime, args, false); auto delegator = IAbilityDelegator::Create(runtime, application_->GetAppContext(), std::move(testRunner), record->observer); - AbilityDelegatorRegistry::RegisterInstance(delegator, args, runtime->GetLanguage()); - delegator->SetApiTargetVersion(targetVersion); + AbilityDelegatorRegistry::RegisterInstance(delegator, args, AbilityRuntime::Runtime::Language::JS); + delegator->SetApiTargetVersion(targetVersion); delegator->Prepare(); } if (applicationCodeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2) { TAG_LOGI(AAFwkTag::DELEGATOR, "create 1.2 testrunner"); - auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2); + auto& runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2); auto testRunner = TestRunner::Create(runtime, args, false); auto delegator = IAbilityDelegator::Create(runtime, application_->GetAppContext(), std::move(testRunner), record->observer); - AbilityDelegatorRegistry::RegisterInstance(delegator, args, runtime->GetLanguage()); - delegator->SetApiTargetVersion(targetVersion); + AbilityDelegatorRegistry::RegisterInstance(delegator, args, AbilityRuntime::Runtime::Language::ETS); + delegator->SetApiTargetVersion(targetVersion); delegator->Prepare(); } } else { // FA model @@ -2497,8 +2497,10 @@ bool MainThread::PrepareAbilityDelegator(const std::shared_ptr & return false; } bool isFaJsModel = entryHapModuleInfo.abilityInfos.front().srcLanguage == "js" ? true : false; - static auto runtime = AbilityRuntime::Runtime::Create(options); - auto testRunner = TestRunner::Create(runtime, args, isFaJsModel); + options.langs.emplace(AbilityRuntime::Runtime::Language::JS, true); // default + static auto runtimes = AbilityRuntime::Runtime::CreateRuntimes(options); + for (const auto& runtime : runtimes) { + auto testRunner = TestRunner::Create(runtime, args, isFaJsModel); if (testRunner == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null testRunner"); return false; @@ -2509,9 +2511,10 @@ bool MainThread::PrepareAbilityDelegator(const std::shared_ptr & } auto delegator = std::make_shared( application_->GetAppContext(), std::move(testRunner), record->observer); - AbilityDelegatorRegistry::RegisterInstance(delegator, args, AbilityRuntime::Runtime::Language::JS); + AbilityDelegatorRegistry::RegisterInstance(delegator, args, runtime->GetLanguage()); delegator->SetApiTargetVersion(targetVersion); delegator->Prepare(); + } } return true; } diff --git a/interfaces/kits/native/appkit/ability_delegator/ability_delegator.h b/interfaces/kits/native/appkit/ability_delegator/ability_delegator.h index 19f5e0cc52d..217952afe26 100644 --- a/interfaces/kits/native/appkit/ability_delegator/ability_delegator.h +++ b/interfaces/kits/native/appkit/ability_delegator/ability_delegator.h @@ -69,7 +69,7 @@ public: /** * Definition of cleanup function. */ - using ClearFunc = std::function &)>; + using ClearFunc = std::function &)>; public: static std::shared_ptr Create(const std::shared_ptr& context, @@ -143,7 +143,7 @@ public: * @param monitor, Indicates the specified monitor object. * @return the obtained ability. */ - std::shared_ptr WaitAbilityMonitor(const std::shared_ptr &monitor); + std::shared_ptr WaitAbilityMonitor(const std::shared_ptr &monitor); /** * Waits for the specified monitor and return the obtained abilityStage. @@ -161,7 +161,7 @@ public: * @param timeoutMs, Indicates the specified time out time, in milliseconds. * @return the obtained ability. */ - std::shared_ptr WaitAbilityMonitor( + std::shared_ptr WaitAbilityMonitor( const std::shared_ptr &monitor, const int64_t timeoutMs); /** @@ -194,7 +194,7 @@ public: * * @return the ability that is currently being displayed. */ - std::shared_ptr GetCurrentTopAbility(); + std::shared_ptr GetCurrentTopAbility(); /** * Obtains the name of the thread. @@ -259,7 +259,7 @@ public: * * @param ability, Indicates the ability properties. */ - void PostPerformStart(const std::shared_ptr &ability); + void PostPerformStart(const std::shared_ptr &ability); /** * Saves abilityStage properties when abilityStage is started and notify monitors. @@ -273,42 +273,42 @@ public: * * @param ability, Indicates the ability properties. */ - void PostPerformScenceCreated(const std::shared_ptr &ability); + void PostPerformScenceCreated(const std::shared_ptr &ability); /** * Saves ability properties when scence is restored and notify monitors of state changes. * * @param ability, Indicates the ability properties. */ - void PostPerformScenceRestored(const std::shared_ptr &ability); + void PostPerformScenceRestored(const std::shared_ptr &ability); /** * Saves ability properties when scence is destroyed and notify monitors of state changes. * * @param ability, Indicates the ability properties. */ - void PostPerformScenceDestroyed(const std::shared_ptr &ability); + void PostPerformScenceDestroyed(const std::shared_ptr &ability); /** * Saves ability properties when ability is in the foreground and notify monitors of state changes. * * @param ability, Indicates the ability properties. */ - void PostPerformForeground(const std::shared_ptr &ability); + void PostPerformForeground(const std::shared_ptr &ability); /** * Saves ability properties when ability is in the background and notify monitors of state changes. * * @param ability, Indicates the ability properties. */ - void PostPerformBackground(const std::shared_ptr &ability); + void PostPerformBackground(const std::shared_ptr &ability); /** * Saves ability properties when ability is stopped and notify monitors of state changes. * * @param ability, Indicates the ability properties. */ - void PostPerformStop(const std::shared_ptr &ability); + void PostPerformStop(const std::shared_ptr &ability); /** * Finishes user test. @@ -328,11 +328,11 @@ public: private: AbilityDelegator::AbilityState ConvertAbilityState(const AbilityLifecycleExecutor::LifecycleState lifecycleState); - void ProcessAbilityProperties(const std::shared_ptr &ability); - void RemoveAbilityProperty(const std::shared_ptr &ability); - std::shared_ptr FindPropertyByToken(const sptr &token); - std::shared_ptr FindPropertyByName(const std::string &name); - inline void CallClearFunc(const std::shared_ptr &ability); + void ProcessAbilityProperties(const std::shared_ptr &ability); + void RemoveAbilityProperty(const std::shared_ptr &ability); + std::shared_ptr FindPropertyByToken(const sptr &token); + std::shared_ptr FindPropertyByName(const std::string &name); + inline void CallClearFunc(const std::shared_ptr &ability); private: static constexpr size_t INFORMATION_MAX_LENGTH {1000}; @@ -345,7 +345,7 @@ private: sptr observer_; std::unique_ptr delegatorThread_; - std::list> abilityProperties_; + std::list> abilityProperties_; std::vector> abilityMonitors_; std::vector> abilityStageMonitors_; diff --git a/interfaces/kits/native/appkit/ability_delegator/ability_delegator_infos.h b/interfaces/kits/native/appkit/ability_delegator/ability_delegator_infos.h index 3f649fb32ca..56baa8b1107 100644 --- a/interfaces/kits/native/appkit/ability_delegator/ability_delegator_infos.h +++ b/interfaces/kits/native/appkit/ability_delegator/ability_delegator_infos.h @@ -23,8 +23,12 @@ class NativeReference; namespace OHOS { +namespace AbilityRuntime { + struct ETSNativeReference; +} namespace AppExecFwk { -struct ADelegatorAbilityProperty { + +struct BaseDelegatorAbilityProperty { // token of ability sptr token_; // name of ability @@ -35,10 +39,15 @@ struct ADelegatorAbilityProperty { std::string fullName_; // lifecycle state of ability AbilityLifecycleExecutor::LifecycleState lifecycleState_ {AbilityLifecycleExecutor::LifecycleState::UNINITIALIZED}; - // ability object in jsruntime +}; +struct ADelegatorAbilityProperty : public BaseDelegatorAbilityProperty { std::weak_ptr object_; }; +struct ETSDelegatorAbilityProperty : public BaseDelegatorAbilityProperty { + std::weak_ptr object_; +}; + struct DelegatorAbilityStageProperty { std::string moduleName_; std::string srcEntrance_; diff --git a/interfaces/kits/native/appkit/ability_delegator/iability_monitor.h b/interfaces/kits/native/appkit/ability_delegator/iability_monitor.h index 6a91fec7732..f899604dd30 100644 --- a/interfaces/kits/native/appkit/ability_delegator/iability_monitor.h +++ b/interfaces/kits/native/appkit/ability_delegator/iability_monitor.h @@ -63,7 +63,7 @@ public: * @param isNotify Indicates whether to notify the matched ability to the object who waited. * @return true if match is successful; returns false otherwise. */ - virtual bool Match(const std::shared_ptr &ability, bool isNotify = false); + virtual bool Match(const std::shared_ptr &ability, bool isNotify = false); /** * Waits for and returns the started Ability object that matches the conditions specified in this monitor @@ -72,7 +72,7 @@ public: * * @return the Ability object if any object has started is matched within 5 seconds; returns null otherwise. */ - virtual std::shared_ptr WaitForAbility(); + virtual std::shared_ptr WaitForAbility(); /** * Waits for and returns the started Ability object that matches the conditions specified in this monitor @@ -84,61 +84,61 @@ public: * @return the Ability object if any object has started is matched within the specified time; * returns null otherwise. */ - virtual std::shared_ptr WaitForAbility(const int64_t timeoutMs); + virtual std::shared_ptr WaitForAbility(const int64_t timeoutMs); /** * Called when ability is started. * * @param abilityObj Indicates the ability object. */ - virtual void OnAbilityStart(const std::weak_ptr &abilityObj); + virtual void OnAbilityStart(const std::weak_ptr &abilityObj); /** * Called when ability is in foreground. * * @param abilityObj Indicates the ability object. */ - virtual void OnAbilityForeground(const std::weak_ptr &abilityObj); + virtual void OnAbilityForeground(const std::weak_ptr &abilityObj); /** * Called when ability is in background. * * @param abilityObj Indicates the ability object. */ - virtual void OnAbilityBackground(const std::weak_ptr &abilityObj); + virtual void OnAbilityBackground(const std::weak_ptr &abilityObj); /** * Called when ability is stopped. * * @param abilityObj Indicates the ability object. */ - virtual void OnAbilityStop(const std::weak_ptr &abilityObj); + virtual void OnAbilityStop(const std::weak_ptr &abilityObj); /** * Called when window stage is created. * * @param abilityObj Indicates the ability object. */ - virtual void OnWindowStageCreate(const std::weak_ptr &abilityObj); + virtual void OnWindowStageCreate(const std::weak_ptr &abilityObj); /** * Called when window stage is restored. * * @param abilityObj Indicates the ability object. */ - virtual void OnWindowStageRestore(const std::weak_ptr &abilityObj); + virtual void OnWindowStageRestore(const std::weak_ptr &abilityObj); /** * Called when window stage is destroyed. * * @param abilityObj Indicates the ability object. */ - virtual void OnWindowStageDestroy(const std::weak_ptr &abilityObj); + virtual void OnWindowStageDestroy(const std::weak_ptr &abilityObj); private: std::string abilityName_; std::string moduleName_; - std::shared_ptr matchedAbility_; + std::shared_ptr matchedAbility_; std::condition_variable cvMatch_; std::mutex mMatch_; diff --git a/interfaces/kits/native/appkit/ability_delegator/runner_runtime/ets_test_runner.h b/interfaces/kits/native/appkit/ability_delegator/runner_runtime/ets_test_runner.h new file mode 100644 index 00000000000..c9c58f76fc9 --- /dev/null +++ b/interfaces/kits/native/appkit/ability_delegator/runner_runtime/ets_test_runner.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_ETS_TEST_RUNNER_H +#define OHOS_ABILITY_RUNTIME_ETS_TEST_RUNNER_H + +#include "bundle_info.h" +#include "ets_runtime.h" +#include "test_runner.h" + +class ETSNativeReference; + +namespace OHOS { +namespace RunnerRuntime { +using namespace AppExecFwk; +using namespace AbilityRuntime; + +class ETSTestRunner : public TestRunner { +public: + /** + * Creates a TestRunner instance with the input parameter passed. + * + * @param runtime Indicates the ability runtime. + * @param args Indicates the AbilityDelegatorArgs object. + * @param bundleInfo Indicates the bundle info. + * @return the TestRunner object if JsTestRunner object is created successfully; returns null otherwise. + */ + static std::unique_ptr Create(const std::unique_ptr &runtime, + const std::shared_ptr &args, const AppExecFwk::BundleInfo &bundleInfo); + + /** + * Default deconstructor used to deconstruct. + */ + ~ETSTestRunner() override; + + /** + * Prepares the testing environment for running test code. + */ + void Prepare() override; + + /** + * Runs all test code. + */ + void Run() override; + +private: + ETSTestRunner(ETSRuntime &ETSRuntime, + const std::shared_ptr &args, const AppExecFwk::BundleInfo &bundleInfo); + void CallOnPrepareMethod(ani_env* aniEnv); + void CallOnRunMethod(ani_env* aniEnv); + + ETSRuntime &etsRuntime_; + std::unique_ptr etsTestRunnerObj_; + std::string srcPath_; + std::string hapPath_; +}; +} // namespace RunnerRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_TEST_RUNNER_H diff --git a/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.cpp b/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.cpp index 849f3efa5f7..1c64541ce08 100644 --- a/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.cpp +++ b/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.cpp @@ -33,49 +33,49 @@ MockIabilityMonitor::MockIabilityMonitor(const std::string& abilityName) : IAbil windowStageDestroy_ = false; } -void MockIabilityMonitor::OnAbilityStart(const std::weak_ptr& abilityObj) +void MockIabilityMonitor::OnAbilityStart(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::OnAbilityStart is called"); start_ = true; } -void MockIabilityMonitor::OnAbilityForeground(const std::weak_ptr& abilityObj) +void MockIabilityMonitor::OnAbilityForeground(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::OnAbilityForeground is called"); foreground_ = true; } -void MockIabilityMonitor::OnAbilityBackground(const std::weak_ptr& abilityObj) +void MockIabilityMonitor::OnAbilityBackground(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::OnAbilityBackground is called"); background_ = true; } -void MockIabilityMonitor::OnAbilityStop(const std::weak_ptr& abilityObj) +void MockIabilityMonitor::OnAbilityStop(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::OnAbilityStop is called"); stop_ = true; } -void MockIabilityMonitor::OnWindowStageCreate(const std::weak_ptr& abilityObj) +void MockIabilityMonitor::OnWindowStageCreate(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::OnWindowStageCreate is called"); windowStageCreate_ = true; } -void MockIabilityMonitor::OnWindowStageRestore(const std::weak_ptr& abilityObj) +void MockIabilityMonitor::OnWindowStageRestore(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::OnWindowStageRestore is called"); windowStageRestore_ = true; } -void MockIabilityMonitor::OnWindowStageDestroy(const std::weak_ptr& abilityObj) +void MockIabilityMonitor::OnWindowStageDestroy(const std::weak_ptr &abilityObj) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::OnWindowStageDestroy is called"); windowStageDestroy_ = true; } -bool MockIabilityMonitor::Match(const std::shared_ptr& ability, bool isNotify) +bool MockIabilityMonitor::Match(const std::shared_ptr &ability, bool isNotify) { TAG_LOGI(AAFwkTag::TEST, "MockIabilityMonitor::Match is called"); diff --git a/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.h b/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.h index 7cda62a9808..5f2a8f7e2d7 100644 --- a/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.h +++ b/test/mock/frameworks_kits_appkit_native_test/ability_delegator/mock_iability_monitor.h @@ -28,7 +28,7 @@ public: explicit MockIabilityMonitor(const std::string& abilityName); virtual ~MockIabilityMonitor() = default; - virtual bool Match(const std::shared_ptr& ability, bool isNotify = false); + virtual bool Match(const std::shared_ptr &ability, bool isNotify = false); std::shared_ptr waitForAbility() { @@ -39,14 +39,14 @@ public: return std::make_shared(); }; - void OnAbilityStart(const std::weak_ptr& abilityObj) override; - void OnAbilityForeground(const std::weak_ptr& abilityObj) override; - void OnAbilityBackground(const std::weak_ptr& abilityObj) override; - void OnAbilityStop(const std::weak_ptr& abilityObj) override; + void OnAbilityStart(const std::weak_ptr &abilityObj) override; + void OnAbilityForeground(const std::weak_ptr &abilityObj) override; + void OnAbilityBackground(const std::weak_ptr &abilityObj) override; + void OnAbilityStop(const std::weak_ptr &abilityObj) override; - void OnWindowStageCreate(const std::weak_ptr& abilityObj) override; - void OnWindowStageRestore(const std::weak_ptr& abilityObj) override; - void OnWindowStageDestroy(const std::weak_ptr& abilityObj) override; + void OnWindowStageCreate(const std::weak_ptr &abilityObj) override; + void OnWindowStageRestore(const std::weak_ptr &abilityObj) override; + void OnWindowStageDestroy(const std::weak_ptr &abilityObj) override; bool start_; bool foreground_; diff --git a/test/moduletest/ability_delegator_test/BUILD.gn b/test/moduletest/ability_delegator_test/BUILD.gn index 649a72006d8..4d6378c26b5 100644 --- a/test/moduletest/ability_delegator_test/BUILD.gn +++ b/test/moduletest/ability_delegator_test/BUILD.gn @@ -134,6 +134,7 @@ ohos_moduletest("ability_delegator_registry_moduletest") { "hilog:libhilog", "init:libbegetutil", "ipc:ipc_core", + "runtime_core:ani", "napi:ace_napi", ] } @@ -164,6 +165,7 @@ ohos_moduletest("iability_monitor_moduletest") { "googletest:gtest_main", "hilog:libhilog", "ipc:ipc_core", + "runtime_core:ani", "napi:ace_napi", ] } @@ -198,6 +200,8 @@ ohos_moduletest("ability_delegator_moduletest") { "hilog:libhilog", "init:libbegetutil", "ipc:ipc_core", + "runtime_core:ani", + "napi:ace_napi", ] if (ability_runtime_graphics) { @@ -243,6 +247,7 @@ ohos_moduletest("js_test_runner_moduletest") { "hilog:libhilog", "init:libbegetutil", "ipc:ipc_core", + "runtime_core:ani", "napi:ace_napi", ] } diff --git a/test/unittest/app_recovery_test/BUILD.gn b/test/unittest/app_recovery_test/BUILD.gn index b0e3ce8f526..93b2719aebf 100644 --- a/test/unittest/app_recovery_test/BUILD.gn +++ b/test/unittest/app_recovery_test/BUILD.gn @@ -72,6 +72,7 @@ ohos_unittest("AppRecoveryUnitTest") { "image_framework:image_native", "ipc:ipc_core", "napi:ace_napi", + "runtime_core:ani", "window_manager:libdm", "window_manager:libwm", "window_manager:windowstage_kit", diff --git a/test/unittest/cj_ability_delegator_args_test/BUILD.gn b/test/unittest/cj_ability_delegator_args_test/BUILD.gn index a1eb3f55943..42021c99934 100644 --- a/test/unittest/cj_ability_delegator_args_test/BUILD.gn +++ b/test/unittest/cj_ability_delegator_args_test/BUILD.gn @@ -82,6 +82,7 @@ ohos_unittest("cj_ability_delegator_args_test") { "napi:cj_bind_ffi", "napi:cj_bind_native", "resource_management:global_resmgr", + "runtime_core:ani", "samgr:samgr_proxy", "window_manager:libwsutils", "window_manager:scene_session", diff --git a/test/unittest/cj_ability_delegator_test/BUILD.gn b/test/unittest/cj_ability_delegator_test/BUILD.gn index 118a54889bb..3aa3163f0fc 100644 --- a/test/unittest/cj_ability_delegator_test/BUILD.gn +++ b/test/unittest/cj_ability_delegator_test/BUILD.gn @@ -82,6 +82,7 @@ ohos_unittest("cj_ability_delegator_test") { "napi:cj_bind_native", "resource_management:global_resmgr", "samgr:samgr_proxy", + "runtime_core:ani", "window_manager:libwsutils", "window_manager:scene_session", ] diff --git a/test/unittest/cj_application_context_test/BUILD.gn b/test/unittest/cj_application_context_test/BUILD.gn index 5563d277b2a..5ab302f5417 100644 --- a/test/unittest/cj_application_context_test/BUILD.gn +++ b/test/unittest/cj_application_context_test/BUILD.gn @@ -84,6 +84,7 @@ ohos_unittest("cj_application_context_test") { "napi:cj_bind_ffi", "napi:cj_bind_native", "resource_management:global_resmgr", + "runtime_core:ani", "samgr:samgr_proxy", "window_manager:cj_window_ffi", "window_manager:libwsutils", diff --git a/test/unittest/cj_test_runner_test/BUILD.gn b/test/unittest/cj_test_runner_test/BUILD.gn index 891969d72a3..8a73533fedb 100644 --- a/test/unittest/cj_test_runner_test/BUILD.gn +++ b/test/unittest/cj_test_runner_test/BUILD.gn @@ -19,6 +19,7 @@ ohos_unittest("cj_test_runner_test") { module_out_path = "ability_runtime/ability_runtime/cj_test_runner_test" include_dirs = [ "native", + "${ability_runtime_path}/ets_environment/interfaces/inner_api", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/ability_delegator/include", @@ -96,6 +97,7 @@ ohos_unittest("cj_test_runner_test") { "napi:ace_napi", "napi:cj_bind_native", "resource_management:global_resmgr", + "runtime_core:ani", "samgr:samgr_proxy", ] diff --git a/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/BUILD.gn b/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/BUILD.gn index 93ebc7c8779..3459096cd32 100644 --- a/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/BUILD.gn +++ b/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/BUILD.gn @@ -112,6 +112,7 @@ ohos_unittest("iability_monitor_unittest") { "hilog:libhilog", "ipc:ipc_core", "napi:ace_napi", + "runtime_core:ani", ] } @@ -147,6 +148,7 @@ ohos_unittest("ability_delegator_unittest") { "init:libbegetutil", "ipc:ipc_core", "napi:ace_napi", + "runtime_core:ani", ] if (ability_runtime_graphics) { @@ -174,6 +176,7 @@ ohos_unittest("delegator_thread_unittest") { "googletest:gtest_main", "hilog:libhilog", "ipc:ipc_core", + "runtime_core:ani", ] } @@ -250,6 +253,7 @@ ohos_unittest("js_test_runner_unittest") { "init:libbegetutil", "ipc:ipc_core", "napi:ace_napi", + "runtime_core:ani", ] } diff --git a/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/ability_delegator_test.cpp b/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/ability_delegator_test.cpp index 59ed7bb9521..291cdc72f71 100644 --- a/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/ability_delegator_test.cpp +++ b/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/ability_delegator_test.cpp @@ -1831,7 +1831,7 @@ HWTEST_F(AbilityDelegatorTest, RegisterClearFuncTest_0100, TestSize.Level1) ASSERT_NE(commonDelegator_, nullptr); // Register clear function. - auto clearFunc = [](const std::shared_ptr &property) { + auto clearFunc = [](const std::shared_ptr &property) { TAG_LOGI(AAFwkTag::TEST, "Clear function is called"); }; commonDelegator_->RegisterClearFunc(clearFunc); diff --git a/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/iability_monitor_test.cpp b/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/iability_monitor_test.cpp index 516a62a1a7f..5f9106bdebe 100644 --- a/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/iability_monitor_test.cpp +++ b/test/unittest/frameworks_kits_appkit_native_test/ability_delegator/iability_monitor_test.cpp @@ -226,7 +226,7 @@ HWTEST_F(IabilityMonitorTest, FuncTest_0100, TestSize.Level1) TAG_LOGI(AAFwkTag::TEST, "test start."); auto iabilityMonitor = new IAbilityMonitor(ABILITY_NAME); ASSERT_NE(iabilityMonitor, nullptr); - auto nativeRef = std::shared_ptr(); + auto nativeRef = std::shared_ptr(); iabilityMonitor->OnAbilityStart(nativeRef); iabilityMonitor->OnAbilityForeground(nativeRef); iabilityMonitor->OnAbilityBackground(nativeRef); diff --git a/test/unittest/js_ui_ability_test/BUILD.gn b/test/unittest/js_ui_ability_test/BUILD.gn index fd77d23885a..efdda0d6043 100644 --- a/test/unittest/js_ui_ability_test/BUILD.gn +++ b/test/unittest/js_ui_ability_test/BUILD.gn @@ -69,6 +69,7 @@ ohos_unittest("js_ui_ability_test") { "ipc:ipc_napi", "libuv:uv", "napi:ace_napi", + "runtime_core:ani", "window_manager:libwsutils", ] } -- Gitee