diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index 7bc7dddc53d4776466db93ba0ac028cb582f35bc..a0063fbc25f9d376a65651730a09c5c2c922e510 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -22,6 +22,7 @@ group("ani_packages") { "${ability_runtime_path}/frameworks/ets/ani/ani_wantagent_common:ani_wantagent_common", "${ability_runtime_path}/frameworks/ets/ani/app_manager:app_manager_ani", "${ability_runtime_path}/frameworks/ets/ani/application:application_ani", + "${ability_runtime_path}/frameworks/ets/ani/app/ability_context:ability_context_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/insight_intent/insight_intent_driver:insight_intent_driver_ani_kit", "${ability_runtime_path}/frameworks/ets/ani/native_constructor:context_ani", "${ability_runtime_path}/frameworks/ets/ani/uri_permission_manager:uri_permission_manager_ani_kit", diff --git a/frameworks/ets/ani/ani_common/include/ets_context_utils.h b/frameworks/ets/ani/ani_common/include/ets_context_utils.h index 159b325bd34f2b9c7564de0386c81feb60857028..a67924090f8c859ba8a92769c091151b7b0721d0 100644 --- a/frameworks/ets/ani/ani_common/include/ets_context_utils.h +++ b/frameworks/ets/ani/ani_common/include/ets_context_utils.h @@ -29,6 +29,7 @@ void BindResourceManager(ani_env *aniEnv, ani_class contextClass, ani_object con void CreateEtsBaseContext(ani_env *aniEnv, ani_class contextClass, ani_object contextObj, std::shared_ptr context); ani_object GetApplicationContextSync(ani_env *env, ani_object aniObj); +std::shared_ptr GetBaseContext(ani_env *env, ani_object aniObj); void SwitchArea(ani_env *env, ani_object obj, ani_enum_item areaModeItem); ani_enum_item GetArea(ani_env *env, ani_object obj); ani_object CreateModuleResourceManagerSync(ani_env *env, ani_object aniObj, diff --git a/frameworks/ets/ani/app/ability_context/BUILD.gn b/frameworks/ets/ani/app/ability_context/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5eb598fce09f43a65667d6d4ca57dd0acac14280 --- /dev/null +++ b/frameworks/ets/ani/app/ability_context/BUILD.gn @@ -0,0 +1,72 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +ohos_shared_library("ability_context_ani_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "./include", + "${ability_runtime_path}/interfaces/inner_api", + "${ability_runtime_path}/interfaces/kits/native/appkit", + "${ability_runtime_path}/interfaces/kits/native/ability/native/ability_runtime", + "${ability_runtime_services_path}/common/include", + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/ui_ability/include", + ] + + configs = [] + + public_configs = [] + + sources = [ "./src/ets_ability_context_module.cpp" ] + + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + deps = [ + "${ability_runtime_innerkits_path}/ani_base_context:ani_base_context", + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_native_path}/ability/native:abilitykit_native", + "${ability_runtime_native_path}/ability/native:ui_ability_ani", + "${ability_runtime_native_path}/ability:ability_context_native", + "${ability_runtime_native_path}/appkit:app_context", + "${ability_runtime_native_path}/appkit:app_context_utils", + "${ability_runtime_native_path}/appkit:appkit_native", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "napi:ace_napi", + "runtime_core:ani", + "runtime_core:ani_helpers", + ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/frameworks/ets/ani/app/ability_context/include/ets_ability_context_module.h b/frameworks/ets/ani/app/ability_context/include/ets_ability_context_module.h new file mode 100644 index 0000000000000000000000000000000000000000..46d7f78c5eb20d44f51ebabc60c40dce2dbd0ae5 --- /dev/null +++ b/frameworks/ets/ani/app/ability_context/include/ets_ability_context_module.h @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_ABILITY_RUNTIME_ETS_ABILITY_CONTEXT_MODULE_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_CONTEXT_MODULE_H + +#include +#include "ability_context.h" +#include "ani.h" +#include "native_engine/native_engine.h" + +namespace OHOS { +namespace AbilityRuntime { +class EtsAbilityContextModule { +public: + EtsAbilityContextModule() = default; + ~EtsAbilityContextModule() = default; + + EtsAbilityContextModule(const EtsAbilityContextModule&) = delete; + EtsAbilityContextModule(EtsAbilityContextModule&&) = delete; + EtsAbilityContextModule& operator=(const EtsAbilityContextModule&) = delete; + EtsAbilityContextModule& operator=(EtsAbilityContextModule&&) = delete; + + static ani_object NativeTransferStatic(ani_env *aniEnv, ani_object aniObj, ani_object input, ani_object type); + static ani_object NativeTransferDynamic(ani_env *aniEnv, ani_class aniCls, ani_object input); + static napi_value GetOrCreateDynamicObject(napi_env napiEnv, + std::shared_ptr abilityContext); + +private: + static bool IsInstanceOf(ani_env *aniEnv, ani_object aniObj); + static std::unique_ptr CreateNativeReference(napi_env napiEnv, + std::shared_ptr abilityContext); + static ani_object CreateDynamicObject(ani_env *aniEnv, ani_class aniCls, + std::shared_ptr abilityContext); +}; + +void EtsAbilityContextModuleInit(ani_env *aniEnv); +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_CONTEXT_MODULE_H diff --git a/frameworks/ets/ani/app/ability_context/src/ets_ability_context_module.cpp b/frameworks/ets/ani/app/ability_context/src/ets_ability_context_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..638c9a786b87b2f960cb4bc1cbcc269b2ccfa7a3 --- /dev/null +++ b/frameworks/ets/ani/app/ability_context/src/ets_ability_context_module.cpp @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ets_ability_context_module.h" + +#include +#include +#include +#include "ability_context.h" +#include "ani_base_context.h" +#include "ani_common_util.h" +#include "context_transfer.h" +#include "ets_ability_context.h" +#include "ets_error_utils.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "interop_js/arkts_esvalue.h" +#include "interop_js/arkts_interop_js_api.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include "js_ability_context.h" +#include "js_runtime_utils.h" +#include "native_engine/native_engine.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +constexpr const char *ETS_ABILITY_CONTEXT_CLASS_NAME = "Lapplication/UIAbilityContext/UIAbilityContext;"; +} // namespace + +ani_object EtsAbilityContextModule::NativeTransferStatic(ani_env *aniEnv, ani_object, ani_object input, + ani_object type) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::CONTEXT, "transfer static AbilityContext"); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null aniEnv"); + return nullptr; + } + + void *unwrapResult = nullptr; + bool success = arkts_esvalue_unwrap(aniEnv, input, &unwrapResult); + if (!success) { + TAG_LOGE(AAFwkTag::CONTEXT, "failed to unwrap"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + if (unwrapResult == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null unwrapResult"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto context = reinterpret_cast *>(unwrapResult)->lock(); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null AbilityContext"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto abilityContext = Context::ConvertTo(context); + if (abilityContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "invalid abilityContext"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto &bindingObj = abilityContext->GetBindingObject(); + if (bindingObj == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null bindingObj"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto staticContext = bindingObj->Get(); + if (staticContext != nullptr) { + TAG_LOGI(AAFwkTag::CONTEXT, "there exist a staticContext"); + return reinterpret_cast(*staticContext); + } + + // if not exist, create a new one + std::string contextType; + if (!AppExecFwk::GetStdString(aniEnv, reinterpret_cast(type), contextType)) { + TAG_LOGE(AAFwkTag::JSNAPI, "GetStdString failed"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + TAG_LOGD(AAFwkTag::CONTEXT, "contextType %{public}s", contextType.c_str()); + + auto newContext = ContextTransfer::GetInstance().GetStaticObject(contextType, aniEnv, context); + if (newContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "create abilityContext failed"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + return newContext; +} + +std::unique_ptr EtsAbilityContextModule::CreateNativeReference(napi_env napiEnv, + std::shared_ptr abilityContext) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (napiEnv == nullptr || abilityContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null param"); + return nullptr; + } + + auto value = CreateJsAbilityContext(napiEnv, abilityContext); + auto systemModule = JsRuntime::LoadSystemModuleByEngine(napiEnv, "application.AbilityContext", &value, 1); + if (systemModule == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null systemModule"); + return nullptr; + } + + napi_value object = systemModule->GetNapiValue(); + if (!CheckTypeForNapiValue(napiEnv, object, napi_object)) { + TAG_LOGE(AAFwkTag::CONTEXT, "check type failed"); + return nullptr; + } + + auto workContext = new (std::nothrow) std::weak_ptr(abilityContext); + if (workContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null workContext"); + return nullptr; + } + auto status = napi_coerce_to_native_binding_object(napiEnv, object, DetachCallbackFunc, AttachJsUIAbilityContext, + workContext, nullptr); + if (status != napi_ok) { + TAG_LOGE(AAFwkTag::CONTEXT, "coerce AbilityContext failed: %{public}d", status); + delete workContext; + return nullptr; + } + + status = napi_wrap(napiEnv, object, workContext, + [](napi_env, void *data, void *) { + TAG_LOGD(AAFwkTag::CONTEXT, "finalizer for weak_ptr AbilityContext"); + delete static_cast *>(data); + }, nullptr, nullptr); + if (status != napi_ok) { + TAG_LOGE(AAFwkTag::CONTEXT, "wrap failed: %{public}d", status); + delete workContext; + return nullptr; + } + + return systemModule; +} + +napi_value EtsAbilityContextModule::GetOrCreateDynamicObject(napi_env napiEnv, + std::shared_ptr abilityContext) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (napiEnv == nullptr || abilityContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null param"); + return nullptr; + } + + // if sub-thread, create a new abilityContext and return + if (getpid() != syscall(SYS_gettid)) { + auto subThreadObj = static_cast( + abilityContext->GetSubThreadObject(static_cast(napiEnv))); + if (subThreadObj != nullptr) { + return subThreadObj->Get(); + } + auto subThreadRef = CreateNativeReference(napiEnv, abilityContext); + if (subThreadRef == nullptr) { + return nullptr; + } + auto newObject = subThreadRef->Get(); + abilityContext->BindSubThreadObject( + static_cast(napiEnv), static_cast(subThreadRef.release())); + return newObject; + } + + // if main-thread, get bindingObj firstly + auto &bindingObj = abilityContext->GetBindingObject(); + if (bindingObj == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null bindingObj"); + return nullptr; + } + + // if main-thread bindingObj exist, return it directly + auto dynamicContext = bindingObj->Get(); + if (dynamicContext != nullptr) { + TAG_LOGI(AAFwkTag::UIABILITY, "there exist a dynamicContext"); + return dynamicContext->Get(); + } + + // if main-thread bindingObj didn't exist, return null + return nullptr; +} + +ani_object EtsAbilityContextModule::NativeTransferDynamic(ani_env *aniEnv, ani_class aniCls, ani_object input) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::CONTEXT, "transfer dynamic AbilityContext"); + if (!IsInstanceOf(aniEnv, input)) { + TAG_LOGE(AAFwkTag::CONTEXT, "not AbilityContext"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + auto context = AbilityRuntime::GetStageModeContext(aniEnv, input); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null context"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + std::shared_ptr abilityContext = Context::ConvertTo(context); + if (abilityContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "invalid abilityContext"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + ani_object object = CreateDynamicObject(aniEnv, aniCls, abilityContext); + if (object == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "invalid object"); + EtsErrorUtil::ThrowEtsTransferClassError(aniEnv); + return nullptr; + } + + return object; +} + +ani_object EtsAbilityContextModule::CreateDynamicObject(ani_env *aniEnv, ani_class aniCls, + std::shared_ptr abilityContext) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + std::string contextType; + if (!AppExecFwk::GetStaticFieldString(aniEnv, aniCls, "contextType", contextType)) { + TAG_LOGE(AAFwkTag::CONTEXT, "get context type failed"); + return nullptr; + } + TAG_LOGD(AAFwkTag::CONTEXT, "contextType %{public}s", contextType.c_str()); + + // get napiEnv from aniEnv + napi_env napiEnv = {}; + if (!arkts_napi_scope_open(aniEnv, &napiEnv)) { + TAG_LOGE(AAFwkTag::CONTEXT, "arkts_napi_scope_open failed"); + return nullptr; + } + + // create normal ability context + auto contextObj = ContextTransfer::GetInstance().GetDynamicObject(contextType, napiEnv, abilityContext); + if (contextObj == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "create AbilityContext failed"); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return nullptr; + } + + hybridgref ref = nullptr; + bool success = hybridgref_create_from_napi(napiEnv, contextObj, &ref); + if (!success) { + TAG_LOGE(AAFwkTag::CONTEXT, "hybridgref_create_from_napi failed"); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return nullptr; + } + + ani_object result = nullptr; + success = hybridgref_get_esvalue(aniEnv, ref, &result); + if (!success) { + TAG_LOGE(AAFwkTag::CONTEXT, "hybridgref_get_esvalue failed"); + hybridgref_delete_from_napi(napiEnv, ref); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return nullptr; + } + + hybridgref_delete_from_napi(napiEnv, ref); + + if (!arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr)) { + TAG_LOGE(AAFwkTag::CONTEXT, "arkts_napi_scope_close_n failed"); + return nullptr; + } + + return result; +} + +bool EtsAbilityContextModule::IsInstanceOf(ani_env *aniEnv, ani_object aniObj) +{ + ani_class cls {}; + ani_status status = ANI_ERROR; + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null aniEnv"); + return false; + } + if ((status = aniEnv->FindClass(ETS_ABILITY_CONTEXT_CLASS_NAME, &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "FindClass status: %{public}d", status); + return false; + } + ani_boolean isInstanceOf = false; + if ((status = aniEnv->Object_InstanceOf(aniObj, cls, &isInstanceOf)) != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "Object_InstanceOf status: %{public}d", status); + return false; + } + return isInstanceOf; +} + +void EtsAbilityContextModuleInit(ani_env *aniEnv) +{ + TAG_LOGD(AAFwkTag::CONTEXT, "Init AbilityContext kit"); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null ani env"); + return; + } + + ani_class abilityContextCls = nullptr; + auto status = aniEnv->FindClass(ETS_ABILITY_CONTEXT_CLASS_NAME, &abilityContextCls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "FindClass AbilityContext failed status: %{public}d", status); + return; + } + + std::array nativeFuncs = { + ani_native_function { "nativeTransferStatic", "Lstd/interop/ESValue;Lstd/core/String;:Lstd/core/Object;", + reinterpret_cast(EtsAbilityContextModule::NativeTransferStatic) }, + ani_native_function { "nativeTransferDynamic", "Lstd/core/Object;:Lstd/interop/ESValue;", + reinterpret_cast(EtsAbilityContextModule::NativeTransferDynamic) }, + }; + status = aniEnv->Class_BindNativeMethods(abilityContextCls, nativeFuncs.data(), nativeFuncs.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_BindNativeMethods failed status: %{public}d", status); + return; + } + + ContextTransfer::GetInstance().RegisterStaticObjectCreator("UIAbilityContext", + [](ani_env *aniEnv, std::shared_ptr context) -> ani_object { + TAG_LOGE(AAFwkTag::APPKIT, "AbilityContext should be created during ability startup"); + return nullptr; + }); + + ContextTransfer::GetInstance().RegisterDynamicObjectCreator("UIAbilityContext", + [](napi_env napiEnv, std::shared_ptr context) -> napi_value { + auto abilityContext = Context::ConvertTo(context); + if (abilityContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "invalid abilityContext"); + return nullptr; + } + + auto object = EtsAbilityContextModule::GetOrCreateDynamicObject(napiEnv, abilityContext); + if (object == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "get or create object failed"); + return nullptr; + } + return object; + }); + + TAG_LOGD(AAFwkTag::CONTEXT, "Init AbilityContext kit end"); +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + TAG_LOGD(AAFwkTag::CONTEXT, "ANI_Constructor"); + if (vm == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null vm"); + return ANI_ERROR; + } + + ani_env *aniEnv = nullptr; + ani_status status = vm->GetEnv(ANI_VERSION_1, &aniEnv); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "GetEnv failed status: %{public}d", status); + return ANI_NOT_FOUND; + } + + EtsAbilityContextModuleInit(aniEnv); + *result = ANI_VERSION_1; + TAG_LOGD(AAFwkTag::CONTEXT, "ANI_Constructor finish"); + return ANI_OK; +} +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/ets/ani/ui_ability/include/ets_ui_ability.h b/frameworks/ets/ani/ui_ability/include/ets_ui_ability.h index 0d68ec8eb3970d3e6d51481a335df68a2ecab5e9..e3bbe69745244bc3009db7eff41836a314aef2fb 100644 --- a/frameworks/ets/ani/ui_ability/include/ets_ui_ability.h +++ b/frameworks/ets/ani/ui_ability/include/ets_ui_ability.h @@ -105,6 +105,9 @@ public: */ void OnAbilityResult(int requestCode, int resultCode, const Want &resultData) override; + static void CreateAndBindContext(const std::shared_ptr &abilityContext, + const std::unique_ptr& runtime); + #ifdef SUPPORT_SCREEN public: /** diff --git a/frameworks/ets/ani/ui_ability/src/ets_ui_ability.cpp b/frameworks/ets/ani/ui_ability/src/ets_ui_ability.cpp index 8548fe376903ddf821d989bf05de0fa53e794fb7..2e18feffe81cbdaf3e01c58887453942c1fcf1d0 100644 --- a/frameworks/ets/ani/ui_ability/src/ets_ui_ability.cpp +++ b/frameworks/ets/ani/ui_ability/src/ets_ui_ability.cpp @@ -33,6 +33,7 @@ #include "insight_intent_executor_info.h" #include "insight_intent_executor_mgr.h" #include "insight_intent_execute_param.h" +#include "ohos_application.h" #include "string_wrapper.h" #ifdef WINDOWS_PLATFORM @@ -95,6 +96,9 @@ EtsUIAbility::EtsUIAbility(ETSRuntime &etsRuntime) : etsRuntime_(etsRuntime) EtsUIAbility::~EtsUIAbility() { TAG_LOGI(AAFwkTag::UIABILITY, "~EtsUIAbility called"); + if (abilityContext_ != nullptr) { + abilityContext_->Unbind(); + } auto env = etsRuntime_.GetAniEnv(); if (env == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "null env"); @@ -189,6 +193,43 @@ void EtsUIAbility::UpdateAbilityObj( } } +void EtsUIAbility::CreateAndBindContext(const std::shared_ptr &abilityContext, + const std::unique_ptr& runtime) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "called"); + if (abilityContext == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext"); + return; + } + if (runtime == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime"); + return; + } + if (runtime->GetLanguage() != Runtime::Language::ETS) { + TAG_LOGE(AAFwkTag::UIABILITY, "wrong runtime language"); + return; + } + auto& etsRuntime = static_cast(*runtime); + auto env = etsRuntime.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + + int32_t screenMode = abilityContext->GetScreenMode(); + if (screenMode == AAFwk::IDLE_SCREEN_MODE) { + ani_ref contextObj = CreateEtsAbilityContext(env, abilityContext); + ani_ref* contextGlobalRef = new ani_ref; + ani_status status = ANI_ERROR; + if ((status = env->GlobalReference_Create(contextObj, contextGlobalRef)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "status : %{public}d", status); + return; + } + abilityContext->Bind(etsRuntime, contextGlobalRef); + } + // no CreateAniEmbeddableUIAbilityContext +} + void EtsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, std::shared_ptr want, const std::string &moduleName, const std::string &srcPath) { @@ -199,6 +240,7 @@ void EtsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, s return; } int32_t screenMode = want->GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::ScreenMode::IDLE_SCREEN_MODE); + abilityContext_->SetScreenMode(screenMode); CreateEtsContext(screenMode); } @@ -225,6 +267,7 @@ void EtsUIAbility::CreateEtsContext(int32_t screenMode) shellContextRef_ = std::make_shared(); shellContextRef_->aniObj = contextObj; shellContextRef_->aniRef = contextGlobalRef; + abilityContext_->Bind(etsRuntime_, &(shellContextRef_->aniRef)); } // to be done: CreateAniEmbeddableUIAbilityContext } @@ -972,3 +1015,10 @@ ETS_EXPORT extern "C" OHOS::AbilityRuntime::UIAbility *OHOS_ETS_Ability_Create( { return OHOS::AbilityRuntime::EtsUIAbility::Create(runtime); } + +ETS_EXPORT extern "C" void OHOS_CreateAndBindETSUIAbilityContext( + const std::shared_ptr &abilityContext, + const std::unique_ptr &runtime) +{ + OHOS::AbilityRuntime::EtsUIAbility::CreateAndBindContext(abilityContext, runtime); +} diff --git a/frameworks/ets/ets/application/UIAbilityContext.ets b/frameworks/ets/ets/application/UIAbilityContext.ets index 9a916d88efeaaa654f934ccb411939965d506fd0..1ae948f2ac78141b585f9190c199af199c53e37c 100644 --- a/frameworks/ets/ets/application/UIAbilityContext.ets +++ b/frameworks/ets/ets/application/UIAbilityContext.ets @@ -45,6 +45,7 @@ let unregisterToken = new object(); export default class UIAbilityContext extends Context { static { loadLibrary("context_ani"); + loadLibrary("ability_context_ani_kit.z"); } private cleaner: Cleaner | null = null; @@ -80,6 +81,24 @@ export default class UIAbilityContext extends Context { destroyRegister.unregister(unregisterToken); } + private static native nativeTransferStatic(input: ESValue, type: string): Object; + private static native nativeTransferDynamic(input: Object): ESValue; + private static contextType: string = 'UIAbilityContext'; + + static transferStatic(input: Any): Object { + let type: string = ''; + try { + type = ESValue.wrap(input).getProperty('__context_impl__').getProperty('contextType').toString(); + } catch (err) { + console.log('transferStatic err: ' + err.toString()); + } + console.log('transferStatic type: ' + type); + return UIAbilityContext.nativeTransferStatic(ESValue.wrap(input), type); + } + static transferDynamic(input: Object): Any { + return UIAbilityContext.nativeTransferDynamic(input).unwrap(); + } + private native nativeStartAbilitySync(want: Want, callback: AsyncCallbackWrapper): void; private native nativeStartAbilitySync(want: Want, options: StartOptions, callback: AsyncCallbackWrapper): void; diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index 0c4a22d62bf0c463f04c606e8d48e67cc3cbfac3..5b726de3034672d0b20c6599ef7f3c6eccc23d26 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -943,6 +943,7 @@ ohos_shared_library("ui_ability_ani") { "ipc:ipc_napi", "resource_management:global_resmgr", "runtime_core:ani", + "runtime_core:ani_helpers", "samgr:samgr_proxy", "window_manager:windowstageani_kit", ] diff --git a/frameworks/native/ability/native/ability_runtime/ets_ui_ability_instance.cpp b/frameworks/native/ability/native/ability_runtime/ets_ui_ability_instance.cpp index 50853f413a768c799a16d62f256f3d1ed34e4efb..b568256a029164ceb653bdef8a77f950aebbe4db 100644 --- a/frameworks/native/ability/native/ability_runtime/ets_ui_ability_instance.cpp +++ b/frameworks/native/ability/native/ability_runtime/ets_ui_ability_instance.cpp @@ -29,6 +29,10 @@ const char *ETS_ANI_LIBNAME = "libui_ability_ani.z.so"; const char *ETS_ANI_Create_FUNC = "OHOS_ETS_Ability_Create"; using CreateETSUIAbilityFunc = UIAbility*(*)(const std::unique_ptr&); CreateETSUIAbilityFunc g_etsCreateFunc = nullptr; +const char *CREATE_AND_BIND_ETS_UI_ABILITY_CONTEXT_FUNC = "OHOS_CreateAndBindETSUIAbilityContext"; +using CreateAndBindETSUIAbilityContextFunc = void(*)(const std::shared_ptr &abilityContext, + const std::unique_ptr &runtime); +CreateAndBindETSUIAbilityContextFunc g_createAndBindETSUIAbilityContextFunc = nullptr; } UIAbility *CreateETSUIAbility(const std::unique_ptr &runtime) @@ -50,5 +54,26 @@ UIAbility *CreateETSUIAbility(const std::unique_ptr &runtime) g_etsCreateFunc = reinterpret_cast(symbol); return g_etsCreateFunc(runtime); } + +void CreateAndBindETSUIAbilityContext(const std::shared_ptr &abilityContext, + const std::unique_ptr &runtime) +{ + if (g_createAndBindETSUIAbilityContextFunc != nullptr) { + return g_createAndBindETSUIAbilityContextFunc(abilityContext, runtime); + } + auto handle = dlopen(ETS_ANI_LIBNAME, RTLD_LAZY); + if (handle == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "dlopen failed %{public}s, %{public}s", ETS_ANI_LIBNAME, dlerror()); + return; + } + auto symbol = dlsym(handle, CREATE_AND_BIND_ETS_UI_ABILITY_CONTEXT_FUNC); + if (symbol == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "dlsym failed %{public}s, %{public}s", ETS_ANI_Create_FUNC, dlerror()); + dlclose(handle); + return; + } + g_createAndBindETSUIAbilityContextFunc = reinterpret_cast(symbol); + return g_createAndBindETSUIAbilityContextFunc(abilityContext, runtime); +} } // namespace AbilityRuntime } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp index 7809a6a7e5a02cbf518b95667887edb31f48f415..b2074cc886074f5cc651398f6c448cba5c632b20 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp @@ -45,6 +45,7 @@ #include "js_window_stage.h" #include "scene_board_judgement.h" #endif +#include "ohos_application.h" #include "napi_common_configuration.h" #include "napi_common_want.h" #include "napi_remote_object.h" @@ -150,12 +151,11 @@ napi_value OnSaveStateCallback(napi_env env, napi_callback_info info) data = nullptr; return nullptr; } -} // namespace -napi_value AttachJsAbilityContext(napi_env env, void *value, void *extValue) +napi_value AttachJsAbilityContext(napi_env env, void *value, void *) { TAG_LOGD(AAFwkTag::UIABILITY, "called"); - if (value == nullptr || extValue == nullptr) { + if (value == nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "invalid params"); return nullptr; } @@ -165,26 +165,22 @@ napi_value AttachJsAbilityContext(napi_env env, void *value, void *extValue) return nullptr; } std::shared_ptr systemModule = nullptr; - auto screenModePtr = reinterpret_cast *>(extValue)->lock(); - if (screenModePtr == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null screenModePtr"); - return nullptr; - } - if (*screenModePtr == AAFwk::IDLE_SCREEN_MODE) { + int32_t screenMode = ptr->GetScreenMode(); + if (screenMode == AAFwk::IDLE_SCREEN_MODE) { auto uiAbiObject = CreateJsAbilityContext(env, ptr); CHECK_POINTER_AND_RETURN(uiAbiObject, nullptr); systemModule = std::shared_ptr(JsRuntime::LoadSystemModuleByEngine(env, "application.AbilityContext", &uiAbiObject, 1).release()); } else { auto emUIObject = JsEmbeddableUIAbilityContext::CreateJsEmbeddableUIAbilityContext(env, - ptr, nullptr, *screenModePtr); + ptr, nullptr, screenMode); CHECK_POINTER_AND_RETURN(emUIObject, nullptr); systemModule = std::shared_ptr(JsRuntime::LoadSystemModuleByEngine(env, "application.EmbeddableUIAbilityContext", &emUIObject, 1).release()); } CHECK_POINTER_AND_RETURN(systemModule, nullptr); auto contextObj = systemModule->GetNapiValue(); - napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, value, extValue); + napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, value, nullptr); auto workContext = new (std::nothrow) std::weak_ptr(ptr); if (workContext != nullptr) { napi_status status = napi_wrap(env, contextObj, workContext, @@ -202,6 +198,30 @@ napi_value AttachJsAbilityContext(napi_env env, void *value, void *extValue) return contextObj; } +void BindContext(napi_env env, std::unique_ptr contextRef, JsRuntime& jsRuntime, + const std::shared_ptr abilityContext) +{ + CHECK_POINTER(contextRef); + napi_value contextObj = contextRef->GetNapiValue(); + if (!CheckTypeForNapiValue(env, contextObj, napi_object)) { + TAG_LOGE(AAFwkTag::UIABILITY, "get ability native object failed"); + return; + } + auto workContext = new (std::nothrow) std::weak_ptr(abilityContext); + CHECK_POINTER(workContext); + napi_coerce_to_native_binding_object( + env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, nullptr); + abilityContext->Bind(jsRuntime, contextRef.release()); + napi_wrap( + env, contextObj, workContext, + [](napi_env, void* data, void* hint) { + TAG_LOGD(AAFwkTag::UIABILITY, "finalizer for weak_ptr ability context is called"); + delete static_cast*>(data); + }, + nullptr, nullptr); +} +} // namespace + UIAbility *JsUIAbility::Create(const std::unique_ptr &runtime) { return new (std::nothrow) JsUIAbility(static_cast(*runtime)); @@ -284,6 +304,46 @@ void JsUIAbility::UpdateAbilityObj(std::shared_ptr abilityInfo, false, abilityInfo->srcEntrance); } +void JsUIAbility::CreateAndBindContext(const std::shared_ptr &abilityContext, + const std::unique_ptr& runtime) +{ + TAG_LOGD(AAFwkTag::UIABILITY, "called"); + if (abilityContext == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext"); + return; + } + if (runtime == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime"); + return; + } + if (runtime->GetLanguage() != Runtime::Language::JS) { + TAG_LOGE(AAFwkTag::UIABILITY, "wrong runtime language"); + return; + } + auto& jsRuntime = static_cast(*runtime); + HandleScope handleScope(jsRuntime); + napi_env env = jsRuntime.GetNapiEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return; + } + int32_t screenMode = abilityContext->GetScreenMode(); + + std::unique_ptr contextRef; + if (screenMode == AAFwk::IDLE_SCREEN_MODE) { + napi_value contextObj = CreateJsAbilityContext(env, abilityContext); + CHECK_POINTER(contextObj); + contextRef = JsRuntime::LoadSystemModuleByEngine(env, "application.AbilityContext", &contextObj, 1); + } else { + napi_value contextObj = + JsEmbeddableUIAbilityContext::CreateJsEmbeddableUIAbilityContext(env, abilityContext, nullptr, screenMode); + CHECK_POINTER(contextObj); + contextRef = JsRuntime::LoadSystemModuleByEngine(env, "application.EmbeddableUIAbilityContext", &contextObj, 1); + } + + BindContext(env, std::move(contextRef), jsRuntime, abilityContext); +} + void JsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, std::shared_ptr want, const std::string &moduleName, const std::string &srcPath) { @@ -303,6 +363,7 @@ void JsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, } napi_value contextObj = nullptr; int32_t screenMode = want->GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::ScreenMode::IDLE_SCREEN_MODE); + abilityContext_->SetScreenMode(screenMode); CreateJSContext(env, contextObj, screenMode); CHECK_POINTER(shellContextRef_); contextObj = shellContextRef_->GetNapiValue(); @@ -312,15 +373,9 @@ void JsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, } auto workContext = new (std::nothrow) std::weak_ptr(abilityContext_); CHECK_POINTER(workContext); - screenModePtr_ = std::make_shared(screenMode); - auto workScreenMode = new (std::nothrow) std::weak_ptr(screenModePtr_); - if (workScreenMode == nullptr) { - TAG_LOGE(AAFwkTag::UIABILITY, "null workScreenMode"); - delete workContext; - return; - } + napi_coerce_to_native_binding_object( - env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, workScreenMode); + env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, nullptr); abilityContext_->Bind(jsRuntime_, shellContextRef_.get()); napi_set_named_property(env, obj, "context", contextObj); TAG_LOGD(AAFwkTag::UIABILITY, "set ability context"); @@ -331,15 +386,12 @@ void JsUIAbility::SetAbilityContext(std::shared_ptr abilityInfo, [](napi_env, void *data, void *hint) { TAG_LOGD(AAFwkTag::UIABILITY, "finalizer for weak_ptr ability context is called"); delete static_cast *>(data); - delete static_cast *>(hint); - }, workScreenMode, nullptr); + }, nullptr, nullptr); if (status != napi_ok && workContext != nullptr) { TAG_LOGE(AAFwkTag::UIABILITY, "napi_wrap Failed: %{public}d", status); delete workContext; - delete workScreenMode; return; } - TAG_LOGI(AAFwkTag::UIABILITY, "End"); } diff --git a/frameworks/native/ability/native/ui_ability.cpp b/frameworks/native/ability/native/ui_ability.cpp index a49b15ba9191711d282645a2cb631accd5bd3735..eb03be3a04f769a48dd93b4b7f3d922522be83e3 100644 --- a/frameworks/native/ability/native/ui_ability.cpp +++ b/frameworks/native/ability/native/ui_ability.cpp @@ -20,6 +20,7 @@ #include "configuration_convertor.h" #include "display_util.h" #include "display_info.h" +#include "ets_runtime.h" #include "ets_ui_ability_instance.h" #include "event_report.h" #include "hilog_tag_wrapper.h" @@ -691,6 +692,88 @@ int32_t UIAbility::OnShare(AAFwk::WantParams &wantParams) return ERR_OK; } +void UIAbility::BindHybridContext(const std::shared_ptr application, + const std::shared_ptr record) +{ + if (application == nullptr || record == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null application or record"); + return; + } + auto appInfo = application->GetApplicationInfo(); + if (appInfo == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null appInfo"); + return; + } + if (appInfo->codeLanguage != AppExecFwk::Constants::CODE_LANGUAGE_HYBRID) { + TAG_LOGD(AAFwkTag::UIABILITY, "not hybrid app, no need to create hybrid context"); + return; + } + + auto abilityInfo = record->GetAbilityInfo(); + if (abilityInfo == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityInfo"); + return; + } + if (abilityInfo->codeLanguage == AppExecFwk::Constants::CODE_LANGUAGE_1_1) { + BindEtsContext(application, record); + } else if (abilityInfo->codeLanguage == AppExecFwk::Constants::CODE_LANGUAGE_1_2) { + BindJsContext(application, record); + } else { + TAG_LOGE(AAFwkTag::UIABILITY, "unknown codeLanguage"); + } +} + +void UIAbility::BindEtsContext(const std::shared_ptr application, + const std::shared_ptr record) +{ + if (abilityContext_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_"); + return; + } + auto& bindingObject = abilityContext_->GetBindingObject(); + if (bindingObject == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null bindingObject"); + return; + } + + auto* ptr = bindingObject->Get(); + if (ptr != nullptr) { + TAG_LOGD(AAFwkTag::UIABILITY, "ets context already binded"); + return; + } + CreateAndBindETSUIAbilityContext(abilityContext_, application->GetRuntime()); +} + +void UIAbility::BindJsContext(const std::shared_ptr application, + const std::shared_ptr record) +{ + if (abilityContext_ == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_"); + return; + } + auto& bindingObject = abilityContext_->GetBindingObject(); + if (bindingObject == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null bindingObject"); + return; + } + + auto* ptr = bindingObject->Get(); + if (ptr != nullptr) { + TAG_LOGD(AAFwkTag::UIABILITY, "ets context already binded"); + return; + } + auto &runtime = application->GetRuntime(); + if (runtime == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null runtime"); + return; + } + if (runtime->GetLanguage() == Runtime::Language::ETS) { + JsUIAbility::CreateAndBindContext(abilityContext_, static_cast(*runtime).GetJsRuntime()); + } else if (runtime->GetLanguage() == Runtime::Language::JS) { + JsUIAbility::CreateAndBindContext(abilityContext_, runtime); + } +} + bool UIAbility::CheckIsSilentForeground() const { return isSilentForeground_; diff --git a/frameworks/native/ability/native/ui_ability_impl.cpp b/frameworks/native/ability/native/ui_ability_impl.cpp index 0d2bbdd6c00966222b34023eb6243e03aa1eacdf..993a55f6fed23c559e9b52e959cc1bf0ca34e555 100644 --- a/frameworks/native/ability/native/ui_ability_impl.cpp +++ b/frameworks/native/ability/native/ui_ability_impl.cpp @@ -52,6 +52,7 @@ void UIAbilityImpl::Init(const std::shared_ptr &app new (std::nothrow) WindowLifeCycleImpl(token_, shared_from_this()))); #endif ability_->Init(record, application, handler, token); + ability_->BindHybridContext(application, record); lifecycleState_ = AAFwk::ABILITY_STATE_INITIAL; TAG_LOGD(AAFwkTag::UIABILITY, "end"); } diff --git a/frameworks/native/appkit/app/ohos_application.cpp b/frameworks/native/appkit/app/ohos_application.cpp index 86e584cb4d84e85ff4e7aff21dc7ccbdb616a2f2..657f61beff425bb0ba1d5a46e680987c1b50ac8c 100644 --- a/frameworks/native/appkit/app/ohos_application.cpp +++ b/frameworks/native/appkit/app/ohos_application.cpp @@ -720,11 +720,6 @@ std::shared_ptr OHOSApplication::GetAppContext() const return abilityRuntimeContext_; } -const std::unique_ptr &OHOSApplication::GetRuntime() const -{ - return runtime_; -} - const std::unique_ptr &OHOSApplication::GetSpecifiedRuntime( const std::string &arkTSMode) const { diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context.h b/interfaces/kits/native/ability/ability_runtime/ability_context.h index e5a2eb076d08e79c2a9b0f33e2303879f8045ea0..3e31bf260bbfc7e97518ffa8435671a76877c2ab 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context.h @@ -394,6 +394,15 @@ public: virtual void SetHookOff(bool hookOff) = 0; virtual ErrCode RevokeDelegator() = 0; virtual ErrCode SetOnNewWantSkipScenarios(int32_t scenarios) = 0; + void SetScreenMode(int32_t screenMode) + { + screenMode_ = screenMode; + } + + int32_t GetScreenMode() const + { + return screenMode_; + } virtual std::shared_ptr GetWant() = 0; @@ -487,7 +496,7 @@ public: */ virtual void OnRequestFailure(const std::string &requestId, const AppExecFwk::ElementName &element, const std::string &message, int32_t resultCode = 0) = 0; - + virtual ErrCode AddCompletionHandlerForAtomicService(const std::string &requestId, OnAtomicRequestSuccess onRequestSucc, OnAtomicRequestFailure onRequestFail, const std::string &appId) = 0; @@ -496,6 +505,9 @@ protected: { return contextTypeId == CONTEXT_TYPE_ID || Context::IsContext(contextTypeId); } + +private: + int32_t screenMode_ = AAFwk::ScreenMode::IDLE_SCREEN_MODE; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability_instance.h b/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability_instance.h index 1a34dc64889a19f9ebb5b802851c11b5083b8fa2..c59016c6932e0f44fe68f3b2eef7858305d0db62 100644 --- a/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability_instance.h +++ b/interfaces/kits/native/ability/native/ability_runtime/ets_ui_ability_instance.h @@ -21,9 +21,12 @@ namespace OHOS { namespace AbilityRuntime { class UIAbility; +class AbilityContext; class Runtime; UIAbility *CreateETSUIAbility(const std::unique_ptr &runtime); +void CreateAndBindETSUIAbilityContext(const std::shared_ptr &abilityContext, + const std::unique_ptr &runtime); } // namespace AbilityRuntime } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_ETS_UI_ABILITY_INSTANCE_H \ No newline at end of file diff --git a/interfaces/kits/native/ability/native/ability_runtime/js_ui_ability.h b/interfaces/kits/native/ability/native/ability_runtime/js_ui_ability.h index bbedbecb7023ff9b2842f890e73a7c3238709116..79c3d67bb04e953bb153fbc582f68a7a93be2225 100644 --- a/interfaces/kits/native/ability/native/ability_runtime/js_ui_ability.h +++ b/interfaces/kits/native/ability/native/ability_runtime/js_ui_ability.h @@ -72,6 +72,9 @@ public: const std::shared_ptr application, std::shared_ptr &handler, const sptr &token) override; + static void CreateAndBindContext(const std::shared_ptr &abilityContext, + const std::unique_ptr& runtime); + /** * @brief OnStart,Start JsUIability * @param want Indicates the {@link Want} structure containing startup information about the ability @@ -431,7 +434,6 @@ private: JsRuntime &jsRuntime_; std::shared_ptr shellContextRef_; std::shared_ptr jsAbilityObj_; - std::shared_ptr screenModePtr_; sptr remoteCallee_; bool reusingWindow_ = false; }; diff --git a/interfaces/kits/native/ability/native/ui_ability.h b/interfaces/kits/native/ability/native/ui_ability.h index 4478ee8141b8c0f6f404b7572c0eb746855b2a38..00e9b4ba52e3dedf435d2d5c500f7ae5e6c37766 100644 --- a/interfaces/kits/native/ability/native/ui_ability.h +++ b/interfaces/kits/native/ability/native/ui_ability.h @@ -338,6 +338,9 @@ public: */ virtual int32_t OnShare(AAFwk::WantParams &wantParams); + void BindHybridContext(const std::shared_ptr application, + const std::shared_ptr record); + bool CheckIsSilentForeground() const; void SetIsSilentForeground(bool isSilentForeground); @@ -368,6 +371,10 @@ private: void SetLaunchParam(const AAFwk::LaunchParam &launchParam); void InitConfigurationProperties(const AppExecFwk::Configuration &changeConfiguration, ResourceConfigHelper &resourceConfig); + void BindEtsContext(const std::shared_ptr application, + const std::shared_ptr record); + void BindJsContext(const std::shared_ptr application, + const std::shared_ptr record); std::shared_ptr continuationHandler_ = nullptr; std::shared_ptr continuationManager_ = nullptr; diff --git a/interfaces/kits/native/appkit/ability_runtime/context/bindable.h b/interfaces/kits/native/appkit/ability_runtime/context/bindable.h index 354431963ed50721a4f30f79ed6d1e34330091b1..8fb38e80cdc628dd40b01c2a7766a193425bfaf8 100644 --- a/interfaces/kits/native/appkit/ability_runtime/context/bindable.h +++ b/interfaces/kits/native/appkit/ability_runtime/context/bindable.h @@ -17,38 +17,57 @@ #define OHOS_ABILITY_RUNTIME_BINDABLE_H #include +#include +class NativeReference; +typedef class __ani_ref *ani_ref; namespace OHOS { namespace AbilityRuntime { class Runtime; class BindingObject final { public: - template - BindingObject(Runtime& runtime, T* ptr) : runtime_(runtime), object_(ptr, SimpleRelease) {} + BindingObject() = default; ~BindingObject() = default; template - T* Get() + void Bind(Runtime& runtime, T* object) { - return static_cast(object_.get()); + static_assert(IsValidType(), "T must be ani_ref or NativeReference"); + const std::string typeName = GetTypeString(); + std::lock_guard guard(objectsMutex_); + std::unique_ptr obj(object, SimpleRelease); + objects_.emplace(typeName, std::move(obj)); } - void Reset() + template + T* Get() { - object_.reset(); + const std::string typeName = GetTypeString(); + std::lock_guard guard(objectsMutex_); + const auto& iter = objects_.find(typeName); + if (iter == objects_.end()) { + return nullptr; + } + return static_cast(iter->second.get()); } void Unbind() { - if (object_) { - object_.release(); - } + // Consistency with previous behavior + Unbind(); } - Runtime& GetRuntime() + template + void Unbind() { - return runtime_; + const std::string typeName = GetTypeString(); + std::lock_guard guard(objectsMutex_); + const auto& iter = objects_.find(typeName); + if (iter == objects_.end()) { + return; + } + iter->second.release(); } BindingObject(const BindingObject&) = delete; @@ -63,8 +82,27 @@ private: delete static_cast(ptr); } - Runtime& runtime_; - std::unique_ptr object_; + template + static constexpr bool IsValidType() + { + if (std::is_same_v || std::is_same_v) { + return true; + } + return false; + } + + template + static std::string GetTypeString() + { + if (std::is_same_v) { + return "ani_ref"; + } else { + return "NativeReference"; + } + } + + std::map> objects_; + std::mutex objectsMutex_; }; class Bindable { @@ -74,16 +112,26 @@ public: template void Bind(Runtime& runtime, T* object) { - object_ = std::make_unique(runtime, object); + if (object_) { + object_->Bind(runtime, object); + } } - void Unbind() + void Unbind() const { if (object_) { object_->Unbind(); } } + template + void Unbind() const + { + if (object_) { + object_->Unbind(); + } + } + const std::unique_ptr& GetBindingObject() const { return object_; @@ -93,8 +141,8 @@ protected: Bindable() = default; private: - std::unique_ptr object_; + std::unique_ptr object_ = std::make_unique(); }; -} // namespace AbilityRuntime -} // namespace OHOS -#endif // OHOS_ABILITY_RUNTIME_BINDABLE_H +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_BINDABLE_H diff --git a/interfaces/kits/native/appkit/app/ohos_application.h b/interfaces/kits/native/appkit/app/ohos_application.h index 6099ca7a8527a9c27c3ce787a3c2656f78a462ce..2b1844516d7cde7dbb37f997f3d44b6946bbc5d6 100644 --- a/interfaces/kits/native/appkit/app/ohos_application.h +++ b/interfaces/kits/native/appkit/app/ohos_application.h @@ -174,7 +174,10 @@ public: * * @param runtime */ - const std::unique_ptr &GetRuntime() const; + const std::unique_ptr &GetRuntime() const + { + return runtime_; + } /** * @brief return the specified runtime