diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index c1c6b1870d8287317a6d1e48710c392525c89064..c275c7ed5af3a6a8673115814327309e7a6a7b3c 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -16,6 +16,7 @@ import("//foundation/ability/ability_runtime/ability_runtime.gni") group("ani_packages") { deps = [ + "${ability_runtime_path}/frameworks/ets/ani/native_constructor:context_ani", "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] } diff --git a/frameworks/ets/ani/native_constructor/BUILD.gn b/frameworks/ets/ani/native_constructor/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..546c6ab0408918cabfd4b311f2005ba04c486b7c --- /dev/null +++ b/frameworks/ets/ani/native_constructor/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +ohos_shared_library("context_ani") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + sources = [ + "context_native_constructor.cpp", + ] + + include_dirs = [ + "${ability_runtime_services_path}/common/include", + ] + + external_deps = [ + "hilog:libhilog", + "runtime_core:ani", + ] + subsystem_name = "ability" + part_name = "ability_runtime" + output_extension = "so" +} \ No newline at end of file diff --git a/frameworks/ets/ani/native_constructor/context_native_constructor.cpp b/frameworks/ets/ani/native_constructor/context_native_constructor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79964f5e4d9fee8b41d3f43dc6b145a62b75229c --- /dev/null +++ b/frameworks/ets/ani/native_constructor/context_native_constructor.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +void ContextConstructor() +{ +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (vm == nullptr || result == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Illegal VM or result"); + return ANI_ERROR; + } + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Unsupported ANI_VERSION_1"); + return ANI_ERROR; + } + ani_class contextClass; + static const char *contextClassName = "Lapplication/Context/Context;"; + if (ANI_OK != env->FindClass(contextClassName, &contextClass)) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Not found class %{public}s.", contextClassName); + return ANI_NOT_FOUND; + } + std::array classMethods_context = { + ani_native_function {"", ":V", reinterpret_cast(ContextConstructor)}, + }; + if (ANI_OK != env->Class_BindNativeMethods(contextClass, classMethods_context.data(), + classMethods_context.size())) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Cannot bind native ctor to class %{public}s.", contextClassName); + return ANI_ERROR; + }; + *result = ANI_VERSION_1; + return ANI_OK; +} +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index 9f07fdb1852acb6b8a7f2fdd8836c92349d787e4..7f1e14120f120ef7fdea30fa88b61ffd81e4ffa8 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -31,6 +31,39 @@ ohos_prebuilt_etc("ability_runtime_base_context_abc_etc") { deps = [ ":ability_runtime_base_context_abc" ] } +generate_static_abc("ability_runtime_application_context_abc") { + base_url = "./" + files = [ "./application/ApplicationContext.ets" ] + + is_boot_abc = "True" + device_dst_file = + "/system/framework/ability_runtime_application_context_abc.abc" +} + +ohos_prebuilt_etc("ability_runtime_application_context_abc_etc") { + source = "$target_out_dir/ability_runtime_application_context_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_runtime_application_context_abc" ] +} + +generate_static_abc("ability_runtime_context_abc") { + base_url = "./" + files = [ "./application/Context.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_runtime_context_abc.abc" +} + +ohos_prebuilt_etc("ability_runtime_context_abc_etc") { + source = "$target_out_dir/ability_runtime_context_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_runtime_context_abc" ] +} + generate_static_abc("ability_runtime_ability_utils_abc") { base_url = "./" files = [ "./utils/AbilityUtils.ets" ] @@ -116,6 +149,8 @@ group("ets_packages") { ":ability_runtime_ability_constant_abc_etc", ":ability_runtime_ability_utils_abc_etc", ":ability_runtime_base_context_abc_etc", + ":ability_runtime_application_context_abc_etc", + ":ability_runtime_context_abc_etc", ":ability_runtime_start_options_abc_etc", ":ability_runtime_want_abc_etc", ":ability_runtime_want_constant_abc_etc", diff --git a/frameworks/ets/ets/application/ApplicationContext.ets b/frameworks/ets/ets/application/ApplicationContext.ets new file mode 100644 index 0000000000000000000000000000000000000000..b572cc2880353a53d2ffc03e3e23707c88df20dc --- /dev/null +++ b/frameworks/ets/ets/application/ApplicationContext.ets @@ -0,0 +1,24 @@ +/* + * 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 Context from 'application.Context' + +export default class ApplicationContext extends Context { + public native setSupportedProcessCacheSync(isSupported : boolean):void; + + setSupportedProcessCache(isSupported : boolean):void { + this.setSupportedProcessCacheSync(isSupported); + } +} \ No newline at end of file diff --git a/frameworks/ets/ets/application/Context.ets b/frameworks/ets/ets/application/Context.ets new file mode 100644 index 0000000000000000000000000000000000000000..ea7786a0d9171d0e5ac17f31759781cce02f55f1 --- /dev/null +++ b/frameworks/ets/ets/application/Context.ets @@ -0,0 +1,42 @@ +/* + * 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 BaseContext from 'application.BaseContext' +import ApplicationContext from 'application.ApplicationContext' +import contextConstant from '@ohos.app.ability.contextConstant' +import { ApplicationInfo } from 'bundleManager.ApplicationInfo' +import resmgr from '@ohos.resourceManager' + +export class Context extends BaseContext { + static { + loadLibrary("context_ani"); + } + area: contextConstant.AreaMode = contextConstant.AreaMode.EL1; + filesDir: string = ""; + tempDir: string = ""; + applicationInfo: ApplicationInfo; + resourceManager: resmgr.ResourceManager; + native constructor(); + constructor(applicationInfo: ApplicationInfo, resourceManager: resmgr.ResourceManager) { + super(); + this.applicationInfo = applicationInfo; + this.resourceManager = resourceManager; + } + public native getApplicationContextSync(): ApplicationContext; + + getApplicationContext(): ApplicationContext { + return this.getApplicationContextSync(); + } +} \ No newline at end of file diff --git a/frameworks/native/appkit/BUILD.gn b/frameworks/native/appkit/BUILD.gn index 11863d7b8bd13c71b1da20dcdbd81cfc737d3765..7c458ab82d95f3577e7e57ed49c78a9510da3d8b 100644 --- a/frameworks/native/appkit/BUILD.gn +++ b/frameworks/native/appkit/BUILD.gn @@ -397,6 +397,7 @@ ohos_shared_library("app_context_utils") { branch_protector_ret = "pac_ret" include_dirs = [ + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", "${ability_runtime_napi_path}/ability_auto_startup_callback", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/app", @@ -407,6 +408,7 @@ ohos_shared_library("app_context_utils") { public_configs = [ ":appkit_public_config" ] sources = [ + "ability_runtime/context/ets_context_utils.cpp", "ability_runtime/context/js_application_context_utils.cpp", "ability_runtime/context/js_context_utils.cpp", "ability_runtime/context/js_resource_manager_utils.cpp", @@ -426,6 +428,7 @@ ohos_shared_library("app_context_utils") { "${ability_runtime_native_path}/ability/native:auto_startup_callback", "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:application_context_manager", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] external_deps = [ @@ -434,6 +437,7 @@ ohos_shared_library("app_context_utils") { "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", + "bundle_framework:bms_ani_common", "c_utils:utils", "hilog:libhilog", "hitrace:hitrace_meter", @@ -443,6 +447,8 @@ ohos_shared_library("app_context_utils") { "napi:ace_napi", "resource_management:global_resmgr", "resource_management:resmgr_napi_core", + "resource_management:resourceManager_ani", + "runtime_core:ani", ] public_external_deps = [ "ability_base:configuration" ] if (ability_runtime_graphics) { @@ -601,6 +607,12 @@ ohos_shared_library("appkit_manager_helper") { ohos_shared_library("application_context_manager") { branch_protector_ret = "pac_ret" + include_dirs = [ + "${ability_runtime_path}/interfaces/inner_api/runtime/include", + "${ability_runtime_path}/interfaces/kits/native/ability/native", + "${ability_runtime_path}/ets_environment/interfaces/inner_api", + ] + sources = [ "${ability_runtime_native_path}/appkit/ability_runtime/context/application_context_manager.cpp" ] cflags = [] @@ -609,8 +621,10 @@ ohos_shared_library("application_context_manager") { } external_deps = [ + "ets_runtime:libark_jsruntime", "hilog:libhilog", "napi:ace_napi", + "runtime_core:ani", ] public_configs = [ ":application_context_manager_config" ] diff --git a/frameworks/native/appkit/ability_runtime/context/application_context_manager.cpp b/frameworks/native/appkit/ability_runtime/context/application_context_manager.cpp index b46e080eacf629b64309cb536ca732c00bc35826..073170d29b5d7502b06cbb61679d85ed2a9c1831 100644 --- a/frameworks/native/appkit/ability_runtime/context/application_context_manager.cpp +++ b/frameworks/native/appkit/ability_runtime/context/application_context_manager.cpp @@ -88,5 +88,38 @@ void ApplicationContextManager::RemoveGlobalObject(napi_env env) applicationContextMap_.erase(env); } } + +void ApplicationContextManager::AddEtsGlobalObject(ani_env* env, + std::shared_ptr applicationContextObj) +{ + std::lock_guard lock(etsApplicationContextMutex_); + auto iter = etsApplicationContextMap_.find(env); + if (iter == etsApplicationContextMap_.end()) { + etsApplicationContextMap_[env] = applicationContextObj; + return; + } + if (iter->second != nullptr) { + iter->second.reset(); + iter->second = nullptr; + } + iter->second = applicationContextObj; +} + +std::shared_ptr ApplicationContextManager::GetEtsGlobalObject(ani_env* env) +{ + std::lock_guard lock(etsApplicationContextMutex_); + return etsApplicationContextMap_[env]; +} + +void ApplicationContextManager::RemoveEtsGlobalObject(ani_env* env) +{ + std::lock_guard lock(etsApplicationContextMutex_); + auto iter = etsApplicationContextMap_.find(env); + if (iter != etsApplicationContextMap_.end() && iter->second != nullptr) { + iter->second.reset(); + iter->second = nullptr; + etsApplicationContextMap_.erase(env); + } +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/appkit/ability_runtime/context/ets_context_utils.cpp b/frameworks/native/appkit/ability_runtime/context/ets_context_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b072f5e99b224e0ae4048756b210bdd5769e352 --- /dev/null +++ b/frameworks/native/appkit/ability_runtime/context/ets_context_utils.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ets_context_utils.h" + +#include "ani_common_util.h" +#include "ani_enum_convert.h" +#include "application_context.h" +#include "application_context_manager.h" +#include "common_fun_ani.h" +#include "hilog_tag_wrapper.h" +#include "resourceManager.h" +#include "ets_error_utils.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace ContextUtil { +namespace { + constexpr const char* CONTEXT_CLASS_NAME = "Lapplication/Context/Context;"; +} +void BindApplicationInfo(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context) +{ + if (aniEnv == nullptr || context == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null aniEnv or null context"); + } + ani_field applicationInfoField; + if (ANI_OK != aniEnv->Class_FindField(contextClass, "applicationInfo", &applicationInfoField)) { + TAG_LOGE(AAFwkTag::APPKIT, "find applicationInfo failed"); + return; + } + auto appInfo = context->GetApplicationInfo(); + ani_object appInfoObj = AppExecFwk::CommonFunAni::ConvertApplicationInfo(aniEnv, *appInfo); + if (aniEnv->Object_SetField_Ref(contextObj, applicationInfoField, + reinterpret_cast(appInfoObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Ref failed"); + return; + } +} + +void BindResourceManager(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context) +{ + if (aniEnv == nullptr || context == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null aniEnv or null context"); + } + ani_field resourceManagerField; + if (ANI_OK != aniEnv->Class_FindField(contextClass, "resourceManager", &resourceManagerField)) { + TAG_LOGE(AAFwkTag::APPKIT, "find resourceManager failed"); + return; + } + auto resourceManager = context->GetResourceManager(); + ani_object resourceMgrObj = Global::Resource::ResMgrAddon::CreateResMgr(aniEnv, "", resourceManager, context); + if (aniEnv->Object_SetField_Ref(contextObj, resourceManagerField, + reinterpret_cast(resourceMgrObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Ref failed"); + return; + } +} + +void BindParentProperty(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context) +{ + if (aniEnv == nullptr || context == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null aniEnv or null context"); + } + BindApplicationInfo(aniEnv, contextClass, contextObj, context); + BindResourceManager(aniEnv, contextClass, contextObj, context); + + ani_field areaField; + if (ANI_OK != aniEnv->Class_FindField(contextClass, "area", &areaField)) { + TAG_LOGE(AAFwkTag::APPKIT, "find area failed"); + return; + } + auto area = context->GetArea(); + ani_enum_item areaModeItem {}; + OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts( + aniEnv, "L@ohos/app/ability/contextConstant/contextConstant/AreaMode;", area, areaModeItem); + if (aniEnv->Object_SetField_Ref(contextObj, areaField, (ani_ref)areaModeItem) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Int failed"); + return; + } + ani_field filesDirField; + if (ANI_OK != aniEnv->Class_FindField(contextClass, "filesDir", &filesDirField)) { + TAG_LOGE(AAFwkTag::APPKIT, "find filesDir failed"); + return; + } + auto filesDir = context->GetFilesDir(); + ani_string filesDir_string{}; + aniEnv->String_NewUTF8(filesDir.c_str(), filesDir.size(), &filesDir_string); + if (aniEnv->Object_SetField_Ref(contextObj, filesDirField, reinterpret_cast(filesDir_string)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Ref failed"); + return; + } + ani_field tempDirField; + if (ANI_OK != aniEnv->Class_FindField(contextClass, "tempDir", &tempDirField)) { + TAG_LOGE(AAFwkTag::APPKIT, "find find tempDir failed"); + return; + } + auto tempDir = context->GetTempDir(); + ani_string tempDir_string{}; + aniEnv->String_NewUTF8(tempDir.c_str(), tempDir.size(), &tempDir_string); + if (aniEnv->Object_SetField_Ref(contextObj, tempDirField, reinterpret_cast(tempDir_string)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Ref failed"); + return; + } +} + +void BindNativeFunction(ani_env* aniEnv) +{ + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "env is null"); + return; + } + ani_class contextCls = nullptr; + if (aniEnv->FindClass(CONTEXT_CLASS_NAME, &contextCls) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "FindClass Context failed"); + return; + } + std::array contextFunctions = { + ani_native_function {"getApplicationContextSync", ":Lapplication/ApplicationContext/ApplicationContext;", + reinterpret_cast(AbilityRuntime::ContextUtil::GetApplicationContextSync)} + }; + ani_status status = aniEnv->Class_BindNativeMethods(contextCls, contextFunctions.data(), + contextFunctions.size()); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_BindNativeMethods failed status: %{public}d", status); + } +} + +void CreateEtsBaseContext(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context) +{ + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null aniEnv"); + } + BindParentProperty(aniEnv, contextClass, contextObj, context); + BindNativeFunction(aniEnv); +} + +std::shared_ptr GetBaseContext(ani_env *env, ani_object aniObj) +{ + ani_status status = ANI_ERROR; + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "null env"); + return nullptr; + } + ani_class cls {}; + if ((status = env->FindClass(CONTEXT_CLASS_NAME, &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "status: %{public}d", status); + return nullptr; + } + ani_field contextField = nullptr; + if ((status = env->Class_FindField(cls, "nativeContext", &contextField)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "status: %{public}d", status); + return nullptr; + } + ani_long nativeContextLong; + if ((status = env->Object_GetField_Long(aniObj, contextField, &nativeContextLong)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UIABILITY, "status: %{public}d", status); + return nullptr; + } + auto weakContext = reinterpret_cast*>(nativeContextLong); + return weakContext != nullptr ? weakContext->lock() : nullptr; +} + +ani_object GetApplicationContext(ani_env* env, const std::shared_ptr applicationContext) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env"); + } + ani_class applicationContextCls = nullptr; + if (env->FindClass("Lapplication/ApplicationContext/ApplicationContext;", &applicationContextCls) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "FindClass ApplicationContext failed"); + return {}; + } + ani_method contextCtorMethod = nullptr; + if (env->Class_FindMethod(applicationContextCls, "", ":V", &contextCtorMethod) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_FindMethod ctor failed"); + return {}; + } + ani_object applicationContextObject = nullptr; + if (env->Object_New(applicationContextCls, contextCtorMethod, &applicationContextObject) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_New failed"); + return {}; + } + ani_field contextField; + if (env->Class_FindField(applicationContextCls, "nativeContext", &contextField) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_FindField failed"); + return {}; + } + auto workContext = new (std::nothrow) std::weak_ptr(applicationContext); + if (workContext == nullptr) { + TAG_LOGE(AAFwkTag::UIABILITY, "workContext nullptr"); + return {}; + } + ani_long nativeContextLong = (ani_long)workContext; + if (env->Object_SetField_Long(applicationContextObject, contextField, nativeContextLong) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Long failed"); + return {}; + } + auto etsReference = std::make_shared(); + etsReference->aniObj = applicationContextObject; + AbilityRuntime::ApplicationContextManager::GetApplicationContextManager().AddEtsGlobalObject(env, etsReference); + applicationContext->SetApplicationInfoUpdateFlag(false); + return applicationContextObject; +} + +ani_object GetApplicationContextSync([[maybe_unused]]ani_env *env, [[maybe_unused]]ani_object aniObj) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env"); + } + auto context = GetBaseContext(env, aniObj); + if (!context) { + TAG_LOGW(AAFwkTag::APPKIT, "null context"); + ThrowEtsError(env, (int32_t)AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return {}; + } + auto applicationContext = context->GetApplicationContext(); + if (applicationContext == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext"); + ThrowEtsError(env, (int32_t)AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return {}; + } + if (!applicationContext->GetApplicationInfoUpdateFlag()) { + auto appContextObj = ApplicationContextManager::GetApplicationContextManager().GetEtsGlobalObject(env); + if (appContextObj != nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "appContextObj is not nullptr"); + return appContextObj->aniObj; + } + } + return GetApplicationContext(env, applicationContext); +} +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/native/appkit/ability_runtime/context/application_context_manager.h b/interfaces/kits/native/appkit/ability_runtime/context/application_context_manager.h index 4ce60e5b7036de6eb21576b6cbaf904165902683..bb307cb09267d498d5ddb67ce1eefdbe290b7a3c 100644 --- a/interfaces/kits/native/appkit/ability_runtime/context/application_context_manager.h +++ b/interfaces/kits/native/appkit/ability_runtime/context/application_context_manager.h @@ -17,6 +17,7 @@ #define OHOS_ABILITY_RUNTIME_APPLICATION_CONTEXT_MANAGER_H #include "native_engine/native_engine.h" +#include "ets_runtime.h" #include #include @@ -42,13 +43,21 @@ public: void RemoveGlobalObject(napi_env env); + void AddEtsGlobalObject(ani_env* env, std::shared_ptr applicationContextObj); + + std::shared_ptr GetEtsGlobalObject(ani_env* env); + + void RemoveEtsGlobalObject(ani_env* env); + private: ApplicationContextManager(); ~ApplicationContextManager(); std::unordered_map> applicationContextMap_; + std::unordered_map> etsApplicationContextMap_; std::mutex applicationContextMutex_; + std::mutex etsApplicationContextMutex_; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/appkit/ability_runtime/context/ets_context_utils.h b/interfaces/kits/native/appkit/ability_runtime/context/ets_context_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..a80ebcc62727c6c7444036ca340be902061a7796 --- /dev/null +++ b/interfaces/kits/native/appkit/ability_runtime/context/ets_context_utils.h @@ -0,0 +1,39 @@ +/* + * 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_CONTEXT_UTILS_H +#define OHOS_ABILITY_RUNTIME_ETS_CONTEXT_UTILS_H + +#include "ets_runtime.h" +#include "context.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace ContextUtil { + +void BindApplicationInfo(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context); + +void BindResourceManager(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context); + +void CreateEtsBaseContext(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context); + +ani_object GetApplicationContextSync([[maybe_unused]]ani_env *env, [[maybe_unused]]ani_object aniObj); +} +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_CONTEXT_UTILS_H \ No newline at end of file