From 8c4acf7660a94079764f099ff51daf16073ad3ea Mon Sep 17 00:00:00 2001 From: zhangzezhong Date: Wed, 28 May 2025 14:28:22 +0800 Subject: [PATCH] =?UTF-8?q?BaseContext,Context,ApplcationContext0411?= =?UTF-8?q?=E5=9B=9E=E5=90=88master?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzezhong --- bundle.json | 10 + frameworks/ets/BUILD.gn | 73 +++++++ .../ets/application/ApplicationContext.ets | 24 +++ frameworks/ets/application/BaseContext.ets | 19 ++ frameworks/ets/application/Context.ets | 33 +++ frameworks/native/appkit/BUILD.gn | 1 + .../context/application_context_manager.cpp | 33 +++ .../context/ets_context_utils.cpp | 202 ++++++++++++++++++ frameworks/native/appkit/app/main_thread.cpp | 4 + .../native/appkit/app/ohos_application.cpp | 115 ++++++++++ .../inner_api/ani_base_context/BUILD.gn | 53 +++++ .../include/ani_base_context.h | 55 +++++ .../ani_base_context/src/ani_base_context.cpp | 54 +++++ .../context/application_context_manager.h | 9 + .../context/ets_context_utils.h | 46 ++++ .../kits/native/appkit/app/ohos_application.h | 4 + 16 files changed, 735 insertions(+) create mode 100644 frameworks/ets/BUILD.gn create mode 100644 frameworks/ets/application/ApplicationContext.ets create mode 100644 frameworks/ets/application/BaseContext.ets create mode 100644 frameworks/ets/application/Context.ets create mode 100644 frameworks/native/appkit/ability_runtime/context/ets_context_utils.cpp create mode 100644 interfaces/inner_api/ani_base_context/BUILD.gn create mode 100644 interfaces/inner_api/ani_base_context/include/ani_base_context.h create mode 100644 interfaces/inner_api/ani_base_context/src/ani_base_context.cpp create mode 100644 interfaces/kits/native/appkit/ability_runtime/context/ets_context_utils.h diff --git a/bundle.json b/bundle.json index 38fc7eb4e9a..bb4504160ca 100644 --- a/bundle.json +++ b/bundle.json @@ -129,6 +129,7 @@ "//foundation/ability/ability_runtime/frameworks/c/ability_runtime:ability_runtime", "//foundation/ability/ability_runtime/frameworks/cj:cj_ability_packages", "//foundation/ability/ability_runtime/frameworks/js/napi:napi_packages", + "//foundation/ability/ability_runtime/frameworks/ets/ets:ets_packages", "//foundation/ability/ability_runtime/cj_environment/frameworks/cj_environment:cj_environment", "//foundation/ability/ability_runtime/js_environment/frameworks/js_environment:js_environment", "//foundation/ability/ability_runtime/services/abilitymgr/etc:appfwk_etc", @@ -277,6 +278,15 @@ }, "name": "//foundation/ability/ability_runtime/interfaces/inner_api/napi_base_context:napi_base_context" }, + { + "header": { + "header_base": "//foundation/ability/ability_runtime/interfaces/inner_api/ani_base_context/include", + "header_files": [ + "ani_base_context.h" + ] + }, + "name": "//foundation/ability/ability_runtime/interfaces/inner_api/ani_base_context:ani_base_context" + }, { "header": { "header_base": "//foundation/ability/ability_runtime/frameworks/js/napi/inner/napi_common", diff --git a/frameworks/ets/BUILD.gn b/frameworks/ets/BUILD.gn new file mode 100644 index 00000000000..f1019627b21 --- /dev/null +++ b/frameworks/ets/BUILD.gn @@ -0,0 +1,73 @@ +# 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") + +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_base_context_abc") { + base_url = "./" + files = [ "./application/BaseContext.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_runtime_base_context_abc.abc" +} + +ohos_prebuilt_etc("ability_runtime_base_context_abc_etc") { + source = "$target_out_dir/ability_runtime_base_context_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + 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" ] +} + +group("ets_packages") { + deps = [ + ":ability_runtime_application_context_abc_etc", + ":ability_runtime_base_context_abc_etc", + ":ability_runtime_context_abc_etc", + ] +} diff --git a/frameworks/ets/application/ApplicationContext.ets b/frameworks/ets/application/ApplicationContext.ets new file mode 100644 index 00000000000..3ab5c0b2eb1 --- /dev/null +++ b/frameworks/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/application/BaseContext.ets b/frameworks/ets/application/BaseContext.ets new file mode 100644 index 00000000000..16d5fd10eab --- /dev/null +++ b/frameworks/ets/application/BaseContext.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default class BaseContext { + public nativeContext : long = 0; + public stageMode: boolean = true; +} \ No newline at end of file diff --git a/frameworks/ets/application/Context.ets b/frameworks/ets/application/Context.ets new file mode 100644 index 00000000000..b09d761333f --- /dev/null +++ b/frameworks/ets/application/Context.ets @@ -0,0 +1,33 @@ +/* + * 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 { + area: contextConstant.AreaMode = contextConstant.AreaMode.EL1; + filesDir: string = ""; + tempDir: string = ""; + applicationInfo: ApplicationInfo; + resourceManager: resmgr.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 a04288c9bec..0d53a59f47c 100644 --- a/frameworks/native/appkit/BUILD.gn +++ b/frameworks/native/appkit/BUILD.gn @@ -397,6 +397,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", 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 b46e080eacf..073170d29b5 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 00000000000..12497dbbc2c --- /dev/null +++ b/frameworks/native/appkit/ability_runtime/context/ets_context_utils.cpp @@ -0,0 +1,202 @@ +/* + * 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 { +std::weak_ptr 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 CreateEtsBaseContext(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, + std::shared_ptr context) +{ + context_ = context; + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null aniEnv"); + } + BindParentProperty(aniEnv, contextClass, contextObj, context); +} + +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 = context_.lock(); + 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 diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index 6f4c1ae42ae..85d1d2bd6c7 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -1672,6 +1672,10 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con appThread->ScheduleProcessSecurityExit(); }; applicationContext->RegisterProcessSecurityExit(callback); + if (appInfo.codeLanguage == AbilityRuntime::APPLICAITON_CODE_LANGUAGE_ARKTS_1_2) { + application_->InitAniApplicationContext(); + application_->InitAniContext(); + } application_->SetRuntime(std::move(runtime)); diff --git a/frameworks/native/appkit/app/ohos_application.cpp b/frameworks/native/appkit/app/ohos_application.cpp index 424c34c1270..5a2ea5cbe5f 100644 --- a/frameworks/native/appkit/app/ohos_application.cpp +++ b/frameworks/native/appkit/app/ohos_application.cpp @@ -46,11 +46,16 @@ #include "display_manager.h" #include "window.h" #endif +#include "ets_context_utils.h" +#include "ets_runtime.h" +#include "ets_error_utils.h" namespace OHOS { namespace AppExecFwk { namespace { constexpr const char* PERSIST_DARKMODE_KEY = "persist.ace.darkmode"; + constexpr const char* ETS_APPLICATION_CONTEXT_CLASS_NAME = "Lapplication/ApplicationContext/ApplicationContext;"; + constexpr const char* ETS_CONTEXT_CLASS_NAME = "Lapplication/Context/Context;"; } REGISTER_APPLICATION(OHOSApplication, OHOSApplication) constexpr int32_t APP_ENVIRONMENT_OVERWRITE = 1; @@ -208,6 +213,116 @@ void OHOSApplication::SetApplicationContext( #endif } +static void SetSupportedProcessCacheSync([[maybe_unused]]ani_env *env, [[maybe_unused]]ani_object aniObj, + ani_boolean value) +{ + TAG_LOGD(AAFwkTag::APPKIT, "SetSupportedProcessCacheSync Call"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "env is null"); + return; + } + ani_class applicationContextCls = nullptr; + if (env->FindClass(ETS_APPLICATION_CONTEXT_CLASS_NAME, &applicationContextCls) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "FindClass ApplicationContext failed"); + AbilityRuntime::ThrowEtsInvalidParamError(env, "FindClass failed"); + return; + } + ani_field contextField; + if (env->Class_FindField(applicationContextCls, "nativeContext", &contextField) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_FindField failed"); + AbilityRuntime::ThrowEtsInvalidParamError(env, "Class_FindField failed"); + return; + } + ani_long nativeContextLong; + if (env->Object_GetField_Long(aniObj, contextField, &nativeContextLong) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_GetField_Long failed"); + AbilityRuntime::ThrowEtsInvalidParamError(env, "Object_GetField_Long failed"); + return; + } + int32_t errCode = ((AbilityRuntime::ApplicationContext*)nativeContextLong)->SetSupportedProcessCacheSelf(value); + if (errCode == AAFwk::ERR_CAPABILITY_NOT_SUPPORT) { + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_CAPABILITY_NOT_SUPPORT); + } else if (errCode != ERR_OK) { + AbilityRuntime::ThrowEtsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + } +} + +void OHOSApplication::InitAniApplicationContext() +{ + TAG_LOGD(AAFwkTag::APPKIT, "InitAniApplicationContext Call"); + auto& runtime = GetRuntime(AbilityRuntime::APPLICAITON_CODE_LANGUAGE_ARKTS_1_2); + if (runtime == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "runtime is null"); + return; + } + auto aniEnv = static_cast(*runtime).GetAniEnv(); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "env is null"); + return; + } + ani_class applicationContextCls = nullptr; + if (aniEnv->FindClass(ETS_APPLICATION_CONTEXT_CLASS_NAME, &applicationContextCls) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "FindClass ApplicationContext failed"); + return; + } + std::array applicationContextFunctions = { + ani_native_function {"setSupportedProcessCacheSync", "Z:V", + reinterpret_cast(SetSupportedProcessCacheSync)}, + }; + aniEnv->Class_BindNativeMethods(applicationContextCls, applicationContextFunctions.data(), + applicationContextFunctions.size()); + + ani_method contextCtorMethod = nullptr; + if (aniEnv->Class_FindMethod(applicationContextCls, "", ":V", &contextCtorMethod) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_FindMethod ctor failed"); + return; + } + ani_object applicationContextObject = nullptr; + if (aniEnv->Object_New(applicationContextCls, contextCtorMethod, &applicationContextObject) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_New failed"); + return; + } + ani_field contextField; + if (aniEnv->Class_FindField(applicationContextCls, "nativeContext", &contextField) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Class_FindField failed"); + return; + } + if (aniEnv->Object_SetField_Long(applicationContextObject, contextField, + (ani_long)abilityRuntimeContext_.get()) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Long failed"); + return; + } + auto etsReference = std::make_shared(); + etsReference->aniObj = applicationContextObject; + AbilityRuntime::ApplicationContextManager::GetApplicationContextManager().AddEtsGlobalObject(aniEnv, etsReference); +} + +void OHOSApplication::InitAniContext() +{ + TAG_LOGD(AAFwkTag::APPKIT, "InitAniContext Call"); + auto& runtime = GetRuntime(AbilityRuntime::APPLICAITON_CODE_LANGUAGE_ARKTS_1_2); + if (runtime == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "runtime is null"); + return; + } + auto aniEnv = static_cast(*runtime).GetAniEnv(); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "env is null"); + return; + } + ani_class contextCls = nullptr; + if (aniEnv->FindClass(ETS_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)}, + }; + aniEnv->Class_BindNativeMethods(contextCls, contextFunctions.data(), + contextFunctions.size()); +} + /** * * @brief Set the abilityRecordMgr to the OHOSApplication. diff --git a/interfaces/inner_api/ani_base_context/BUILD.gn b/interfaces/inner_api/ani_base_context/BUILD.gn new file mode 100644 index 00000000000..5e06a355be2 --- /dev/null +++ b/interfaces/inner_api/ani_base_context/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +config("ani_context_base_public_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_shared_library("ani_base_context") { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "include", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", + "${ability_runtime_services_path}/common/include", + ] + + sources = [ "src/ani_base_context.cpp" ] + + configs = [] + + public_configs = [ ":ani_context_base_public_config" ] + + external_deps = [ + "ability_base:configuration", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "hilog:libhilog", + "runtime_core:ani", + ] + + innerapi_tags = [ "platformsdk" ] + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/interfaces/inner_api/ani_base_context/include/ani_base_context.h b/interfaces/inner_api/ani_base_context/include/ani_base_context.h new file mode 100644 index 00000000000..f6e91e74525 --- /dev/null +++ b/interfaces/inner_api/ani_base_context/include/ani_base_context.h @@ -0,0 +1,55 @@ +/* + * 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_ANI_BASE_CONTEXT_H +#define OHOS_ABILITY_RUNTIME_ANI_BASE_CONTEXT_H + +#include "ani.h" + +#include +#include +#include +#include +#include "context.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AppExecFwk { +class Ability; +} + +namespace AbilityRuntime { + /** + * @brief Get "stageMode" value of object. + * + * @param env ANI environment. + * @param object Native value contains "stageMode" object. + * @param stageMode The value of "stageMode" object. + * @return ani_status + */ + ani_status IsStageContext(ani_env* env, ani_object object, ani_boolean& stageMode); + + /** + * @brief Get stage mode context. + * + * @param env ANI environment. + * @param object Native value of context. + * @return The stage mode context. + */ + class Context; + std::shared_ptr GetStageModeContext(ani_env* env, ani_object object); +} +} +#endif // OHOS_ABILITY_RUNTIME_ANI_BASE_CONTEXT_H diff --git a/interfaces/inner_api/ani_base_context/src/ani_base_context.cpp b/interfaces/inner_api/ani_base_context/src/ani_base_context.cpp new file mode 100644 index 00000000000..c43cf6cacd6 --- /dev/null +++ b/interfaces/inner_api/ani_base_context/src/ani_base_context.cpp @@ -0,0 +1,54 @@ +/* +* 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 "ani_base_context.h" + +namespace OHOS { +namespace AbilityRuntime { +ani_status IsStageContext(ani_env* env, ani_object object, ani_boolean& stageMode) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "env is nullptr"); + return ANI_ERROR; + } + + ani_status status = env->Object_GetFieldByName_Boolean(object, "stageMode", &stageMode); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "GetField failed, status : %{public}d", status); + return ANI_ERROR; + } + + return ANI_OK; +} + +std::shared_ptr GetStageModeContext(ani_env* env, ani_object object) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "env is nullptr"); + return nullptr; + } + + ani_long nativeContextLong; + ani_status status = env->Object_GetFieldByName_Long(object, "nativeContext", &nativeContextLong); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "Object_GetField_Long failed, status : %{public}d", status); + return nullptr; + } + + auto weakContext = reinterpret_cast*>(nativeContextLong); + return weakContext != nullptr ? weakContext->lock() : nullptr; +} +} // namespace AbilityRuntime +} // namespace OHOS 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 4ce60e5b703..bb307cb0926 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 00000000000..3faa9093295 --- /dev/null +++ b/interfaces/kits/native/appkit/ability_runtime/context/ets_context_utils.h @@ -0,0 +1,46 @@ +/* + * 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 SetArea([[maybe_unused]]ani_env *env, [[maybe_unused]]ani_object aniObj, ani_int value); + +void BindMethods(ani_env* aniEnv, ani_class contextClass); + +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 BindParentProperty(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 diff --git a/interfaces/kits/native/appkit/app/ohos_application.h b/interfaces/kits/native/appkit/app/ohos_application.h index 783bd601495..150810a459f 100644 --- a/interfaces/kits/native/appkit/app/ohos_application.h +++ b/interfaces/kits/native/appkit/app/ohos_application.h @@ -229,6 +229,10 @@ public: void CleanEmptyAbilityStage(); + void InitAniApplicationContext(); + + void InitAniContext(); + #ifdef SUPPORT_GRAPHICS bool GetDisplayConfig(uint64_t displayId, float &density, std::string &directionStr); #endif -- Gitee