diff --git a/frameworks/cj/ffi/BUILD.gn b/frameworks/cj/ffi/BUILD.gn index 03df8fc4f901e9ed2625b89d0ed895e1b7ca304b..b9797aa47928e3073e7626a0c69d8642909fee08 100644 --- a/frameworks/cj/ffi/BUILD.gn +++ b/frameworks/cj/ffi/BUILD.gn @@ -69,6 +69,7 @@ ohos_shared_library("cj_ability_ffi") { "napi:ace_napi", "napi:cj_bind_ffi", "napi:cj_bind_native", + "runtime_core:ani", ] sources = [ 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 d909518810b8d955c92bda96a4ac85f8fa1893ed..8d2a9961007957785d74ef7f94cca3fb0912d8a4 100644 --- a/frameworks/ets/ani/ani_common/src/ani_common_util.cpp +++ b/frameworks/ets/ani/ani_common/src/ani_common_util.cpp @@ -93,7 +93,7 @@ bool GetFieldBoolByName(ani_env *env, ani_object object, const char *name, bool return false; } ani_boolean isUndefined = true; - if ((status = env->Reference_IsUndefined(object, &isUndefined)) != ANI_OK) { + if ((status = env->Reference_IsUndefined(field, &isUndefined)) != ANI_OK) { TAG_LOGE(AAFwkTag::ANI, "status: %{public}d", status); return false; } @@ -103,7 +103,7 @@ bool GetFieldBoolByName(ani_env *env, ani_object object, const char *name, bool } ani_boolean aniValue = false; if ((status = env->Object_CallMethodByName_Boolean( - reinterpret_cast(object), "booleanValue", nullptr, &aniValue)) != ANI_OK) { + reinterpret_cast(field), "booleanValue", nullptr, &aniValue)) != ANI_OK) { TAG_LOGE(AAFwkTag::ANI, "status: %{public}d", status); return false; } @@ -143,7 +143,7 @@ bool GetFieldStringByName(ani_env *env, ani_object object, const char *name, std return false; } ani_boolean isUndefined = true; - if ((status = env->Reference_IsUndefined(object, &isUndefined)) != ANI_OK) { + if ((status = env->Reference_IsUndefined(field, &isUndefined)) != ANI_OK) { TAG_LOGE(AAFwkTag::ANI, "status: %{public}d", status); return false; } diff --git a/frameworks/ets/ani/ani_common/src/ani_common_want.cpp b/frameworks/ets/ani/ani_common/src/ani_common_want.cpp index 0f6f8ad80cbbba99916ca1bb186f24dcb14ef313..0fcacfbf24a0f9ecd0c6d9a4d0fe3bb239a6d063 100644 --- a/frameworks/ets/ani/ani_common/src/ani_common_want.cpp +++ b/frameworks/ets/ani/ani_common/src/ani_common_want.cpp @@ -61,6 +61,10 @@ bool InnerUnwrapWantParams(ani_env* env, ani_object wantObject, AAFwk::WantParam ani_object WrapWant(ani_env *env, const AAFwk::Want &want) { TAG_LOGD(AAFwkTag::ANI, "WrapWant called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ANI, "null env"); + return nullptr; + } ani_class cls = nullptr; ani_status status = ANI_ERROR; ani_method method = nullptr; diff --git a/frameworks/ets/ani/enum_convert/ani_enum_convert.h b/frameworks/ets/ani/enum_convert/ani_enum_convert.h index 6234c8bc88fa2631cee71c7abafbbfe85279ba1f..a61bbe0b3d7e02b3b5590b832bb0c42cf6acf98c 100644 --- a/frameworks/ets/ani/enum_convert/ani_enum_convert.h +++ b/frameworks/ets/ani/enum_convert/ani_enum_convert.h @@ -47,7 +47,7 @@ static bool EnumConvert_EtsToNative(ani_env *env, ani_enum_item enumItem, T &res ani_int intValue{}; status = env->EnumItem_GetValue_Int(enumItem, &intValue); if (ANI_OK != status) { - TAG_LOGE(AAFwkTag::EtsRUNTIME, "EnumConvert_EtsToNative failed, status : %{public}d", status); + TAG_LOGE(AAFwkTag::ETSRUNTIME, "EnumConvert_EtsToNative failed, status : %{public}d", status); return false; } result = static_cast(intValue); @@ -56,12 +56,12 @@ static bool EnumConvert_EtsToNative(ani_env *env, ani_enum_item enumItem, T &res ani_string strValue{}; status = env->EnumItem_GetValue_String(enumItem, &strValue); if (ANI_OK != status) { - TAG_LOGE(AAFwkTag::EtsRUNTIME, "EnumItem_GetValue_String failed, status : %{public}d", status); + TAG_LOGE(AAFwkTag::ETSRUNTIME, "EnumItem_GetValue_String failed, status : %{public}d", status); return false; } return GetStdString(env, strValue, result); } else { - TAG_LOGE(AAFwkTag::EtsRUNTIME, "Enum convert failed: type not supported"); + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Enum convert failed: type not supported"); return false; } } @@ -78,7 +78,7 @@ static bool EnumConvert_NativeToEts(ani_env *env, const char *enumName, const T ani_enum aniEnum{}; ani_status status = env->FindEnum(enumName, &aniEnum); if (ANI_OK != status) { - TAG_LOGE(AAFwkTag::EtsRUNTIME, "Enum convert FindEnum failed: %{public}s status: %{public}d", enumName, status); + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Enum convert FindEnum failed: %{public}s status: %{public}d", enumName, status); return false; } constexpr int32_t loopMaxNum = 1000; @@ -86,7 +86,7 @@ static bool EnumConvert_NativeToEts(ani_env *env, const char *enumName, const T ani_enum_item enumItem{}; status = env->Enum_GetEnumItemByIndex(aniEnum, index, &enumItem); if (ANI_OK != status) { - TAG_LOGE(AAFwkTag::EtsRUNTIME, + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Enum convert Enum_GetEnumItemByIndex failed: enumName:%{public}s index:%{public}d status:%{public}d", enumName, index, status); return false; @@ -98,7 +98,7 @@ static bool EnumConvert_NativeToEts(ani_env *env, const char *enumName, const T return true; } } - TAG_LOGE(AAFwkTag::EtsRUNTIME, "EnumConvert_NativeToEts failed enumName: %{public}s", enumName); + TAG_LOGE(AAFwkTag::ETSRUNTIME, "EnumConvert_NativeToEts failed enumName: %{public}s", enumName); return false; } } diff --git a/frameworks/ets/ets/@ohos.app.ability.UIAbility.ets b/frameworks/ets/ets/@ohos.app.ability.UIAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..f53af8d5f3a52ec32b5a2d7f95d02ff0d5803e17 --- /dev/null +++ b/frameworks/ets/ets/@ohos.app.ability.UIAbility.ets @@ -0,0 +1,74 @@ +/* + * 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 AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; +import { AbilityUtils } from './utils/AbilityUtils'; + +export default class UIAbility { + private destroyCallbackPoint: long; + + private native nativeOnDestroyCallback(): void; + + private callOnDestroy(): boolean { + const derivedClassType = AbilityUtils.getClassType(this); + if (derivedClassType === undefined) { + this.onDestroy(); + return false; + } + const uiAbilityClassType = AbilityUtils.getClassType(new UIAbility()); + if (uiAbilityClassType === undefined) { + this.onDestroy(); + return false; + } + const isOverride = AbilityUtils.isOverride(derivedClassType, "onDestroyAsync", uiAbilityClassType); + if (isOverride) { + this.onDestroyAsync().then(() => this.nativeOnDestroyCallback()); + return true; + } + this.onDestroy(); + return false; + } + + launchWant: Want = new Want(); + lastRequestWant: Want = new Want(); + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + } + + onWindowStageDestroy(): void { + } + + onDestroy(): void { + } + + onDestroyAsync(): Promise { + return new Promise((resolve: (a: undefined) => void, reject: (err: Error) => void): void => { + }); + } + + onForeground(): void { + } + + onBackground(): void { + } + + onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { + } +} diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index 9f07fdb1852acb6b8a7f2fdd8836c92349d787e4..26efc114b17d9134c8341923f9b935867e0a6ae8 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -31,6 +31,22 @@ ohos_prebuilt_etc("ability_runtime_base_context_abc_etc") { deps = [ ":ability_runtime_base_context_abc" ] } +generate_static_abc("ability_runtime_ui_ability_abc") { + base_url = "./" + files = [ "./@ohos.app.ability.UIAbility.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_runtime_ui_ability_abc.abc" +} + +ohos_prebuilt_etc("ability_runtime_ui_ability_abc_etc") { + source = "$target_out_dir/ability_runtime_ui_ability_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_runtime_ui_ability_abc" ] +} + generate_static_abc("ability_runtime_ability_utils_abc") { base_url = "./" files = [ "./utils/AbilityUtils.ets" ] @@ -113,9 +129,10 @@ ohos_prebuilt_etc("ability_runtime_want_constant_abc_etc") { group("ets_packages") { deps = [ + ":ability_runtime_base_context_abc_etc", + # ":ability_runtime_ui_ability_abc_etc", ":ability_runtime_ability_constant_abc_etc", ":ability_runtime_ability_utils_abc_etc", - ":ability_runtime_base_context_abc_etc", ":ability_runtime_start_options_abc_etc", ":ability_runtime_want_abc_etc", ":ability_runtime_want_constant_abc_etc", diff --git a/frameworks/js/napi/app/ability_delegator/ability_monitor.cpp b/frameworks/js/napi/app/ability_delegator/ability_monitor.cpp index 5eab898a5a901bbcb2b765670410e073a933a738..950c81b07a06927125620b3d38b27c6374c1b446 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 433a48b48281f7dc729448f8da41a3063d011f87..37bb4b5b2fb95b0a66115bb7cdc31357be394977 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 b150907480c40bea7c8b8c75427d69263f1d10a2..68f4863719a4869011036edebcb1464ac713ea42 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"); @@ -526,14 +527,15 @@ napi_value JSAbilityDelegator::OnWaitAbilityMonitor(napi_env env, NapiCallbackIn 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 52d727221b7f227bb5bed8c59e3ca21fceff1a4d..d21d8b1129d240a23ee1550d664ecd511bba9e73 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -155,6 +155,7 @@ ohos_shared_library("abilitykit_utils") { "${ability_runtime_path}/interfaces/kits/native/ability/native", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", "${ability_runtime_innerkits_path}/ability_manager/include", + "${ability_runtime_innerkits_path}/runtime/include", "${ability_runtime_innerkits_path}/wantagent/include", "${ability_runtime_services_path}/abilitymgr/include/utils", "${ability_runtime_services_path}/abilitymgr/include", @@ -764,6 +765,7 @@ config("uiability_config") { ohos_shared_library("uiabilitykit_native") { include_dirs = [ + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", "${ability_runtime_path}/interfaces/kits/native/ability/native", "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime", "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_extension_ability", @@ -771,6 +773,7 @@ ohos_shared_library("uiabilitykit_native") { ] sources = [ + "${ability_runtime_native_path}/ability/native/ability_runtime/ets_ui_ability.cpp", "${ability_runtime_native_path}/ability/native/ability_runtime/js_ui_ability.cpp", "${ability_runtime_native_path}/ability/native/continuation/distributed/continuation_handler_stage.cpp", "${ability_runtime_native_path}/ability/native/continuation/distributed/continuation_manager_stage.cpp", @@ -802,6 +805,7 @@ ohos_shared_library("uiabilitykit_native") { "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:appkit_delegator", "${ability_runtime_native_path}/insight_intent/insight_intent_context:insightintentcontext", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", "${ability_runtime_path}/utils/global/freeze:freeze_util", "${ability_runtime_services_path}/common:event_report", ] @@ -822,6 +826,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/ability/native/ability_loader.cpp b/frameworks/native/ability/native/ability_loader.cpp index 1c26bd9c57a4b15d9a00a68a3e7fae84e03eb1b1..1a8f740a1c2e2bef0216900f7cb276eea9397081 100644 --- a/frameworks/native/ability/native/ability_loader.cpp +++ b/frameworks/native/ability/native/ability_loader.cpp @@ -52,21 +52,23 @@ Ability *AbilityLoader::GetAbilityByName(const std::string &abilityName) return nullptr; } -AbilityRuntime::Extension *AbilityLoader::GetExtensionByName(const std::string &abilityName) +AbilityRuntime::Extension *AbilityLoader::GetExtensionByName(const std::string &abilityName, + const std::string &language) { auto it = extensions_.find(abilityName); if (it != extensions_.end()) { - return it->second(); + return it->second(language); } TAG_LOGE(AAFwkTag::ABILITY, "failed:%{public}s", abilityName.c_str()); return nullptr; } -AbilityRuntime::UIAbility *AbilityLoader::GetUIAbilityByName(const std::string &abilityName) +AbilityRuntime::UIAbility *AbilityLoader::GetUIAbilityByName(const std::string &abilityName, + const std::string &language) { auto it = uiAbilities_.find(abilityName); if (it != uiAbilities_.end()) { - return it->second(); + return it->second(language); } TAG_LOGE(AAFwkTag::ABILITY, "failed:%{public}s", abilityName.c_str()); return nullptr; diff --git a/frameworks/native/ability/native/ability_runtime/ets_ui_ability.cpp b/frameworks/native/ability/native/ability_runtime/ets_ui_ability.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dac5f017eb87aa6839e24f030f7ed97935305a34 --- /dev/null +++ b/frameworks/native/ability/native/ability_runtime/ets_ui_ability.cpp @@ -0,0 +1,694 @@ +/* + * 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_ui_ability.h" + +#include + +#include "ani_common_want.h" +#include "app_recovery.h" +#include "connection_manager.h" +#include "display_util.h" +#include "ets_data_struct_converter.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "string_wrapper.h" +#ifdef SUPPORT_SCREEN +// #include "ani_window_stage.h" +#endif + +namespace OHOS { +namespace AbilityRuntime { +std::once_flag EtsUIAbility::singletonFlag_; +namespace { +#ifdef SUPPORT_GRAPHICS +const std::string PAGE_STACK_PROPERTY_NAME = "pageStack"; +const std::string SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME = "ohos.extra.param.key.supportContinuePageStack"; +const std::string METHOD_NAME = "WindowScene::GoForeground"; +#endif +#ifdef SUPPORT_SCREEN +constexpr int32_t BASE_DISPLAY_ID_NUM(10); +#endif +constexpr const char *UI_ABILITY_CLASS_NAME = "L@ohos/app/ability/UIAbility/UIAbility;"; + +void OnDestroyPromiseCallback(ani_env *env, ani_object aniObj) +{ + TAG_LOGI(AAFwkTag::UIABILITY, "OnDestroyPromiseCallback called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + ani_long destroyCallbackPtr = 0; + ani_status status = ANI_ERROR; + if ((status = env->Object_GetFieldByName_Long(aniObj, "destroyCallbackPoint", &destroyCallbackPtr)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_GetFieldByName_Long status: %{public}d", status); + return; + } + if (destroyCallbackPtr == 0) { + TAG_LOGE(AAFwkTag::UIABILITY, "null destroyCallbackPtr"); + return; + } + auto *callbackInfo = reinterpret_cast *>(destroyCallbackPtr); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null callbackInfo"); + return; + } + callbackInfo->Call(); + AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo); +} +} // namespace + +UIAbility *EtsUIAbility::Create(const std::unique_ptr &runtime) +{ + return new (std::nothrow) EtsUIAbility(static_cast(*runtime)); +} + +EtsUIAbility::EtsUIAbility(ETSRuntime &etsRuntime) : etsRuntime_(etsRuntime) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "EtsUIAbility called"); +} + +EtsUIAbility::~EtsUIAbility() +{ + TAG_LOGI(AAFwkTag::UIABILITY, "~EtsUIAbility called"); + if (shellContextRef_ && shellContextRef_->aniRef) { + auto env = etsRuntime_.GetAniEnv(); + if (env != nullptr) { + env->GlobalReference_Delete(shellContextRef_->aniRef); + } + } + if (etsWindowStageObj_ && etsWindowStageObj_->aniRef) { + auto env = etsRuntime_.GetAniEnv(); + if (env != nullptr) { + env->GlobalReference_Delete(etsWindowStageObj_->aniRef); + } + } +} + +void EtsUIAbility::Init(std::shared_ptr record, + const std::shared_ptr application, std::shared_ptr &handler, + const sptr &token) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (record == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null localAbilityRecord"); + return; + } + auto abilityInfo = record->GetAbilityInfo(); + if (abilityInfo == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityInfo"); + return; + } + UIAbility::Init(record, application, handler, token); + std::string srcPath(abilityInfo->package); + if (!abilityInfo->isModuleJson) { + srcPath.append("/assets/js/"); + if (!abilityInfo->srcPath.empty()) { + srcPath.append(abilityInfo->srcPath); + } + srcPath.append("/").append(abilityInfo->name).append(".abc"); + } else { + if (abilityInfo->srcEntrance.empty()) { + TAG_LOGE(AAFwkTag::UIABILITY, "empty srcEntrance"); + return; + } + srcPath.append("/"); + srcPath.append(abilityInfo->srcEntrance); + auto pos = srcPath.rfind("."); + if (pos != std::string::npos) { + srcPath.erase(pos); + srcPath.append(".abc"); + } + TAG_LOGD(AAFwkTag::UIABILITY, "etsAbility srcPath: %{public}s", srcPath.c_str()); + } + + std::string moduleName(abilityInfo->moduleName); + moduleName.append("::").append(abilityInfo->name); + SetAbilityContext(abilityInfo, record->GetWant(), moduleName, srcPath, application); +} + +bool EtsUIAbility::BindNativeMethods() +{ + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return false; + } + ani_class cls {}; + ani_status status = env->FindClass(UI_ABILITY_CLASS_NAME, &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "FindClass failed status: %{public}d", status); + return false; + } + std::call_once(singletonFlag_, [&status, env, cls]() { + std::array functions = { + ani_native_function { "nativeOnDestroyCallback", ":V", reinterpret_cast(OnDestroyPromiseCallback) }, + }; + status = env->Class_BindNativeMethods(cls, functions.data(), functions.size()); + }); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Class_BindNativeMethods failed status: %{public}d", status); + return false; + } + return true; +} + +void EtsUIAbility::UpdateAbilityObj( + std::shared_ptr abilityInfo, const std::string &moduleName, const std::string &srcPath) +{ + std::string key = moduleName + "::" + srcPath; + std::unique_ptr moduleObj = nullptr; + etsAbilityObj_ = etsRuntime_.LoadModule(moduleName, srcPath, abilityInfo->hapPath, + abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE, false, abilityInfo->srcEntrance); + if (!BindNativeMethods()) { + TAG_LOGE(AAFwkTag::UIABILITY, "BindNativeMethods failed"); + return; + } +} + +void EtsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, std::shared_ptr want, + const std::string &moduleName, const std::string &srcPath, const std::shared_ptr &application) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "SetAbilityContext called"); + UpdateAbilityObj(abilityInfo, moduleName, srcPath); + if (etsAbilityObj_ == nullptr || abilityContext_ == nullptr || want == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_ or abilityContext_ or want"); + return; + } +} + +void EtsUIAbility::OnStart(const Want &want, sptr sessionInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); + UIAbility::OnStart(want, sessionInfo); + + if (!etsAbilityObj_) { + TAG_LOGE(AAFwkTag::UIABILITY, "not found Ability.js"); + return; + } + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + ani_object wantObj = OHOS::AppExecFwk::WrapWant(env, want); + if (wantObj == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); + return; + } + ani_status status = ANI_ERROR; + if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "launchWant", wantObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "launchWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + auto launchParam = GetLaunchParam(); + if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) { + launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT; + } + ani_object launchParamObj = nullptr; + if (!WrapLaunchParam(env, launchParam, launchParamObj)) { + TAG_LOGE(AAFwkTag::UIABILITY, "WrapLaunchParam failed"); + return; + } + CallObjectMethod(false, "onCreate", nullptr, wantObj, launchParamObj); + TAG_LOGD(AAFwkTag::UIABILITY, "OnStart end"); +} + +void EtsUIAbility::OnStop() +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UIABILITY, "OnStop called"); + if (abilityContext_) { + TAG_LOGD(AAFwkTag::UIABILITY, "set terminating true"); + abilityContext_->SetTerminating(true); + } + UIAbility::OnStop(); + + CallObjectMethod(false, "onDestroy", nullptr); + OnStopCallback(); + TAG_LOGD(AAFwkTag::UIABILITY, "OnStop end"); +} + +void EtsUIAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback) +{ + if (callbackInfo == nullptr) { + isAsyncCallback = false; + OnStop(); + return; + } + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UIABILITY, "OnStop Begin"); + if (abilityContext_) { + TAG_LOGD(AAFwkTag::UIABILITY, "set terminating true"); + abilityContext_->SetTerminating(true); + } + UIAbility::OnStop(); + std::weak_ptr weakPtr = shared_from_this(); + auto asyncCallback = [abilityWeakPtr = weakPtr]() { + auto ability = abilityWeakPtr.lock(); + if (ability == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null ability"); + return; + } + ability->OnStopCallback(); + }; + callbackInfo->Push(asyncCallback); + + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr || etsAbilityObj_ == nullptr) { + isAsyncCallback = false; + OnStop(); + return; + } + + ani_long destroyCallbackPoint = reinterpret_cast(callbackInfo); + ani_status status = + env->Object_SetFieldByName_Long(etsAbilityObj_->aniObj, "destroyCallbackPoint", destroyCallbackPoint); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Long status: %{public}d", status); + return; + } + isAsyncCallback = CallObjectMethod(true, "callOnDestroy", ":Z"); + TAG_LOGD(AAFwkTag::UIABILITY, "callOnDestroy isAsyncCallback: %{public}d", isAsyncCallback); + if (!isAsyncCallback) { + OnStopCallback(); + return; + } + TAG_LOGD(AAFwkTag::UIABILITY, "OnStop end"); +} + +void EtsUIAbility::OnStopCallback() +{ + bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_); + if (ret) { + ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid()); + TAG_LOGD(AAFwkTag::UIABILITY, "the service connection is not disconnected"); + } +} + +#ifdef SUPPORT_SCREEN +void EtsUIAbility::OnSceneCreated() +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); + UIAbility::OnSceneCreated(); + auto etsAppWindowStage = CreateAppWindowStage(); + if (etsAppWindowStage == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAppWindowStage"); + return; + } + UpdateEtsWindowStage(reinterpret_cast(etsAppWindowStage)); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + etsWindowStageObj_ = std::make_shared(); + etsWindowStageObj_->aniObj = etsAppWindowStage; + ani_ref entryObjectRef = nullptr; + env->GlobalReference_Create(etsAppWindowStage, &entryObjectRef); + etsWindowStageObj_->aniRef = entryObjectRef; + CallObjectMethod(false, "onWindowStageCreate", nullptr, etsAppWindowStage); + TAG_LOGD(AAFwkTag::UIABILITY, "OnSceneCreated end"); +} + +void EtsUIAbility::onSceneDestroyed() +{ + TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); + UIAbility::onSceneDestroyed(); + UpdateEtsWindowStage(nullptr); + CallObjectMethod(false, "onWindowStageDestroy", nullptr); + if (scene_ != nullptr) { + auto window = scene_->GetMainWindow(); + if (window != nullptr) { + TAG_LOGD(AAFwkTag::UIABILITY, "unRegisterDisplaymovelistener"); + window->UnregisterDisplayMoveListener(abilityDisplayMoveListener_); + } + } + TAG_LOGD(AAFwkTag::UIABILITY, "onSceneDestroyed end"); +} + +void EtsUIAbility::OnForeground(const Want &want) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); + UIAbility::OnForeground(want); + if (CheckIsSilentForeground()) { + TAG_LOGD(AAFwkTag::UIABILITY, "silent foreground, do not call 'onForeground'"); + return; + } + CallOnForegroundFunc(want); +} + +void EtsUIAbility::CallOnForegroundFunc(const Want &want) +{ + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + ani_status status = ANI_ERROR; + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); + return; + } + if ((status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantRef)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + CallObjectMethod(false, "onForeground", nullptr, wantRef); + TAG_LOGD(AAFwkTag::UIABILITY, "CallOnForegroundFunc end"); +} + +void EtsUIAbility::OnBackground() +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str()); + CallObjectMethod(false, "onBackground", nullptr); + UIAbility::OnBackground(); + TAG_LOGD(AAFwkTag::UIABILITY, "OnBackground end"); +} + +ani_object EtsUIAbility::CreateAppWindowStage() +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return nullptr; + } + auto scene = GetScene(); + if (scene == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "scene not found"); + return nullptr; + } + ani_object etsWindowStage = nullptr; + // ani_object etsWindowStage = CreateAniWindowStage(env, scene); + if (etsWindowStage == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsWindowStage"); + return nullptr; + } + return etsWindowStage; +} + +void EtsUIAbility::GetPageStackFromWant(const Want &want, std::string &pageStack) +{ + auto stringObj = AAFwk::IString::Query(want.GetParams().GetParam(PAGE_STACK_PROPERTY_NAME)); + if (stringObj != nullptr) { + pageStack = AAFwk::String::Unbox(stringObj); + } +} + +bool EtsUIAbility::IsRestorePageStack(const Want &want) +{ + return want.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME, true); +} + +void EtsUIAbility::RestorePageStack(const Want &want) +{ + if (IsRestorePageStack(want)) { + std::string pageStack; + GetPageStackFromWant(want, pageStack); + // to be done: AniSetUIContent + } +} + +void EtsUIAbility::AbilityContinuationOrRecover(const Want &want) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::UIABILITY, "launch reason: %{public}d, last exit reasion: %{public}d", launchParam_.launchReason, + launchParam_.lastExitReason); + if (IsRestoredInContinuation()) { + RestorePageStack(want); + NotifyContinuationResult(want, true); + } else if (ShouldRecoverState(want)) { + std::string pageStack = abilityRecovery_->GetSavedPageStack(AppExecFwk::StateReason::DEVELOPER_REQUEST); + + auto mainWindow = scene_->GetMainWindow(); + if (mainWindow == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null mainWindow"); + } + } else { + if (ShouldDefaultRecoverState(want) && abilityRecovery_ != nullptr && scene_ != nullptr) { + TAG_LOGD(AAFwkTag::UIABILITY, "need restore"); + std::string pageStack = abilityRecovery_->GetSavedPageStack(AppExecFwk::StateReason::DEVELOPER_REQUEST); + auto mainWindow = scene_->GetMainWindow(); + if (!pageStack.empty() && mainWindow != nullptr) { + mainWindow->SetRestoredRouterStack(pageStack); + } + } + OnSceneCreated(); + } +} + +void EtsUIAbility::DoOnForeground(const Want &want) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (scene_ == nullptr) { + if ((abilityContext_ == nullptr) || (sceneListener_ == nullptr)) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext or sceneListener_"); + return; + } + DoOnForegroundForSceneIsNull(want); + } else { + auto window = scene_->GetMainWindow(); + if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) { + auto windowMode = want.GetIntParam( + Want::PARAM_RESV_WINDOW_MODE, AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED); + window->SetWindowMode(static_cast(windowMode)); + windowMode_ = windowMode; + TAG_LOGD(AAFwkTag::UIABILITY, "set window mode: %{public}d", windowMode); + } + } + + auto window = scene_->GetMainWindow(); + if (window != nullptr && securityFlag_) { + window->SetSystemPrivacyMode(true); + } + + if (CheckIsSilentForeground()) { + TAG_LOGI(AAFwkTag::UIABILITY, "silent foreground, do not show window"); + return; + } + + TAG_LOGD(AAFwkTag::UIABILITY, "move scene to foreground, sceneFlag_: %{public}d", UIAbility::sceneFlag_); + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "scene_->GoForeground"); + scene_->GoForeground(UIAbility::sceneFlag_); + TAG_LOGD(AAFwkTag::UIABILITY, "DoOnForeground end"); +} + +void EtsUIAbility::DoOnForegroundForSceneIsNull(const Want &want) +{ + scene_ = std::make_shared(); + int32_t displayId = AAFwk::DisplayUtil::GetDefaultDisplayId(); + if (setting_ != nullptr) { + std::string strDisplayId = setting_->GetProperty(OHOS::AppExecFwk::AbilityStartSetting::WINDOW_DISPLAY_ID_KEY); + std::regex formatRegex("[0-9]{0,9}$"); + std::smatch sm; + bool flag = std::regex_match(strDisplayId, sm, formatRegex); + if (flag && !strDisplayId.empty()) { + displayId = strtol(strDisplayId.c_str(), nullptr, BASE_DISPLAY_ID_NUM); + TAG_LOGD(AAFwkTag::UIABILITY, "displayId: %{public}d", displayId); + } else { + TAG_LOGW(AAFwkTag::UIABILITY, "formatRegex: [%{public}s] failed", strDisplayId.c_str()); + } + } + auto option = GetWindowOption(want); + Rosen::WMError ret = Rosen::WMError::WM_OK; + auto sessionToken = GetSessionToken(); + auto identityToken = GetIdentityToken(); + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "scene_->Init"); + if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled() && sessionToken != nullptr) { + abilityContext_->SetWeakSessionToken(sessionToken); + ret = scene_->Init(displayId, abilityContext_, sceneListener_, option, sessionToken, identityToken); + } else { + ret = scene_->Init(displayId, abilityContext_, sceneListener_, option); + } + if (ret != Rosen::WMError::WM_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "init window scene failed"); + return; + } + + AbilityContinuationOrRecover(want); + auto window = scene_->GetMainWindow(); + if (window) { + TAG_LOGD(AAFwkTag::UIABILITY, "registerDisplayMoveListener, windowId: %{public}d", window->GetWindowId()); + abilityDisplayMoveListener_ = new AbilityDisplayMoveListener(weak_from_this()); + if (abilityDisplayMoveListener_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityDisplayMoveListener_"); + return; + } + window->RegisterDisplayMoveListener(abilityDisplayMoveListener_); + } +} + +void EtsUIAbility::ContinuationRestore(const Want &want) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "called"); + if (!IsRestoredInContinuation()) { + TAG_LOGE(AAFwkTag::UIABILITY, "not in continuation"); + return; + } + if (scene_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null scene_"); + return; + } + RestorePageStack(want); + NotifyContinuationResult(want, true); +} + +void EtsUIAbility::UpdateEtsWindowStage(ani_ref windowStage) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "UpdateEtsWindowStage called"); + if (shellContextRef_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null shellContextRef_"); + return; + } + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + ani_status status = ANI_ERROR; + if (windowStage == nullptr) { + ani_ref undefinedRef = nullptr; + env->GetUndefined(&undefinedRef); + if ((status = env->Object_SetFieldByName_Ref(shellContextRef_->aniObj, "windowStage", undefinedRef)) != + ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + return; + } + if ((status = env->Object_SetFieldByName_Ref(shellContextRef_->aniObj, "windowStage", windowStage)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_SetFieldByName_Ref status: %{public}d", status); + return; + } +} +#endif + +void EtsUIAbility::OnNewWant(const Want &want) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "OnNewWant called"); + UIAbility::OnNewWant(want); + +#ifdef SUPPORT_SCREEN + if (scene_) { + scene_->OnNewWant(want); + } +#endif + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj_"); + return; + } + ani_object wantObj = OHOS::AppExecFwk::WrapWant(env, want); + if (wantObj == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null wantObj"); + return; + } + ani_status status = env->Object_SetFieldByName_Ref(etsAbilityObj_->aniObj, "lastRequestWant", wantObj); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "lastRequestWant Object_SetFieldByName_Ref status: %{public}d", status); + return; + } + auto launchParam = GetLaunchParam(); + if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) { + launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT; + } + ani_object launchParamObj = nullptr; + if (!WrapLaunchParam(env, launchParam, launchParamObj)) { + TAG_LOGE(AAFwkTag::UIABILITY, "WrapLaunchParam failed"); + return; + } + std::string methodName = "OnNewWant"; + CallObjectMethod(false, "onNewWant", nullptr, wantObj, launchParamObj); + TAG_LOGD(AAFwkTag::UIABILITY, "OnNewWant end"); +} + +void EtsUIAbility::OnAbilityResult(int requestCode, int resultCode, const Want &resultData) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "OnAbilityResult called"); + UIAbility::OnAbilityResult(requestCode, resultCode, resultData); + if (abilityContext_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_"); + return; + } + abilityContext_->OnAbilityResult(requestCode, resultCode, resultData); + TAG_LOGD(AAFwkTag::UIABILITY, "OnAbilityResult end"); +} + +bool EtsUIAbility::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); + TAG_LOGI(AAFwkTag::UIABILITY, "EtsUIAbility call ets, name: %{public}s", name); + if (etsAbilityObj_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null etsAbilityObj"); + return false; + } + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return false; + } + auto obj = etsAbilityObj_->aniObj; + auto cls = etsAbilityObj_->aniCls; + + ani_method method {}; + ani_status status = env->Class_FindMethod(cls, name, signature, &method); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Class_FindMethod status: %{public}d", status); + env->ResetError(); + return false; + } + if (withResult) { + ani_boolean res = false; + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Boolean_V(obj, method, &res, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_CallMethod_Boolean_V status: %{public}d", status); + etsRuntime_.HandleUncaughtError(); + return false; + } + va_end(args); + return res; + } + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Void_V(obj, method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "Object_CallMethod_Void_V status: %{public}d", status); + etsRuntime_.HandleUncaughtError(); + return false; + } + va_end(args); + TAG_LOGI(AAFwkTag::UIABILITY, "CallObjectMethod end, name: %{public}s", name); + return false; +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/native/ability/native/extension_ability_thread.cpp b/frameworks/native/ability/native/extension_ability_thread.cpp index f72fa0f4c2a0baf0747fcde775a4cb4ec02b887a..6a7633b35194a6998d9e00c87f75cf097d648bd9 100644 --- a/frameworks/native/ability/native/extension_ability_thread.cpp +++ b/frameworks/native/ability/native/extension_ability_thread.cpp @@ -242,7 +242,13 @@ void ExtensionAbilityThread::HandleAttach(const std::shared_ptr abilityInfo = abilityRecord->GetAbilityInfo(); + if (abilityInfo == nullptr) { + TAG_LOGE(AAFwkTag::EXT, "null abilityInfo"); + return; + } + auto extension = AppExecFwk::AbilityLoader::GetInstance().GetExtensionByName(abilityName, + abilityInfo->codeLanguage); if (extension == nullptr) { TAG_LOGE(AAFwkTag::EXT, "null extension"); return; diff --git a/frameworks/native/ability/native/ui_ability_thread.cpp b/frameworks/native/ability/native/ui_ability_thread.cpp index 18d97dee4d6e877cd0b78765fd3c7611c0128c44..e20643c444024976ee2d7b3daff98bc6a6239792 100644 --- a/frameworks/native/ability/native/ui_ability_thread.cpp +++ b/frameworks/native/ability/native/ui_ability_thread.cpp @@ -131,7 +131,8 @@ void UIAbilityThread::Attach(const std::shared_ptr } // 2.new ability - auto ability = AppExecFwk::AbilityLoader::GetInstance().GetUIAbilityByName(abilityName); + auto ability = AppExecFwk::AbilityLoader::GetInstance().GetUIAbilityByName( + abilityName, abilityRecord->GetAbilityInfo()->codeLanguage); if (ability == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null ability"); return; @@ -203,7 +204,8 @@ void UIAbilityThread::Attach(const std::shared_ptr } // 2.new ability - auto ability = AppExecFwk::AbilityLoader::GetInstance().GetUIAbilityByName(abilityName); + auto ability = AppExecFwk::AbilityLoader::GetInstance().GetUIAbilityByName( + abilityName, abilityRecord->GetAbilityInfo()->codeLanguage); if (ability == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null ability"); return; diff --git a/frameworks/native/appkit/BUILD.gn b/frameworks/native/appkit/BUILD.gn index cc0227d2feb3217aad08944d7a2786747cca7d8b..f0d40ede7ce1afa958e69de7a58cc25051642648 100644 --- a/frameworks/native/appkit/BUILD.gn +++ b/frameworks/native/appkit/BUILD.gn @@ -54,6 +54,7 @@ config("appkit_config") { config("appkit_public_config") { visibility = [ ":*" ] include_dirs = [ + "${ability_runtime_path}/ets_environment/interfaces/inner_api", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_delegator", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", @@ -75,6 +76,7 @@ config("appkit_public_config") { ohos_shared_library("appkit_native") { include_dirs = [ "native", + "${ability_runtime_path}/ets_environment/interfaces/inner_api", "${ability_runtime_path}/interfaces/inner_api/error_utils/include", "${ability_runtime_path}/interfaces/kits/native/appkit", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_bundle_manager_helper", @@ -166,6 +168,7 @@ ohos_shared_library("appkit_native") { "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:app_context_utils", "${ability_runtime_native_path}/appkit:appkit_manager_helper", + "${ability_runtime_path}/ets_environment/frameworks/ets_environment:ets_environment", "${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment", "${ability_runtime_path}/utils/global/freeze:freeze_util", "${ability_runtime_services_path}/common:app_util", @@ -208,6 +211,7 @@ ohos_shared_library("appkit_native") { "napi:ace_napi", "preferences:native_preferences", "resource_management:global_resmgr", + "runtime_core:ani", "safwk:system_ability_fwk", "samgr:samgr_proxy", "storage_service:storage_manager_acl", @@ -509,6 +513,7 @@ ohos_shared_library("appkit_delegator") { "image_framework:image_native", "ipc:ipc_core", "json:nlohmann_json_static", + "runtime_core:ani", "napi:ace_napi", "samgr:samgr_proxy", ] diff --git a/frameworks/native/appkit/ability_delegator/ability_delegator.cpp b/frameworks/native/appkit/ability_delegator/ability_delegator.cpp index 1449f61557fd7bd7e29303c5e7c9defd09967ce3..0c9ef8125c7d84ce7dfe4d481a571e0a6654a094 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/ability_delegator_registry.cpp b/frameworks/native/appkit/ability_delegator/ability_delegator_registry.cpp index 7187c88382eac76eabb85137bf793722dba009b7..7cd73453052ed30544d1f69b093cd2954774d90b 100644 --- a/frameworks/native/appkit/ability_delegator/ability_delegator_registry.cpp +++ b/frameworks/native/appkit/ability_delegator/ability_delegator_registry.cpp @@ -17,20 +17,30 @@ namespace OHOS { namespace AppExecFwk { -std::shared_ptr AbilityDelegatorRegistry::abilityDelegator_ {}; +std::map> + AbilityDelegatorRegistry::abilityDelegator_ {}; std::shared_ptr AbilityDelegatorRegistry::abilityDelegatorArgs_ {}; -std::shared_ptr AbilityDelegatorRegistry::GetAbilityDelegator() +std::shared_ptr AbilityDelegatorRegistry::GetAbilityDelegator( + const AbilityRuntime::Runtime::Language &language) { - auto p = reinterpret_cast(abilityDelegator_.get()); - return std::shared_ptr(abilityDelegator_, p); + auto it = abilityDelegator_.find(language); + if (it != abilityDelegator_.end()) { + auto p = reinterpret_cast(it->second.get()); + return std::shared_ptr(it->second, p); + } + return nullptr; } #ifdef CJ_FRONTEND std::shared_ptr AbilityDelegatorRegistry::GetCJAbilityDelegator() { - auto p = reinterpret_cast(abilityDelegator_.get()); - return std::shared_ptr(abilityDelegator_, p); + auto it = abilityDelegator_.find(AbilityRuntime::Runtime::Language::CJ); + if (it != abilityDelegator_.end()) { + auto p = reinterpret_cast(it->second.get()); + return std::shared_ptr(it->second, p); + } + return nullptr; } #endif @@ -39,11 +49,11 @@ std::shared_ptr AbilityDelegatorRegistry::GetArguments() return abilityDelegatorArgs_; } -void AbilityDelegatorRegistry::RegisterInstance( - const std::shared_ptr& delegator, const std::shared_ptr& args) +void AbilityDelegatorRegistry::RegisterInstance(const std::shared_ptr &delegator, + const std::shared_ptr &args, const AbilityRuntime::Runtime::Language &language) { - abilityDelegator_ = delegator; abilityDelegatorArgs_ = args; + abilityDelegator_.emplace(language, delegator); } } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/native/appkit/ability_delegator/iability_monitor.cpp b/frameworks/native/appkit/ability_delegator/iability_monitor.cpp index 17bf4c740bdd7cbcab6b11e4b3d3c28f9b02b33c..4a6238cb04740d7a071b687f11224c5901ba233b 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/app/application_data_manager.cpp b/frameworks/native/appkit/app/application_data_manager.cpp index 6dfd3a4493efb0896184c21819410ade2e088f11..79c2449ccbffee933660e96284a27195137eed92 100644 --- a/frameworks/native/appkit/app/application_data_manager.cpp +++ b/frameworks/native/appkit/app/application_data_manager.cpp @@ -59,6 +59,15 @@ bool ApplicationDataManager::NotifyCJUnhandledException(const std::string &errMs return AppRecovery::GetInstance().TryRecoverApp(StateReason::CJ_ERROR); } +bool ApplicationDataManager::NotifyETSUnhandledException(const std::string &errMsg) +{ + if (errorObserver_) { + errorObserver_->OnUnhandledException(errMsg); + return true; + } + return AppRecovery::GetInstance().TryRecoverApp(StateReason::JS_ERROR); +} + void ApplicationDataManager::RemoveErrorObserver() { errorObserver_ = nullptr; @@ -88,5 +97,15 @@ bool ApplicationDataManager::NotifyCJExceptionObject(const AppExecFwk::ErrorObje // and restart as developer wants return AppRecovery::GetInstance().TryRecoverApp(StateReason::CJ_ERROR); } + +bool ApplicationDataManager::NotifyETSExceptionObject(const AppExecFwk::ErrorObject &errorObj) +{ + TAG_LOGD(AAFwkTag::APPKIT, "Notify Exception error observer come"); + if (errorObserver_) { + errorObserver_->OnExceptionObject(errorObj); + return true; + } + return AppRecovery::GetInstance().TryRecoverApp(StateReason::JS_ERROR); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/native/appkit/app/dump_runtime_helper.cpp b/frameworks/native/appkit/app/dump_runtime_helper.cpp index 945867d5b91541371d8a8ae7eef1c18f45e61cac..052ec4ece780ccf21afa532700a9d370de81a831 100644 --- a/frameworks/native/appkit/app/dump_runtime_helper.cpp +++ b/frameworks/native/appkit/app/dump_runtime_helper.cpp @@ -87,7 +87,7 @@ void DumpRuntimeHelper::SetAppFreezeFilterCallback() TAG_LOGE(AAFwkTag::APPKIT, "null application"); return; } - auto& runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; @@ -205,7 +205,7 @@ void DumpRuntimeHelper::DumpJsHeap(const OHOS::AppExecFwk::JsHeapDumpInfo &info) TAG_LOGE(AAFwkTag::APPKIT, "null application"); return; } - auto& runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; @@ -235,7 +235,7 @@ void DumpRuntimeHelper::DumpCjHeap(const OHOS::AppExecFwk::CjHeapDumpInfo &info) TAG_LOGE(AAFwkTag::APPKIT, "null application"); return; } - auto& runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index 0e856912f1bd7f5d2355dc5da48545bda731cea6..d15795546b2c7c7ad358189fdc271dbeef3b2505 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -75,6 +75,7 @@ #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "js_runtime.h" +#include "ets_runtime.h" #ifdef CJ_FRONTEND #include "cj_runtime.h" #endif @@ -183,6 +184,7 @@ const char* PC_LIBRARY_PATH = "/system/lib64/liblayered_parameters_manager.z.so" const char* PC_FUNC_INFO = "DetermineResourceType"; const int32_t TYPE_RESERVE = 1; const int32_t TYPE_OTHERS = 2; +std::unique_ptr RUNTIME_NULL = nullptr; #if defined(NWEB) constexpr int32_t PRELOAD_DELAY_TIME = 2000; //millisecond @@ -1395,6 +1397,59 @@ CJUncaughtExceptionInfo MainThread::CreateCjExceptionInfo(const std::string &bun return uncaughtExceptionInfo; } #endif + +EtsEnv::ETSUncaughtExceptionInfo MainThread::CreateEtsExceptionInfo(const std::string &bundleName, uint32_t versionCode, + const std::string &hapPath, std::string &appRunningId, int32_t pid, std::string &processName) +{ + EtsEnv::ETSUncaughtExceptionInfo uncaughtExceptionInfo; + wptr weak = this; + uncaughtExceptionInfo.uncaughtTask = [weak, bundleName, versionCode, appRunningId = std::move(appRunningId), pid, + processName](std::string summary, const EtsEnv::ETSErrorObject errorObj) { + auto appThread = weak.promote(); + if (appThread == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null appThread"); + return; + } + time_t timet; + time(&timet); + HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, "JS_ERROR", + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, EVENT_KEY_PACKAGE_NAME, bundleName, EVENT_KEY_VERSION, + std::to_string(versionCode), EVENT_KEY_TYPE, JSCRASH_TYPE, EVENT_KEY_HAPPEN_TIME, timet, EVENT_KEY_REASON, + errorObj.name, EVENT_KEY_JSVM, JSVM_TYPE, EVENT_KEY_SUMMARY, summary, EVENT_KEY_PNAME, processName, + EVENT_KEY_APP_RUNING_UNIQUE_ID, appRunningId); + ErrorObject appExecErrorObj = { .name = errorObj.name, .message = errorObj.message, .stack = errorObj.stack }; + FaultData faultData; + faultData.faultType = FaultDataType::JS_ERROR; + faultData.errorObject = appExecErrorObj; + DelayedSingleton::GetInstance()->NotifyAppFault(faultData); + if (ApplicationDataManager::GetInstance().NotifyETSUnhandledException(summary) && + ApplicationDataManager::GetInstance().NotifyETSExceptionObject(appExecErrorObj)) { + return; + } + TAG_LOGE(AAFwkTag::APPKIT, + "\n%{public}s is about to exit due to RuntimeError\nError " + "type:%{public}s\n%{public}s", + bundleName.c_str(), errorObj.name.c_str(), summary.c_str()); + bool foreground = false; + if (appThread->applicationImpl_ && + appThread->applicationImpl_->GetState() == ApplicationImpl::APP_STATE_FOREGROUND) { + foreground = true; + } + int result = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::FRAMEWORK, "PROCESS_KILL", + HiviewDFX::HiSysEvent::EventType::FAULT, "PID", pid, "PROCESS_NAME", processName, "MSG", KILL_REASON, + "FOREGROUND", foreground); + TAG_LOGW(AAFwkTag::APPKIT, + "hisysevent write result=%{public}d, send event " + "[FRAMEWORK,PROCESS_KILL]," + " pid=%{public}d, processName=%{public}s, msg=%{public}s, " + "foreground=%{public}d", + result, pid, processName.c_str(), KILL_REASON, foreground); + AAFwk::ExitReason exitReason = { REASON_JS_ERROR, errorObj.name }; + AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason); + _exit(JS_ERROR_EXIT); + }; + return uncaughtExceptionInfo; +} /** * * @brief Launch the application. @@ -1582,6 +1637,9 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con } else { #endif AbilityRuntime::JsRuntime::SetAppLibPath(appLibPaths, isSystemApp); + if (IsNeedEtsInit(appInfo)) { + AbilityRuntime::ETSRuntime::SetAppLibPath(appLibPaths); + } #ifdef CJ_FRONTEND } #endif @@ -1608,7 +1666,14 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con options.pkgContextInfoJsonStringMap = pkgContextInfoJsonStringMap; options.allowArkTsLargeHeap = appInfo.allowArkTsLargeHeap; #ifdef CJ_FRONTEND - options.lang = isCJApp ? AbilityRuntime::Runtime::Language::CJ : AbilityRuntime::Runtime::Language::JS; + if (isCJApp) { + options.langs.emplace(AbilityRuntime::Runtime::Language::CJ, true); + application_->SetCJApplication(true); + } else { + AddRuntimeLang(appInfo, options); + } +#else + AddRuntimeLang(appInfo, options); #endif if (applicationInfo_->appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG) { TAG_LOGD(AAFwkTag::APPKIT, "multi-thread mode: %{public}d", appLaunchData.GetMultiThread()); @@ -1642,12 +1707,12 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con static_cast(hapModuleInfo.aotCompileStatus); } } - auto runtime = AbilityRuntime::Runtime::Create(options); - if (!runtime) { - TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); + std::vector> runtimes = AbilityRuntime::Runtime::CreateRuntimes(options); + if (runtimes.empty()) { + TAG_LOGE(AAFwkTag::APPKIT, "runtimes empty"); return; } - + auto &runtimeVerOne = GetVerOneRuntime(appInfo, runtimes); if (appInfo.debug && appLaunchData.GetDebugApp()) { wptr weak = this; auto cb = [weak]() { @@ -1658,7 +1723,9 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con } return appThread->NotifyDeviceDisConnect(); }; - runtime->SetDeviceDisconnectCallback(cb); + if (runtimeVerOne != nullptr) { + runtimeVerOne->SetDeviceDisconnectCallback(cb); + } } auto perfCmd = appLaunchData.GetPerfCmd(); @@ -1669,11 +1736,13 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con processName = processInfo_->GetProcessName(); TAG_LOGD(AAFwkTag::APPKIT, "pid is %{public}d, processName is %{public}s", pid, processName.c_str()); } - runtime->SetStopPreloadSoCallback([uid = bundleInfo.applicationInfo.uid, currentPid = pid, - bundleName = appInfo.bundleName]()-> void { - TAG_LOGD(AAFwkTag::APPKIT, "runtime callback and report load abc completed info to rss."); - ResHelper::ReportLoadAbcCompletedInfoToRss(uid, currentPid, bundleName); - }); + if (runtimeVerOne != nullptr) { + runtimeVerOne->SetStopPreloadSoCallback([uid = bundleInfo.applicationInfo.uid, currentPid = pid, + bundleName = appInfo.bundleName]()-> void { + TAG_LOGD(AAFwkTag::APPKIT, "runtime callback and report load abc completed info to rss."); + ResHelper::ReportLoadAbcCompletedInfoToRss(uid, currentPid, bundleName); + }); + } AbilityRuntime::Runtime::DebugOption debugOption; debugOption.isStartWithDebug = appLaunchData.GetDebugApp(); debugOption.processName = processName; @@ -1683,13 +1752,19 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con debugOption.isDebugFromLocal = appLaunchData.GetDebugFromLocal(); debugOption.perfCmd = perfCmd; debugOption.isDeveloperMode = isDeveloperMode_; - runtime->SetDebugOption(debugOption); + if (runtimeVerOne != nullptr) { + runtimeVerOne->SetDebugOption(debugOption); + } if (perfCmd.find(PERFCMD_PROFILE) != std::string::npos || perfCmd.find(PERFCMD_DUMPHEAP) != std::string::npos) { TAG_LOGD(AAFwkTag::APPKIT, "perfCmd is %{public}s", perfCmd.c_str()); - runtime->StartProfiler(debugOption); + if (runtimeVerOne != nullptr) { + runtimeVerOne->StartProfiler(debugOption); + } } else { - runtime->StartDebugMode(debugOption); + if (runtimeVerOne != nullptr) { + runtimeVerOne->StartDebugMode(debugOption); + } } std::vector hqfInfos = appInfo.appQuickFix.deployedAppqfInfo.hqfInfos; @@ -1700,7 +1775,9 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con it->moduleName.c_str(), it->hqfFilePath.c_str()); modulePaths.insert(std::make_pair(it->moduleName, it->hqfFilePath)); } - runtime->RegisterQuickFixQueryFunc(modulePaths); + if (runtimeVerOne != nullptr) { + runtimeVerOne->RegisterQuickFixQueryFunc(modulePaths); + } } auto bundleName = appInfo.bundleName; @@ -1708,18 +1785,37 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con #ifdef CJ_FRONTEND if (!isCJApp) { #endif - JsEnv::UncaughtExceptionInfo uncaughtExceptionInfo; - uncaughtExceptionInfo.hapPath = hapPath; - UncatchableTaskInfo uncatchableTaskInfo = {bundleName, versionCode, appRunningId, pid, processName}; - InitUncatchableTask(uncaughtExceptionInfo.uncaughtTask, uncatchableTaskInfo); - (static_cast(*runtime)).RegisterUncaughtExceptionHandler(uncaughtExceptionInfo); - JsEnv::UncatchableTask uncatchableTask; - InitUncatchableTask(uncatchableTask, uncatchableTaskInfo, true); - (static_cast(*runtime)).RegisterUncatchableExceptionHandler(uncatchableTask); + for (const auto &runtime : runtimes) { + if (appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0 && + runtime->GetLanguage() == AbilityRuntime::Runtime::Language::JS) { + JsEnv::UncaughtExceptionInfo uncaughtExceptionInfo; + uncaughtExceptionInfo.hapPath = hapPath; + UncatchableTaskInfo uncatchableTaskInfo = {bundleName, versionCode, appRunningId, pid, processName}; + InitUncatchableTask(uncaughtExceptionInfo.uncaughtTask, uncatchableTaskInfo); + (static_cast(*runtime)).RegisterUncaughtExceptionHandler( + uncaughtExceptionInfo); + JsEnv::UncatchableTask uncatchableTask; + InitUncatchableTask(uncatchableTask, uncatchableTaskInfo, true); + (static_cast(*runtime)).RegisterUncatchableExceptionHandler( + uncatchableTask); + } + if ((appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2 || + appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_HYBRID) && + runtime->GetLanguage() == AbilityRuntime::Runtime::Language::ETS) { + auto expectionInfo = + CreateEtsExceptionInfo(bundleName, versionCode, hapPath, appRunningId, pid, processName); + runtime->RegisterUncaughtExceptionHandler((void*)&expectionInfo); + } + } #ifdef CJ_FRONTEND } else { - auto expectionInfo = CreateCjExceptionInfo(bundleName, versionCode, hapPath); - (static_cast(*runtime)).RegisterUncaughtExceptionHandler(expectionInfo); + for (const auto &runtime : runtimes) { + if (appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0 && + runtime->GetLanguage() == AbilityRuntime::Runtime::Language::CJ) { + auto expectionInfo = CreateCjExceptionInfo(bundleName, versionCode, hapPath); + runtime->RegisterUncaughtExceptionHandler((void*)&expectionInfo); + } + } } #endif wptr weak = this; @@ -1733,14 +1829,21 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con }; applicationContext->RegisterProcessSecurityExit(callback); - application_->SetRuntime(std::move(runtime)); - + for (auto &runtime : runtimes) { + application_->AddRuntime(std::move(runtime)); + } std::weak_ptr wpApplication = application_; AbilityLoader::GetInstance().RegisterUIAbility("UIAbility", - [wpApplication]() -> AbilityRuntime::UIAbility* { + [wpApplication](const std::string &language) -> AbilityRuntime::UIAbility* { auto app = wpApplication.lock(); if (app != nullptr) { - return AbilityRuntime::UIAbility::Create(app->GetRuntime()); + if (language == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2) { + return AbilityRuntime::UIAbility::Create(app->GetRuntime( + AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2)); + } else { + return AbilityRuntime::UIAbility::Create(app->GetRuntime( + AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0)); + } } TAG_LOGE(AAFwkTag::APPKIT, "failed"); return nullptr; @@ -1748,33 +1851,18 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con #ifdef CJ_FRONTEND if (!isCJApp) { #endif - auto& jsEngine = (static_cast(*application_->GetRuntime())).GetNativeEngine(); if (application_ != nullptr) { - LoadAllExtensions(jsEngine); + TAG_LOGD(AAFwkTag::APPKIT, "LoadAllExtensions lan:%{public}s", appInfo.codeLanguage.c_str()); + LoadAllExtensions(); } - - IdleTimeCallback callback = [wpApplication](int32_t idleTime) { - auto app = wpApplication.lock(); - if (app == nullptr) { - TAG_LOGE(AAFwkTag::APPKIT, "null app"); - return; - } - auto &runtime = app->GetRuntime(); + if (appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0) { + auto &runtime = application_->GetRuntime(appInfo.codeLanguage); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; } - auto& nativeEngine = (static_cast(*runtime)).GetNativeEngine(); - nativeEngine.NotifyIdleTime(idleTime); - }; - idleTime_ = std::make_shared(mainHandler_, callback); - idleTime_->Start(); - - IdleNotifyStatusCallback cb = idleTime_->GetIdleNotifyFunc(); - jsEngine.NotifyIdleStatusControl(cb); - - auto helper = std::make_shared(application_); - helper->SetAppFreezeFilterCallback(); + SetJsIdleCallback(wpApplication, runtime); + } #ifdef CJ_FRONTEND } else { LoadAllExtensions(); @@ -1784,7 +1872,8 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con auto usertestInfo = appLaunchData.GetUserTestInfo(); if (usertestInfo) { - if (!PrepareAbilityDelegator(usertestInfo, isStageBased, entryHapModuleInfo, bundleInfo.targetVersion)) { + if (!PrepareAbilityDelegator(usertestInfo, isStageBased, entryHapModuleInfo, bundleInfo.targetVersion, + appInfo.codeLanguage)) { TAG_LOGE(AAFwkTag::APPKIT, "PrepareAbilityDelegator failed"); return; } @@ -1876,7 +1965,9 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con } #endif if (appLaunchData.IsNeedPreloadModule()) { - PreloadModule(entryHapModuleInfo, application_->GetRuntime()); + for (auto &runtime : application_->GetRuntime()) { + PreloadModule(entryHapModuleInfo, runtime); + } } } @@ -1911,7 +2002,8 @@ void MainThread::InitUncatchableTask(JsEnv::UncatchableTask &uncatchableTask, co EVENT_KEY_PROCESS_RSS_MEMINFO, std::to_string(DumpProcessHelper::GetProcRssMemInfo())); ErrorObject appExecErrorObj = { errorObject.name, errorObject.message, errorObject.stack}; - auto napiEnv = (static_cast(*appThread->application_->GetRuntime())).GetNapiEnv(); + auto napiEnv = (static_cast( + *appThread->application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0))).GetNapiEnv(); AAFwk::ExitReason exitReason = { REASON_JS_ERROR, errorObject.name }; AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason); if (!isUncatchable && NapiErrorManager::GetInstance()->NotifyUncaughtException(napiEnv, summary, @@ -2054,7 +2146,7 @@ void MainThread::ProcessMainAbility(const AbilityInfo &info, const std::unique_p } void MainThread::PreloadModule(const AppExecFwk::HapModuleInfo &entryHapModuleInfo, - const std::unique_ptr& runtime) + const std::unique_ptr &runtime) { TAG_LOGI(AAFwkTag::APPKIT, "preload module %{public}s", entryHapModuleInfo.moduleName.c_str()); auto callback = []() {}; @@ -2204,7 +2296,7 @@ void MainThread::HandleUpdatePluginInfoInstalled(const ApplicationInfo &pluginAp TAG_LOGE(AAFwkTag::APPKIT, "null application_"); return; } - auto& runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; @@ -2254,7 +2346,7 @@ void MainThread::HandleUpdateApplicationInfoInstalled(const ApplicationInfo& app } application_->UpdateApplicationInfoInstalled(appInfo); - auto& runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; @@ -2342,10 +2434,11 @@ void MainThread::LoadAllExtensions() std::string file = item.extensionLibFile; std::weak_ptr wApp = application_; AbilityLoader::GetInstance().RegisterExtension(item.extensionName, - [wApp, file]() -> AbilityRuntime::Extension* { + [wApp, file](const std::string &language) -> AbilityRuntime::Extension* { auto app = wApp.lock(); if (app != nullptr) { - return AbilityRuntime::ExtensionModuleLoader::GetLoader(file.c_str()).Create(app->GetRuntime()); + return AbilityRuntime::ExtensionModuleLoader::GetLoader(file.c_str()) + .Create(app->GetRuntime(language)); } TAG_LOGE(AAFwkTag::APPKIT, "failed"); return nullptr; @@ -2355,7 +2448,8 @@ void MainThread::LoadAllExtensions() } bool MainThread::PrepareAbilityDelegator(const std::shared_ptr &record, bool isStageBased, - const AppExecFwk::HapModuleInfo &entryHapModuleInfo, uint32_t targetVersion) + const AppExecFwk::HapModuleInfo &entryHapModuleInfo, uint32_t targetVersion, + const std::string &applicationCodeLanguage) { TAG_LOGD(AAFwkTag::APPKIT, "enter, isStageBased = %{public}d", isStageBased); if (!record) { @@ -2365,12 +2459,27 @@ bool MainThread::PrepareAbilityDelegator(const std::shared_ptr & auto args = std::make_shared(record->want); if (isStageBased) { // Stage model TAG_LOGD(AAFwkTag::APPKIT, "Stage model"); - auto testRunner = TestRunner::Create(application_->GetRuntime(), args, false); - auto delegator = IAbilityDelegator::Create(application_->GetRuntime(), application_->GetAppContext(), - std::move(testRunner), record->observer); - AbilityDelegatorRegistry::RegisterInstance(delegator, args); - delegator->SetApiTargetVersion(targetVersion); - delegator->Prepare(); + 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 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); + 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 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); + delegator->Prepare(); + } } else { // FA model TAG_LOGD(AAFwkTag::APPKIT, "FA model"); AbilityRuntime::Runtime::Options options; @@ -2400,7 +2509,7 @@ bool MainThread::PrepareAbilityDelegator(const std::shared_ptr & } auto delegator = std::make_shared( application_->GetAppContext(), std::move(testRunner), record->observer); - AbilityDelegatorRegistry::RegisterInstance(delegator, args); + AbilityDelegatorRegistry::RegisterInstance(delegator, args, AbilityRuntime::Runtime::Language::JS); delegator->SetApiTargetVersion(targetVersion); delegator->Prepare(); } @@ -2461,7 +2570,7 @@ void MainThread::HandleLaunchAbility(const std::shared_ptr & TAG_LOGE(AAFwkTag::APPKIT, "null application"); return; } - auto& runtime = application->GetRuntime(); + auto &runtime = application->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); appThread->UpdateRuntimeModuleChecker(runtime); #ifdef APP_ABILITY_USE_TWO_RUNNER AbilityThread::AbilityThreadMain(application, abilityRecord, stageContext); @@ -2488,7 +2597,7 @@ void MainThread::HandleLaunchAbility(const std::shared_ptr & return; } SetProcessExtensionType(abilityRecord); - auto& runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); UpdateRuntimeModuleChecker(runtime); #ifdef APP_ABILITY_USE_TWO_RUNNER AbilityThread::AbilityThreadMain(application_, abilityRecord, stageContext); @@ -2851,7 +2960,7 @@ void MainThread::HandleDumpHeapPrepare() TAG_LOGE(AAFwkTag::APPKIT, "null app"); return; } - auto &runtime = app->GetRuntime(); + auto &runtime = app->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; @@ -2871,7 +2980,7 @@ void MainThread::HandleDumpHeap(bool isPrivate) TAG_LOGE(AAFwkTag::APPKIT, "null app"); return; } - auto &runtime = app->GetRuntime(); + auto &runtime = app->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; @@ -2924,11 +3033,11 @@ void MainThread::DestroyHeapProfiler() auto task = [] { auto app = applicationForDump_.lock(); - if (app == nullptr || app->GetRuntime() == nullptr) { + if (app == nullptr || app->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0) == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; } - app->GetRuntime()->DestroyHeapProfiler(); + app->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0)->DestroyHeapProfiler(); }; mainHandler_->PostTask(task, "MainThread:DestroyHeapProfiler"); } @@ -2943,11 +3052,11 @@ void MainThread::ForceFullGC() auto task = [] { auto app = applicationForDump_.lock(); - if (app == nullptr || app->GetRuntime() == nullptr) { + if (app == nullptr || app->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0) == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; } - app->GetRuntime()->ForceFullGC(); + app->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0)->ForceFullGC(); }; mainHandler_->PostTask(task, "MainThread:ForceFullGC"); } @@ -3675,7 +3784,7 @@ int32_t MainThread::ChangeAppGcState(int32_t state, uint64_t tid) TAG_LOGE(AAFwkTag::APPKIT, "null application_"); return ERR_INVALID_VALUE; } - auto &runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return ERR_INVALID_VALUE; @@ -3727,7 +3836,7 @@ int32_t MainThread::OnAttachLocalDebug(bool isDebugFromLocal) TAG_LOGE(AAFwkTag::APPKIT, "null application_"); return ERR_INVALID_VALUE; } - auto &runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return ERR_INVALID_VALUE; @@ -3949,7 +4058,7 @@ void MainThread::HandleCacheProcess() // force gc if (application_ != nullptr) { - auto &runtime = application_->GetRuntime(); + auto &runtime = application_->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; @@ -3958,6 +4067,38 @@ void MainThread::HandleCacheProcess() } } +void MainThread::AddRuntimeLang(ApplicationInfo &appInfo, AbilityRuntime::Runtime::Options &options) +{ + if (appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2) { + options.langs.emplace(AbilityRuntime::Runtime::Language::ETS, true); + } else if (appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_HYBRID) { + options.langs.emplace(AbilityRuntime::Runtime::Language::ETS, true); + } else { + options.langs.emplace(AbilityRuntime::Runtime::Language::JS, true); + } +} + +bool MainThread::IsNeedEtsInit(const ApplicationInfo &appInfo) +{ + return appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2 || + appInfo.codeLanguage == AbilityRuntime::CODE_LANGUAGE_ARKTS_HYBRID; +} + +const std::unique_ptr &MainThread::GetVerOneRuntime( + const ApplicationInfo &appInfo, const std::vector> &runtimes) +{ + if (appInfo.codeLanguage != AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0) { + return RUNTIME_NULL; + } + for (auto &runtime : runtimes) { + if (runtime->GetLanguage() == AbilityRuntime::Runtime::Language::JS || + runtime->GetLanguage() == AbilityRuntime::Runtime::Language::CJ) { + return runtime; + } + } + return RUNTIME_NULL; +} + void MainThread::HandleConfigByPlugin(Configuration &config, BundleInfo &bundleInfo) { if (PC_LIBRARY_PATH == nullptr) { @@ -3980,5 +4121,33 @@ void MainThread::HandleConfigByPlugin(Configuration &config, BundleInfo &bundleI entry(config, bundleInfo); } + +void MainThread::SetJsIdleCallback(const std::weak_ptr &wpApplication, + const std::unique_ptr &runtime) +{ + auto &jsEngine = (static_cast(*runtime)).GetNativeEngine(); + IdleTimeCallback callback = [wpApplication](int32_t idleTime) { + auto app = wpApplication.lock(); + if (app == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null app"); + return; + } + auto &runtime = app->GetRuntime(AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); + if (runtime == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); + return; + } + auto &nativeEngine = (static_cast(*runtime)).GetNativeEngine(); + nativeEngine.NotifyIdleTime(idleTime); + }; + idleTime_ = std::make_shared(mainHandler_, callback); + idleTime_->Start(); + + IdleNotifyStatusCallback cb = idleTime_->GetIdleNotifyFunc(); + jsEngine.NotifyIdleStatusControl(cb); + + auto helper = std::make_shared(application_); + helper->SetAppFreezeFilterCallback(); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/native/appkit/app/ohos_application.cpp b/frameworks/native/appkit/app/ohos_application.cpp index 45831ff8001811c05b876e26fa10344ea10802b4..41713dde52b85c112228af397a2d7c92e0cf22f6 100644 --- a/frameworks/native/appkit/app/ohos_application.cpp +++ b/frameworks/native/appkit/app/ohos_application.cpp @@ -37,6 +37,7 @@ #include "iservice_registry.h" #include "runtime.h" #include "js_runtime.h" +#include "ets_runtime.h" #include "startup_manager.h" #include "system_ability_definition.h" #include "syspara/parameter.h" @@ -51,6 +52,7 @@ namespace OHOS { namespace AppExecFwk { namespace { constexpr const char* PERSIST_DARKMODE_KEY = "persist.ace.darkmode"; + std::unique_ptr RUNTIME_NULL = nullptr; } REGISTER_APPLICATION(OHOSApplication, OHOSApplication) constexpr int32_t APP_ENVIRONMENT_OVERWRITE = 1; @@ -77,11 +79,14 @@ void OHOSApplication::OnForeground() abilityRuntimeContext_->NotifyApplicationForeground(); } - if (runtime_ == nullptr) { - TAG_LOGD(AAFwkTag::APPKIT, "NotifyApplicationState, runtime_ is nullptr"); - return; + for (const auto &runtime : runtimes_) { + if (runtime == nullptr) { + TAG_LOGD(AAFwkTag::APPKIT, "NotifyApplicationState, runtime is nullptr"); + continue; + } + runtime->NotifyApplicationState(false); } - runtime_->NotifyApplicationState(false); + TAG_LOGD(AAFwkTag::APPKIT, "NotifyApplicationState::OnForeground end"); } @@ -97,11 +102,13 @@ void OHOSApplication::OnBackground() abilityRuntimeContext_->NotifyApplicationBackground(); } - if (runtime_ == nullptr) { - TAG_LOGD(AAFwkTag::APPKIT, "runtime_ is nullptr"); - return; + for (const auto &runtime : runtimes_) { + if (runtime == nullptr) { + TAG_LOGD(AAFwkTag::APPKIT, "runtime is nullptr"); + continue; + } + runtime->NotifyApplicationState(true); } - runtime_->NotifyApplicationState(true); } void OHOSApplication::DumpApplication() @@ -149,18 +156,18 @@ void OHOSApplication::DumpApplication() } /** - * @brief Set Runtime + * @brief Add Runtime * * @param runtime Runtime instance. */ -void OHOSApplication::SetRuntime(std::unique_ptr&& runtime) +void OHOSApplication::AddRuntime(std::unique_ptr &&runtime) { TAG_LOGD(AAFwkTag::APPKIT, "begin"); if (runtime == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); return; } - runtime_ = std::move(runtime); + runtimes_.emplace_back(std::move(runtime)); } /** @@ -369,6 +376,25 @@ void OHOSApplication::SetAppEnv(const std::vector& appEnvironmen return; } +void OHOSApplication::PreloadHybridModule(const HapModuleInfo &hapModuleInfo) const +{ + if (hapModuleInfo.codeLanguage != Constants::CODE_LANGUAGE_HYBRID) { + TAG_LOGD(AAFwkTag::APPKIT, "not hybrid runtime"); + return; + } + for (const auto &runtime : runtimes_) { + bool isEsmode = hapModuleInfo.compileMode == CompileMode::ES_MODULE; + bool useCommonTrunk = false; + for (const auto& md : hapModuleInfo.metadata) { + if (md.name == "USE_COMMON_CHUNK") { + useCommonTrunk = md.value == "true"; + break; + } + } + runtime->PreloadModule(hapModuleInfo.moduleName, hapModuleInfo.hapPath, isEsmode, useCommonTrunk); + } +} + std::shared_ptr OHOSApplication::AddAbilityStage( const std::shared_ptr &abilityRecord, const std::function &)> &callback, bool &isAsyncCallback) @@ -413,8 +439,10 @@ std::shared_ptr OHOSApplication::AddAbilityStage( TAG_LOGE(AAFwkTag::APPKIT, "null hapModuleInfo"); return nullptr; } - if (runtime_ && (runtime_->GetLanguage() == AbilityRuntime::Runtime::Language::JS)) { - static_cast(*runtime_).SetPkgContextInfoJson( + PreloadHybridModule(*hapModuleInfo); + auto &runtime = GetRuntime(abilityInfo->codeLanguage); + if (runtime && (runtime->GetLanguage() == AbilityRuntime::Runtime::Language::JS)) { + static_cast(*runtime).SetPkgContextInfoJson( hapModuleInfo->moduleName, hapModuleInfo->hapPath, hapModuleInfo->packageName); } SetAppEnv(hapModuleInfo->appEnvironments); @@ -425,7 +453,8 @@ std::shared_ptr OHOSApplication::AddAbilityStage( stageContext->SetResourceManager(rm); } - abilityStage = AbilityRuntime::AbilityStage::Create(runtime_, *hapModuleInfo); + auto &runtimeStage = GetRuntime(hapModuleInfo->codeLanguage); + abilityStage = AbilityRuntime::AbilityStage::Create(runtimeStage, *hapModuleInfo); if (abilityStage == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null abilityStage"); return nullptr; @@ -608,8 +637,8 @@ bool OHOSApplication::AddAbilityStage( return false; } - if (runtime_ == nullptr) { - TAG_LOGE(AAFwkTag::APPKIT, "null runtime_"); + if (runtimes_.empty()) { + TAG_LOGE(AAFwkTag::APPKIT, "runtimes empty"); return false; } @@ -633,7 +662,8 @@ bool OHOSApplication::AddAbilityStage( stageContext->SetResourceManager(rm); } - auto abilityStage = AbilityRuntime::AbilityStage::Create(runtime_, *moduleInfo); + auto &runtime = GetRuntime(moduleInfo->codeLanguage); + auto abilityStage = AbilityRuntime::AbilityStage::Create(runtime, *moduleInfo); if (abilityStage == nullptr) { TAG_LOGE(AAFwkTag::APPKIT, "null abilityStage"); return false; @@ -688,9 +718,9 @@ std::shared_ptr OHOSApplication::GetAppContext() const return abilityRuntimeContext_; } -const std::unique_ptr& OHOSApplication::GetRuntime() const +const std::vector> &OHOSApplication::GetRuntime() const { - return runtime_; + return runtimes_; } void OHOSApplication::SetConfiguration(const Configuration &config) @@ -815,32 +845,60 @@ void OHOSApplication::SetExtensionTypeMap(std::map map) bool OHOSApplication::NotifyLoadRepairPatch(const std::string &hqfFile, const std::string &hapPath) { - if (runtime_ == nullptr) { - TAG_LOGD(AAFwkTag::APPKIT, "null runtime"); + if (runtimes_.empty()) { + TAG_LOGD(AAFwkTag::APPKIT, "runtimes empty"); return true; } - return runtime_->LoadRepairPatch(hqfFile, hapPath); + for (const auto &runtime : runtimes_) { + if (runtime == nullptr) { + TAG_LOGD(AAFwkTag::APPKIT, "null runtime"); + continue; + } + if (!runtime->LoadRepairPatch(hqfFile, hapPath)) { + return false; + } + } + return true; } bool OHOSApplication::NotifyHotReloadPage() { - if (runtime_ == nullptr) { - TAG_LOGD(AAFwkTag::APPKIT, "null runtime"); + if (runtimes_.empty()) { + TAG_LOGD(AAFwkTag::APPKIT, "runtimes empty"); return true; } - return runtime_->NotifyHotReloadPage(); + for (const auto &runtime : runtimes_) { + if (runtime == nullptr) { + TAG_LOGD(AAFwkTag::APPKIT, "null runtime"); + continue; + } + if (!runtime->NotifyHotReloadPage()) { + return false; + } + } + return true; } bool OHOSApplication::NotifyUnLoadRepairPatch(const std::string &hqfFile) { - if (runtime_ == nullptr) { - TAG_LOGD(AAFwkTag::APPKIT, "null runtime"); + if (runtimes_.empty()) { + TAG_LOGD(AAFwkTag::APPKIT, "runtimes empty"); return true; } - return runtime_->UnLoadRepairPatch(hqfFile); + for (const auto &runtime : runtimes_) { + if (runtime == nullptr) { + TAG_LOGD(AAFwkTag::APPKIT, "null runtime"); + continue; + } + if (!runtime->UnLoadRepairPatch(hqfFile)) { + return false; + } + } + + return true; } void OHOSApplication::CleanAppTempData(bool isLastProcess) @@ -1080,5 +1138,35 @@ bool OHOSApplication::GetDisplayConfig(uint64_t displayId, float &density, std:: return true; } #endif + +const std::unique_ptr &OHOSApplication::GetRuntime(const std::string &language) const +{ + for (auto &runtime : runtimes_) { + if (runtime->GetLanguage() == ConvertLangToCode(language)) { + return runtime; + } + } + return RUNTIME_NULL; +} + +void OHOSApplication::SetCJApplication(bool isCJApplication) +{ + isCJApplication_ = isCJApplication; +} + +AbilityRuntime::Runtime::Language OHOSApplication::ConvertLangToCode(const std::string &language) const +{ + if (language == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0) { + if (isCJApplication_) { + return AbilityRuntime::Runtime::Language::CJ; + } else { + return AbilityRuntime::Runtime::Language::JS; + } + } else if (language == AbilityRuntime::CODE_LANGUAGE_ARKTS_1_2) { + return AbilityRuntime::Runtime::Language::ETS; + } else { + return AbilityRuntime::Runtime::Language::UNKNOWN; + } +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/native/runtime/cj_runtime.cpp b/frameworks/native/runtime/cj_runtime.cpp index ecf1697834d004eebefd5e2e51dbd930083283d0..5ac8d635e22ddc1bb1fa8bc735bfe17371fec614 100644 --- a/frameworks/native/runtime/cj_runtime.cpp +++ b/frameworks/native/runtime/cj_runtime.cpp @@ -118,16 +118,6 @@ bool CJRuntime::Initialize(const Options& options) return true; } -void CJRuntime::RegisterUncaughtExceptionHandler(const CJUncaughtExceptionInfo& uncaughtExceptionInfo) -{ - auto cjEnv = OHOS::CJEnv::LoadInstance(); - if (cjEnv == nullptr) { - TAG_LOGE(AAFwkTag::CJRUNTIME, "null cjEnv"); - return; - } - cjEnv->registerCJUncaughtExceptionHandler(uncaughtExceptionInfo); -} - bool CJRuntime::IsCJAbility(const std::string& info) { // in cj application, the srcEntry format should be packageName.AbilityClassName. @@ -368,4 +358,14 @@ void CJRuntime::ForceFullGC(uint32_t tid) return; } cjEnv->forceFullGC(); +} + +void CJRuntime::RegisterUncaughtExceptionHandler(void* uncaughtExceptionInfo) +{ + auto cjEnv = OHOS::CJEnv::LoadInstance(); + if (cjEnv == nullptr) { + TAG_LOGE(AAFwkTag::CJRUNTIME, "null cjEnv"); + return; + } + cjEnv->registerCJUncaughtExceptionHandler(*static_cast(uncaughtExceptionInfo)); } \ No newline at end of file diff --git a/frameworks/native/runtime/ets_data_struct_converter.cpp b/frameworks/native/runtime/ets_data_struct_converter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a3bf58cd7a6989203e3b92ca8413e4400d52f03a --- /dev/null +++ b/frameworks/native/runtime/ets_data_struct_converter.cpp @@ -0,0 +1,106 @@ +/* + * 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_data_struct_converter.h" + +#include "ani_enum_convert.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +constexpr const char *CLASSNAME_LAUNCHPARAM = "L@ohos/app/ability/AbilityConstant/LaunchParamImpl"; +constexpr const char *CLASSNAME_LAUNCHREASON = "L@ohos/app/ability/AbilityConstant/AbilityConstant/LaunchReason;"; +constexpr const char *CLASSNAME_LAST_EXITREASION = "L@ohos/app/ability/AbilityConstant/AbilityConstant/LastExitReason"; + +ani_string GetAniString(ani_env *env, const std::string &str) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "null env"); + return nullptr; + } + ani_string aniStr = nullptr; + ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to getAniString, status : %{public}d", status); + return nullptr; + } + return aniStr; +} + +bool WrapLaunchParamInner(ani_env *env, const AAFwk::LaunchParam &launchParam, ani_object &object) +{ + ani_status status = ANI_ERROR; + ani_enum_item launchReasonItem {}; + OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts( + env, CLASSNAME_LAUNCHREASON, launchParam.launchReason, launchReasonItem); + if ((status = env->Object_SetPropertyByName_Ref(object, "launchReason", launchReasonItem)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to set launchReason"); + return false; + } + + ani_enum_item lastExitReasonItem {}; + OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts( + env, CLASSNAME_LAST_EXITREASION, launchParam.lastExitReason, lastExitReasonItem); + if ((status = env->Object_SetPropertyByName_Ref(object, "lastExitReason", lastExitReasonItem)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to set lastExitReason"); + return false; + } + return true; +} +} // namespace + +bool WrapLaunchParam(ani_env *env, const AAFwk::LaunchParam &launchParam, ani_object &object) +{ + ani_method method = nullptr; + ani_status status = ANI_ERROR; + ani_class cls = nullptr; + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "null env"); + return false; + } + if ((status = env->FindClass(CLASSNAME_LAUNCHPARAM, &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to find lanchParam Class, status : %{public}d", status); + return false; + } + if (cls == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "null cls"); + return false; + } + if ((status = env->Class_FindMethod(cls, "", ":V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to find method, status : %{public}d", status); + return false; + } + if (method == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "null method"); + return false; + } + if ((status = env->Object_New(cls, method, &object)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to create object, status : %{public}d", status); + return false; + } + if (object == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "null object"); + return false; + } + if ((status = env->Object_SetPropertyByName_Ref( + object, "lastExitMessage", GetAniString(env, launchParam.lastExitMessage))) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Failed to set lastExitMessage"); + return false; + } + return WrapLaunchParamInner(env, launchParam, object); +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index 4b04f031c12904c7d98a7d13b749f99b2dd9f16b..cb7c9a217e7b2f69311463c804193995c8ffdecf 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -1765,5 +1765,12 @@ void JsRuntime::StartLocalDebugMode(bool isDebugFromLocal) debugOption_.isDebugFromLocal = isDebugFromLocal; StartDebugMode(debugOption_); } + +void JsRuntime::RegisterUncaughtExceptionHandler(void *uncaughtExceptionInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); + CHECK_POINTER(jsEnv_); + jsEnv_->RegisterUncaughtExceptionHandler(*static_cast(uncaughtExceptionInfo)); +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/runtime/runtime.cpp b/frameworks/native/runtime/runtime.cpp index 26362dd0dbbe6724c623e7a42581ceee0bdb3892..0beb1b4395345e2673aecb38702be5b990642801 100644 --- a/frameworks/native/runtime/runtime.cpp +++ b/frameworks/native/runtime/runtime.cpp @@ -19,6 +19,7 @@ #include "cj_runtime.h" #endif #include "js_runtime.h" +#include "ets_runtime.h" namespace OHOS { namespace AbilityRuntime { @@ -26,8 +27,45 @@ namespace { std::unique_ptr g_preloadedInstance; } -std::unique_ptr Runtime::Create(const Runtime::Options& options) +std::vector> Runtime::CreateRuntimes(Runtime::Options &options) { + std::vector> runtimes; + for (auto lang : options.langs) { + switch (lang.first) { + case Runtime::Language::JS: + options.lang = Runtime::Language::JS; + runtimes.emplace_back(JsRuntime::Create(options)); + break; +#ifdef CJ_FRONTEND + case Runtime::Language::CJ: + options.lang = Runtime::Language::CJ; + runtimes.emplace_back(CJRuntime::Create(options)); + break; +#endif + case Runtime::Language::ETS: { + options.lang = Runtime::Language::JS; + auto &jsRuntime = runtimes.emplace_back(JsRuntime::Create(options)); + options.lang = Runtime::Language::ETS; + runtimes.emplace_back(ETSRuntime::Create(options, + static_cast(jsRuntime.get()))); + break; + } + default: + runtimes.emplace_back(std::unique_ptr()); + break; + } + } + return runtimes; +} + +std::unique_ptr Runtime::Create(Runtime::Options &options) +{ + std::unique_ptr jsRuntime; + if (options.lang == Runtime::Language::ETS) { + options.lang = Runtime::Language::JS; + jsRuntime = JsRuntime::Create(options); + options.lang = Runtime::Language::ETS; + } switch (options.lang) { case Runtime::Language::JS: return JsRuntime::Create(options); @@ -35,6 +73,8 @@ std::unique_ptr Runtime::Create(const Runtime::Options& options) case Runtime::Language::CJ: return CJRuntime::Create(options); #endif + case Runtime::Language::ETS: + return ETSRuntime::Create(options, jsRuntime.get()); default: return std::unique_ptr(); } diff --git a/frameworks/simulator/ability_simulator/src/js_runtime.cpp b/frameworks/simulator/ability_simulator/src/js_runtime.cpp index 7e173d8a07c02d6a7e8b4b074b6642a97dd33f1b..3bed249733a419884556d1f715175eaeb43bb774 100644 --- a/frameworks/simulator/ability_simulator/src/js_runtime.cpp +++ b/frameworks/simulator/ability_simulator/src/js_runtime.cpp @@ -158,5 +158,8 @@ std::unique_ptr JsRuntime::LoadSystemModuleByEngine( napi_create_reference(env, instanceValue, 1, &result); return std::unique_ptr(reinterpret_cast(result)); } + +void JsRuntime::RegisterUncaughtExceptionHandler(void *uncaughtExceptionInfo) +{} } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/runtime/BUILD.gn b/interfaces/inner_api/runtime/BUILD.gn index 836d126b83bdd2b6b003f52e584aaee97e588774..9b78f45490fd2368da7553467750c89ae3e6ffb6 100644 --- a/interfaces/inner_api/runtime/BUILD.gn +++ b/interfaces/inner_api/runtime/BUILD.gn @@ -52,6 +52,7 @@ ohos_shared_library("runtime") { branch_protector_ret = "pac_ret" include_dirs = [ + "${ability_runtime_path}/ets_environment/interfaces/inner_api", "${ability_runtime_path}/services/abilitymgr/include", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_bundle_manager_helper", "${ability_runtime_path}/frameworks/ets/ani/enum_convert", @@ -60,6 +61,8 @@ ohos_shared_library("runtime") { sources = [ "${ability_runtime_native_path}/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp", + "${ability_runtime_native_path}/runtime/ets_data_struct_converter.cpp", + "${ability_runtime_native_path}/runtime/ets_runtime.cpp", "${ability_runtime_native_path}/runtime/hdc_register.cpp", "${ability_runtime_native_path}/runtime/js_app_process_state.cpp", "${ability_runtime_native_path}/runtime/js_data_struct_converter.cpp", @@ -90,6 +93,7 @@ ohos_shared_library("runtime") { "${ability_runtime_innerkits_path}/connect_server_manager:connect_server_manager", "${ability_runtime_native_path}/ability/native:ability_business_error", "${ability_runtime_native_path}/appkit:appkit_manager_helper", + "${ability_runtime_path}/ets_environment/frameworks/ets_environment:ets_environment", "${ability_runtime_path}/js_environment/frameworks/js_environment:js_environment", "${ability_runtime_services_path}/common:app_util", "${ability_runtime_services_path}/common:record_cost_time_util", @@ -122,6 +126,7 @@ ohos_shared_library("runtime") { "jsoncpp:jsoncpp", "napi:ace_napi", "resource_management:global_resmgr", + "runtime_core:ani", "samgr:samgr_proxy", "zlib:shared_libz", "faultloggerd:libfaultloggerd", diff --git a/interfaces/inner_api/runtime/include/cj_runtime.h b/interfaces/inner_api/runtime/include/cj_runtime.h index 0d406dc6f33831c5cb9d87bdf67ff7716a125292..04778b740086e49638f4e4ad07afd4a2051d6168 100644 --- a/interfaces/inner_api/runtime/include/cj_runtime.h +++ b/interfaces/inner_api/runtime/include/cj_runtime.h @@ -55,6 +55,8 @@ public: const std::string& hapPath, bool isEsMode, const std::string& srcEntrance) override {} void PreloadModule(const std::string& moduleName, const std::string& srcPath, const std::string& hapPath, bool isEsMode, bool useCommonTrunk) override {} + void PreloadModule(const std::string& moduleName, const std::string& hapPath, + bool isEsMode, bool useCommonTrunk) override {} void FinishPreload() override {} bool LoadRepairPatch(const std::string& patchFile, const std::string& baseFile) override { return false; } bool NotifyHotReloadPage() override { return false; } @@ -72,8 +74,8 @@ public: void DumpCpuProfile() override {}; void AllowCrossThreadExecution() override {}; void GetHeapPrepare() override {}; - void RegisterUncaughtExceptionHandler(const CJUncaughtExceptionInfo& uncaughtExceptionInfo); static bool RegisterCangjieCallback(); + void RegisterUncaughtExceptionHandler(void* uncaughtExceptionInfo) override; private: bool StartDebugger(); diff --git a/interfaces/inner_api/runtime/include/ets_data_struct_converter.h b/interfaces/inner_api/runtime/include/ets_data_struct_converter.h new file mode 100644 index 0000000000000000000000000000000000000000..1f196768185cd4881b89b7fc3874b6c709a3e3f7 --- /dev/null +++ b/interfaces/inner_api/runtime/include/ets_data_struct_converter.h @@ -0,0 +1,27 @@ +/* + * 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_DATA_STRUCT_CONVERTER_H +#define OHOS_ABILITY_RUNTIME_ETS_DATA_STRUCT_CONVERTER_H + +#include "ani.h" +#include "launch_param.h" + +namespace OHOS { +namespace AbilityRuntime { +bool WrapLaunchParam(ani_env *env, const AAFwk::LaunchParam &launchParam, ani_object &object); +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_DATA_STRUCT_CONVERTER_H diff --git a/interfaces/inner_api/runtime/include/js_runtime.h b/interfaces/inner_api/runtime/include/js_runtime.h index d573886e3c6ebcf7164668e9129cedb044bedfed..dcc410a2cf06f39e99a6cb99bf728dbb3a9483a3 100644 --- a/interfaces/inner_api/runtime/include/js_runtime.h +++ b/interfaces/inner_api/runtime/include/js_runtime.h @@ -103,6 +103,8 @@ public: const std::string& hapPath, bool isEsMode, const std::string& srcEntrance) override; void PreloadModule(const std::string& moduleName, const std::string& srcPath, const std::string& hapPath, bool isEsMode, bool useCommonTrunk) override; + void PreloadModule(const std::string &moduleName, const std::string &hapPath, + bool isEsMode, bool useCommonTrunk) override {} bool PopPreloadObj(const std::string& key, std::unique_ptr& obj); void StartDebugMode(const DebugOption debugOption) override; void SetDebugOption(const DebugOption debugOption) override; @@ -156,6 +158,7 @@ public: void SetPkgContextInfoJson(std::string moduleName, std::string hapPath, std::string packageName); void UpdatePkgContextInfoJson(const std::string& moduleName, const std::string& hapPath, const std::string& packageName); + void RegisterUncaughtExceptionHandler(void *uncaughtExceptionInfo) override; private: void FinishPreload() override; diff --git a/interfaces/inner_api/runtime/include/runtime.h b/interfaces/inner_api/runtime/include/runtime.h index 5b3312752f12c526bc9eac08395af8e769c84cc4..faf6685bbd2e6e2d5159820a1b539585682e7f1b 100644 --- a/interfaces/inner_api/runtime/include/runtime.h +++ b/interfaces/inner_api/runtime/include/runtime.h @@ -27,14 +27,23 @@ namespace AppExecFwk { class EventRunner; } // namespace AppExecFwk namespace AbilityRuntime { +namespace { +const std::string CODE_LANGUAGE_ARKTS_1_0 = "1.1"; +const std::string CODE_LANGUAGE_ARKTS_1_2 = "1.2"; +const std::string CODE_LANGUAGE_ARKTS_HYBRID = "hybrid"; +} // namespace + class Runtime { public: enum class Language { JS = 0, - CJ + CJ, + ETS, + UNKNOWN, }; struct Options { + std::map langs; Language lang = Language::JS; std::string bundleName; std::string moduleName; @@ -80,7 +89,8 @@ public: bool isDeveloperMode; }; - static std::unique_ptr Create(const Options& options); + static std::vector> CreateRuntimes(Options &options); + static std::unique_ptr Create(Options &options); static void SavePreloaded(std::unique_ptr&& instance); static std::unique_ptr GetPreloaded(); @@ -108,6 +118,8 @@ public: const std::string& hapPath, bool isEsMode, const std::string& srcEntrance) = 0; virtual void PreloadModule(const std::string& moduleName, const std::string& srcPath, const std::string& hapPath, bool isEsMode, bool useCommonTrunk) = 0; + virtual void PreloadModule(const std::string &moduleName, const std::string &hapPath, + bool isEsMode, bool useCommonTrunk) {} virtual void FinishPreload() = 0; virtual bool LoadRepairPatch(const std::string& patchFile, const std::string& baseFile) = 0; virtual bool NotifyHotReloadPage() = 0; @@ -122,6 +134,7 @@ public: Runtime(Runtime&&) = delete; Runtime& operator=(const Runtime&) = delete; Runtime& operator=(Runtime&&) = delete; + virtual void RegisterUncaughtExceptionHandler(void *uncaughtExceptionInfo) {} }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/ability/native/ability_loader.h b/interfaces/kits/native/ability/native/ability_loader.h index 23947ec898c2169a47b0bfab43365a590337d66b..18fd34818d50bb9987e01b62b66220331fc1f784 100644 --- a/interfaces/kits/native/ability/native/ability_loader.h +++ b/interfaces/kits/native/ability/native/ability_loader.h @@ -28,9 +28,9 @@ namespace OHOS { namespace AppExecFwk { -using CreateExtension = std::function; +using CreateExtension = std::function; using CreateAblity = std::function; -using CreateUIAbility = std::function; +using CreateUIAbility = std::function; #ifdef ABILITY_WINDOW_SUPPORT using CreateSlice = std::function; #endif @@ -90,14 +90,15 @@ public: * * @return return Ability address */ - AbilityRuntime::Extension *GetExtensionByName(const std::string &abilityName); + AbilityRuntime::Extension *GetExtensionByName(const std::string &abilityName, + const std::string &language = AbilityRuntime::CODE_LANGUAGE_ARKTS_1_0); /** * @brief Get UIAbility address * @param abilityName UIAbility classname * @return return UIAbility address */ - AbilityRuntime::UIAbility *GetUIAbilityByName(const std::string &abilityName); + AbilityRuntime::UIAbility *GetUIAbilityByName(const std::string &abilityName, const std::string &language); #ifdef ABILITY_WINDOW_SUPPORT void RegisterAbilitySlice(const std::string &sliceName, const CreateSlice &createFunc); diff --git a/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability.h b/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability.h new file mode 100644 index 0000000000000000000000000000000000000000..cecb7e7a835c7cfd6d908adde75cc8033c6135ab --- /dev/null +++ b/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability.h @@ -0,0 +1,168 @@ +/* + * 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_UI_ABILITY_H +#define OHOS_ABILITY_RUNTIME_ETS_UI_ABILITY_H + +#include "ets_runtime.h" +#include "ui_ability.h" + +namespace OHOS { +namespace AbilityRuntime { +using AbilityHandler = AppExecFwk::AbilityHandler; +using AbilityInfo = AppExecFwk::AbilityInfo; +using OHOSApplication = AppExecFwk::OHOSApplication; +using Want = AppExecFwk::Want; + +class EtsUIAbility : public UIAbility { +public: + /** + * @brief Create a EtsUIAbility instance through the singleton pattern + * @param runtime The runtime of the ability + * @return Returns the EtsUIability Instance point + */ + static UIAbility *Create(const std::unique_ptr &runtime); + + explicit EtsUIAbility(ETSRuntime &etsRuntime); + ~EtsUIAbility() override; + + /** + * @brief Init the UIability + * @param abilityInfo Indicate the Ability information + * @param application Indicates the main process + * @param handler the UIability EventHandler object + * @param token the remote token + */ + void Init(std::shared_ptr record, + const std::shared_ptr application, + std::shared_ptr &handler, const sptr &token) override; + + /** + * @brief OnStart,Start EtssUIability + * @param want Indicates the {@link Want} structure containing startup information about the ability + * @param sessionInfo Indicates the sessionInfo + */ + void OnStart(const Want &want, sptr sessionInfo = nullptr) override; + + /** + * @brief Called when this ability enters the STATE_STOP state. + * The ability in the STATE_STOP is being destroyed. + * You can override this function to implement your own processing logic. + */ + void OnStop() override; + + /** + * @brief Called when this ability enters the STATE_STOP state. + * The ability in the STATE_STOP is being destroyed. + * You can override this function to implement your own processing logic. + * @param callbackInfo Indicates the lifecycle transaction callback information + * @param isAsyncCallback Indicates whether it is an asynchronous lifecycle callback + */ + void OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback) override; + + /** + * @brief The callback of OnStop. + */ + void OnStopCallback() override; + + /** + * @brief Called when the launch mode of an ability is set to singleInstance. This happens when you re-launch an + * ability that has been at the top of the ability stack. + * @param want Indicates the new Want containing information about the ability. + */ + void OnNewWant(const Want &want) override; + + /** + * @brief Called when startAbilityForResult(ohos.aafwk.content.Want,int) is called to start an ability and the + * result is returned. This method is called only on Page abilities. You can start a new ability to perform some + * calculations and use setResult (int,ohos.aafwk.content.Want) to return the calculation result. Then the system + * calls back the current method to use the returned data to execute its own logic. + * @param requestCode Indicates the request code returned after the ability is started. You can define the request + * code to identify the results returned by abilities. The value ranges from 0 to 65535. + * @param resultCode Indicates the result code returned after the ability is started. You can define the result code + * to identify an error. + * @param want Indicates the data returned after the ability is started. You can define the data returned. The + * value can be null. + */ + void OnAbilityResult(int requestCode, int resultCode, const Want &resultData) override; + +#ifdef SUPPORT_SCREEN +public: + /** + * @brief Called after instantiating WindowScene. + * You can override this function to implement your own processing logic. + */ + void OnSceneCreated() override; + + /** + * @brief Called after ability stoped. + * You can override this function to implement your own processing logic. + */ + void onSceneDestroyed() override; + + /** + * @brief Called when this ability enters the STATE_FOREGROUND state. + * The ability in the STATE_FOREGROUND state is visible. + * You can override this function to implement your own processing logic. + */ + void OnForeground(const Want &want) override; + + /** + * @brief Call "onForeground" ets function barely. + * + * @param want Want + */ + void CallOnForegroundFunc(const Want &want) override; + + /** + * @brief Called when this ability enters the STATE_BACKGROUND state. + * The ability in the STATE_BACKGROUND state is invisible. + * You can override this function to implement your own processing logic. + */ + void OnBackground() override; + +protected: + void DoOnForeground(const Want &want) override; + void ContinuationRestore(const Want &want) override; + +private: + bool IsRestorePageStack(const Want &want); + void RestorePageStack(const Want &want); + void GetPageStackFromWant(const Want &want, std::string &pageStack); + void AbilityContinuationOrRecover(const Want &want); + void UpdateEtsWindowStage(ani_ref windowStage); + + std::shared_ptr etsWindowStageObj_; + int32_t windowMode_ = 0; +#endif + +private: + bool CallObjectMethod(bool withResult, const char *name, const char *signature, ...); + ani_object CreateAppWindowStage(); + void SetAbilityContext(std::shared_ptr abilityInfo, std::shared_ptr want, + const std::string &moduleName, const std::string &srcPath, const std::shared_ptr &application); + void DoOnForegroundForSceneIsNull(const Want &want); + void UpdateAbilityObj(std::shared_ptr abilityInfo, + const std::string &moduleName, const std::string &srcPath); + bool BindNativeMethods(); + + ETSRuntime &etsRuntime_; + std::shared_ptr shellContextRef_; + std::shared_ptr etsAbilityObj_; + static std::once_flag singletonFlag_; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_UI_ABILITY_H diff --git a/interfaces/kits/native/appkit/ability_delegator/ability_delegator.h b/interfaces/kits/native/appkit/ability_delegator/ability_delegator.h index 19f5e0cc52d31c6dd92d0b02307f26b08bbbe684..217952afe26a524a30c56f8acd053dac2580b6c3 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 3f649fb32ca560401bec844e17ba2aa09b7759c7..f270031824370cce3aef58ce783f981a5bdc2809 100644 --- a/interfaces/kits/native/appkit/ability_delegator/ability_delegator_infos.h +++ b/interfaces/kits/native/appkit/ability_delegator/ability_delegator_infos.h @@ -19,12 +19,14 @@ #include #include "ability_lifecycle_executor.h" #include "iremote_object.h" +#include "ets_runtime.h" class NativeReference; namespace OHOS { namespace AppExecFwk { -struct ADelegatorAbilityProperty { + +struct BaseDelegatorAbilityProperty { // token of ability sptr token_; // name of ability @@ -35,10 +37,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/ability_delegator_registry.h b/interfaces/kits/native/appkit/ability_delegator/ability_delegator_registry.h index 1fd257b82310397e327403373df4e0ca6800e3ff..57f9c383be7d8d3bf41457d9cfe902ea43a2a0f5 100644 --- a/interfaces/kits/native/appkit/ability_delegator/ability_delegator_registry.h +++ b/interfaces/kits/native/appkit/ability_delegator/ability_delegator_registry.h @@ -24,6 +24,7 @@ #include "cj_ability_delegator_impl.h" #endif #include "iability_delegator.h" +#include "runtime.h" namespace OHOS { namespace AppExecFwk { @@ -34,7 +35,8 @@ public: * * @return the AbilityDelegator object initialized when the application is started. */ - static std::shared_ptr GetAbilityDelegator(); + static std::shared_ptr GetAbilityDelegator( + const AbilityRuntime::Runtime::Language &language = AbilityRuntime::Runtime::Language::JS); #ifdef CJ_FRONTEND /** @@ -60,10 +62,11 @@ public: * @param args, Indicates the AbilityDelegatorArgs object. */ static void RegisterInstance( - const std::shared_ptr& delegator, const std::shared_ptr& args); + const std::shared_ptr &delegator, const std::shared_ptr &args, + const AbilityRuntime::Runtime::Language &language); private: - static std::shared_ptr abilityDelegator_; + static std::map> abilityDelegator_; static std::shared_ptr abilityDelegatorArgs_; }; } // namespace AppExecFwk diff --git a/interfaces/kits/native/appkit/ability_delegator/iability_monitor.h b/interfaces/kits/native/appkit/ability_delegator/iability_monitor.h index 6a91fec773201b81359d67c387fe3365d2462038..f899604dd30c7cec97896334d12c7a1ff23cf87e 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/app/application_data_manager.h b/interfaces/kits/native/appkit/app/application_data_manager.h index 3f8bb01b4e78f8521570be79cb8903df71347d6f..08ddb478a740ecafb472a6d10f3cc96fda3c749b 100644 --- a/interfaces/kits/native/appkit/app/application_data_manager.h +++ b/interfaces/kits/native/appkit/app/application_data_manager.h @@ -29,9 +29,11 @@ public: void AddErrorObserver(const std::shared_ptr &observer); bool NotifyUnhandledException(const std::string &errMsg); bool NotifyCJUnhandledException(const std::string &errMsg); + bool NotifyETSUnhandledException(const std::string &errMsg); void RemoveErrorObserver(); bool NotifyExceptionObject(const AppExecFwk::ErrorObject &errorObj); bool NotifyCJExceptionObject(const AppExecFwk::ErrorObject &errorObj); + bool NotifyETSExceptionObject(const AppExecFwk::ErrorObject &errorObj); private: ApplicationDataManager(); diff --git a/interfaces/kits/native/appkit/app/main_thread.h b/interfaces/kits/native/appkit/app/main_thread.h index cd5a86a89c5cbfb55f5c95dc2c01fbc909339670..a7e7e7f94156d3490723c2b04222bc51170ae840 100644 --- a/interfaces/kits/native/appkit/app/main_thread.h +++ b/interfaces/kits/native/appkit/app/main_thread.h @@ -40,6 +40,7 @@ #include "resource_manager.h" #include "runtime.h" #include "watchdog.h" +#include "ets_runtime.h" #ifdef CJ_FRONTEND #include "cj_envsetup.h" @@ -323,6 +324,8 @@ public: CJUncaughtExceptionInfo CreateCjExceptionInfo(const std::string &bundleName, uint32_t versionCode, const std::string &hapPath); #endif + EtsEnv::ETSUncaughtExceptionInfo CreateEtsExceptionInfo(const std::string &bundleName, uint32_t versionCode, + const std::string &hapPath, std::string &appRunningId, int32_t pid, std::string &processName); /** * @brief Notify NativeEngine GC of status change. * @@ -622,7 +625,8 @@ private: * */ bool PrepareAbilityDelegator(const std::shared_ptr &record, bool isStageBased, - const AppExecFwk::HapModuleInfo &entryHapModuleInfo, uint32_t targetVersion); + const AppExecFwk::HapModuleInfo &entryHapModuleInfo, uint32_t targetVersion, + const std::string &applicationCodeLanguage); /** * @brief Set current process extension type @@ -797,6 +801,12 @@ private: void SetAppDebug(uint32_t modeFlag, bool isDebug); void GetPluginNativeLibPath(std::vector &pluginBundleInfos, AppLibPathMap &appLibPaths); + void AddRuntimeLang(ApplicationInfo &appInfo, AbilityRuntime::Runtime::Options &options); + bool IsNeedEtsInit(const ApplicationInfo &appInfo); + const std::unique_ptr &GetVerOneRuntime( + const ApplicationInfo &appInfo, const std::vector> &runtimes); + void SetJsIdleCallback(const std::weak_ptr &wpApplication, + const std::unique_ptr &runtime); std::vector fileEntries_; std::vector nativeFileEntries_; diff --git a/interfaces/kits/native/appkit/app/ohos_application.h b/interfaces/kits/native/appkit/app/ohos_application.h index 783bd601495d60835ba55080a9bf51a95ec5992d..3bc1c5697a8c5f78a57f34fd5c3b3fb2850cd708 100644 --- a/interfaces/kits/native/appkit/app/ohos_application.h +++ b/interfaces/kits/native/appkit/app/ohos_application.h @@ -27,6 +27,7 @@ #include "ability_stage_context.h" #include "application_configuration_manager.h" #include "app_launch_data.h" +#include "runtime.h" namespace OHOS { namespace AbilityRuntime { @@ -49,11 +50,11 @@ public: void DumpApplication(); /** - * @brief Set Runtime + * @brief Add Runtime * * @param runtime Runtime instance. */ - void SetRuntime(std::unique_ptr&& runtime); + void AddRuntime(std::unique_ptr &&runtime); /** * @brief Set ApplicationContext @@ -168,12 +169,19 @@ public: */ std::shared_ptr GetAppContext() const; + /** + * @brief return the application runtimes + * + * @param runtime + */ + const std::vector> &GetRuntime() const; + /** * @brief return the application runtime * * @param runtime */ - const std::unique_ptr& GetRuntime() const; + const std::unique_ptr &GetRuntime(const std::string &language) const; /* * @@ -236,6 +244,8 @@ public: void PreloadAppStartup(const BundleInfo &bundleInfo, const std::string &preloadModuleName, std::shared_ptr startupTaskData); + void SetCJApplication(bool isCJApplication = false); + private: void UpdateAppContextResMgr(const Configuration &config); bool IsUpdateColorNeeded(Configuration &config, AbilityRuntime::SetLevel level); @@ -251,14 +261,17 @@ private: const AppExecFwk::HapModuleInfo &hapModuleInfo, const std::function& callback); bool IsMainProcess(const std::string &bundleName, const std::string &process); + AbilityRuntime::Runtime::Language ConvertLangToCode(const std::string &language) const; + void PreloadHybridModule(const HapModuleInfo &hapModuleInfo) const; private: std::shared_ptr abilityRecordMgr_ = nullptr; std::shared_ptr abilityRuntimeContext_ = nullptr; std::unordered_map> abilityStages_; - std::unique_ptr runtime_; + std::vector> runtimes_; std::shared_ptr configuration_ = nullptr; std::map extensionTypeMap_; + bool isCJApplication_ = false; }; } // namespace AppExecFwk } // namespace OHOS