diff --git a/ets_environment/frameworks/ets_environment/BUILD.gn b/ets_environment/frameworks/ets_environment/BUILD.gn index 1c67d800122633704574c09186d75869cc286013..8bc85903f65b5c3cb0adfbd0dce646ee989064d0 100644 --- a/ets_environment/frameworks/ets_environment/BUILD.gn +++ b/ets_environment/frameworks/ets_environment/BUILD.gn @@ -48,9 +48,12 @@ ohos_shared_library("ets_environment") { deps = [ "${ability_runtime_innerkits_path}/connect_server_manager:connect_server_manager", + "${ability_runtime_innerkits_path}/runtime:runtime", ] external_deps = [ + "ability_base:string_utils", + "bundle_framework:appexecfwk_base", "c_utils:utils", "eventhandler:libeventhandler", "faultloggerd:libunwinder", diff --git a/ets_environment/frameworks/ets_environment/src/ets_environment.cpp b/ets_environment/frameworks/ets_environment/src/ets_environment.cpp index f08d98593914e2025bbfd00e08cc48c139225d98..4b4f96d79acef594fec7e80e2a0143ac8e5e073b 100644 --- a/ets_environment/frameworks/ets_environment/src/ets_environment.cpp +++ b/ets_environment/frameworks/ets_environment/src/ets_environment.cpp @@ -24,6 +24,10 @@ #include #include +#include "bundle_constants.h" +#include "constants.h" +#include "file_path_utils.h" +#include "runtime.h" #include "static_core/plugins/ets/runtime/ets_namespace_manager.h" #include "static_core/runtime/tooling/inspector/debugger_arkapi.h" #include "ets_ani_expo.h" @@ -439,18 +443,24 @@ bool ETSEnvironment::LoadAbcLinker(ani_env *env, const std::string &modulePath, TAG_LOGE(AAFwkTag::ETSRUNTIME, "FindClass failed, status: %{public}d", status); return false; } - ani_method method = nullptr; - if ((status = env->Class_FindMethod(abcCls, "", "Lstd/core/RuntimeLinker;[Lstd/core/String;:V", - &method)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ETSRUNTIME, "Class_FindMethod failed, status: %{public}d", status); + + abcObj = CreateRuntimeLinker(env, abcCls, undefinedRef, refArray); + if (abcObj == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "CreateRuntimeLinker failed"); return false; } - env->ResetError(); - if ((status = env->Object_New(abcCls, method, &abcObj, undefinedRef, refArray)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ETSRUNTIME, "Object_New failed, status: %{public}d", status); - HandleUncaughtError(); + + ani_class contextCls{}; + if ((status = env->FindClass("std.interop.InteropContext", &contextCls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "InteropContext failed, status: %{public}d", status); return false; } + if ((status = env->Class_CallStaticMethodByName_Void( + contextCls, "setDefaultInteropLinker", "C{std.core.RuntimeLinker}:", abcObj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "setDefaultInteropLinker failed, status: %{public}d", status); + return false; + } + return true; } @@ -516,7 +526,9 @@ void ETSEnvironment::FinishPreload() { ark::ets::ETSAni::Prefork(env); } -void ETSEnvironment::PostFork(void *napiEnv, const std::string &aotPath) +void ETSEnvironment::PostFork(void *napiEnv, const std::string &aotPath, + const std::vector &appInnerHspPathList, + const std::vector &commonHspBundleInfos) { std::vector options; std::string aotPathString = ""; @@ -535,6 +547,8 @@ void ETSEnvironment::PostFork(void *napiEnv, const std::string &aotPath) return; } ark::ets::ETSAni::Postfork(env, options); + appInnerHspPathList_ = appInnerHspPathList; + commonHspBundleInfos_ = commonHspBundleInfos; } void ETSEnvironment::PreloadSystemClass(const char *className) @@ -584,8 +598,9 @@ ETSEnvFuncs *ETSEnvironment::RegisterFuncs() .FinishPreload = []() { ETSEnvironment::GetInstance()->FinishPreload(); }, - .PostFork = [](void *napiEnv, const std::string &aotPath) { - ETSEnvironment::GetInstance()->PostFork(napiEnv, aotPath); + .PostFork = [](void *napiEnv, const std::string &aotPath, const std::vector &appInnerHspPathList, + const std::vector &commonHspBundleInfos) { + ETSEnvironment::GetInstance()->PostFork(napiEnv, aotPath, appInnerHspPathList, commonHspBundleInfos); }, .PreloadSystemClass = [](const char *className) { ETSEnvironment::GetInstance()->PreloadSystemClass(className); @@ -697,10 +712,167 @@ void ETSEnvironment::BroadcastAndConnect(const std::string& bundleName, int sock AbilityRuntime::ConnectServerManager::Get().SendInstanceMessageAll(nullptr); AbilityRuntime::ConnectServerManager::Get().StartConnectServer(bundleName, socketFd, false); } + +bool ETSEnvironment::ConvertHspPathToAniArray(ani_env *aniEnv, const std::vector &hapPathInfos, + ani_array_ref &refArray) +{ + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "GetAniEnv failed"); + return false; + } + ani_status status = ANI_ERROR; + ani_class stringCls = nullptr; + if ((status = aniEnv->FindClass(CLASSNAME_STRING, &stringCls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "FindClass Lstd/core/String Failed, status: %{public}d", status); + return false; + } + + ani_ref undefined_ref; + if ((status = aniEnv->GetUndefined(&undefined_ref)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "GetUndefined failed, status: %{public}d", status); + return false; + } + + if ((status = aniEnv->Array_New_Ref(stringCls, hapPathInfos.size(), undefined_ref, &refArray)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Array_New_Ref Failed, status: %{public}d", status); + return false; + } + + for (size_t index = 0; index < hapPathInfos.size(); index++) { + std::string hspPath = hapPathInfos[index]; + ani_string ani_str; + if ((status = aniEnv->String_NewUTF8(hspPath.c_str(), hspPath.size(), &ani_str)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "String_NewUTF8 modulePath Failed, status: %{public}d", status); + return false; + } + if ((status = aniEnv->Array_Set_Ref(refArray, index, ani_str)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Array_Set_Ref Failed, status: %{public}d", status); + return false; + } + } + return true; +} + +std::vector ETSEnvironment::GetHspPathList() +{ + std::vector hspPathList; + for (const auto &bundleInfo : commonHspBundleInfos_) { + if (bundleInfo.moduleArkTSMode == AppExecFwk::Constants::ARKTS_MODE_DYNAMIC) { + continue; + } + auto pos = bundleInfo.hapPath.rfind('/'); + if (pos == std::string::npos) { + TAG_LOGW(AAFwkTag::ETSRUNTIME, "hapPath invalid:%{public}s", bundleInfo.hapPath.c_str()); + continue; + } + std::string hspName = bundleInfo.hapPath.substr(pos); + hspPathList.push_back(std::string(AbilityBase::Constants::LOCAL_CODE_PATH) + + std::string(AbilityBase::Constants::FILE_SEPARATOR) + bundleInfo.bundleName + + std::string(AbilityBase::Constants::FILE_SEPARATOR) + bundleInfo.moduleName + hspName); + } + + for (const auto &appInnerHspPath : appInnerHspPathList_) { + hspPathList.push_back(AbilityBase::GetLoadPath(appInnerHspPath)); + } + + for (const auto &it : hspPathList) { + TAG_LOGD(AAFwkTag::ETSRUNTIME, "list hspPath:%{public}s", it.c_str()); + } + + return hspPathList; +} + +bool ETSEnvironment::GetHspAbcRuntimeLinker(ani_array_ref &refHspLinkerArray, ani_class cls) +{ + const auto &hspPathList = GetHspPathList(); + if (hspPathList.empty()) { + return true; + } + ani_env *aniEnv = GetAniEnv(); + if (aniEnv == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "GetAniEnv failed"); + return false; + } + ani_status status = ANI_ERROR; + ani_method method = nullptr; + if ((status = aniEnv->Class_FindMethod(cls, "", "Lstd/core/RuntimeLinker;Lescompat/Array;:V", + &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Class_FindMethod ctor failed, status: %{public}d", status); + return false; + } + + ani_ref undefined_ref; + if ((status = aniEnv->GetUndefined(&undefined_ref)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "GetUndefined failed, status: %{public}d", status); + return false; + } + + ani_array_ref str_refArray; + if (ConvertHspPathToAniArray(aniEnv, hspPathList, str_refArray) == false) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "ConvertHspPathToAniArray failed"); + return false; + } + + ani_object object = nullptr; + if ((status = aniEnv->Object_New(cls, method, &object, undefined_ref, str_refArray)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Object_New AbcRuntimeLinker failed, status: %{public}d", status); + return false; + } + + if ((status = aniEnv->Array_New_Ref(cls, 1, undefined_ref, &refHspLinkerArray)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Array_New_Ref Failed, status: %{public}d", status); + return false; + } + if ((status = aniEnv->Array_Set_Ref(refHspLinkerArray, 0, object)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Array_Set_Ref Failed, status: %{public}d", status); + return false; + } + return true; +} + +ani_object ETSEnvironment::CreateRuntimeLinker( + ani_env *aniEnv, ani_class cls, ani_ref undefined_ref, ani_array_ref& refArray) +{ + ani_object object = nullptr; + ani_array_ref refHspLinkerArray = nullptr; + GetHspAbcRuntimeLinker(refHspLinkerArray, cls); + ani_status status = ANI_ERROR; + + if (refHspLinkerArray == nullptr) { + ani_method runtimeLinkerCtorMethod = nullptr; + if ((status = aniEnv->Class_FindMethod( + cls, "", "Lstd/core/RuntimeLinker;Lescompat/Array;:V", &runtimeLinkerCtorMethod)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Class_FindMethod ctor failed, status: %{public}d", status); + return nullptr; + } + if ((status = aniEnv->Object_New(cls, runtimeLinkerCtorMethod, &object, undefined_ref, refArray)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Object_New runtimeLinkerCtorMethod failed, status: %{public}d", status); + HandleUncaughtError(); + return nullptr; + } + } else { + ani_method runtimeLinkerCtorMethodEx = nullptr; + if ((status = aniEnv->Class_FindMethod(cls, + "", + "Lstd/core/RuntimeLinker;Lescompat/Array;[Lstd/core/RuntimeLinker;:V", + &runtimeLinkerCtorMethodEx)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Class_FindMethod ctor failed, status: %{public}d", status); + return nullptr; + } + if ((status = aniEnv->Object_New(cls, runtimeLinkerCtorMethodEx, &object, undefined_ref, refArray, + refHspLinkerArray)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Object_New runtimeLinkerCtorMethodEx failed, status: %{public}d", status); + HandleUncaughtError(); + return nullptr; + } + } + + return object; +} } // namespace EtsEnv } // namespace OHOS ETS_EXPORT extern "C" ETSEnvFuncs *OHOS_ETS_ENV_RegisterFuncs() { return OHOS::EtsEnv::ETSEnvironment::RegisterFuncs(); -} \ No newline at end of file +} diff --git a/ets_environment/interfaces/inner_api/ets_environment.h b/ets_environment/interfaces/inner_api/ets_environment.h index c7a79c5f5708849150ee2c2fe720ed5d2877f1a1..2e9a19aea07ed8c825d04da7808054b8b9344233 100644 --- a/ets_environment/interfaces/inner_api/ets_environment.h +++ b/ets_environment/interfaces/inner_api/ets_environment.h @@ -60,7 +60,8 @@ public: bool LoadModule(const std::string &modulePath, const std::string &srcEntrance, void *&cls, void *&obj, void *&ref); void FinishPreload(); - void PostFork(void *napiEnv, const std::string &aotPath); + void PostFork(void *napiEnv, const std::string &aotPath, const std::vector& appInnerHspPathList, + const std::vector &commonHspBundleInfos); void PreloadSystemClass(const char *className); void RemoveInstance(uint32_t instanceId); @@ -83,6 +84,11 @@ public: }; private: + bool ConvertHspPathToAniArray(ani_env *aniEnv, const std::vector &hapPathInfos, + ani_array_ref &refArray); + std::vector GetHspPathList(); + bool GetHspAbcRuntimeLinker(ani_array_ref &refHspLinkerArray, ani_class cls); + ani_object CreateRuntimeLinker(ani_env *aniEnv, ani_class cls, ani_ref undefined_ref, ani_array_ref &refArray); bool LoadRuntimeApis(); bool LoadSymbolCreateVM(void *handle, ETSRuntimeAPI &apis); bool LoadSymbolANIGetCreatedVMs(void *handle, ETSRuntimeAPI &apis); @@ -98,6 +104,8 @@ private: ETSUncaughtExceptionInfo uncaughtExceptionInfo_; std::shared_ptr eventHandler_; bool debugMode_ = false; + std::vector appInnerHspPathList_; + std::vector commonHspBundleInfos_; }; } // namespace EtsEnv } // namespace OHOS diff --git a/ets_environment/interfaces/inner_api/ets_interface.h b/ets_environment/interfaces/inner_api/ets_interface.h index fa6fcc369d22bb4102fac29fb8b1634ba3edb03c..935a46ef708412bcd415f773598ca741dc5bb7f9 100644 --- a/ets_environment/interfaces/inner_api/ets_interface.h +++ b/ets_environment/interfaces/inner_api/ets_interface.h @@ -27,6 +27,9 @@ namespace OHOS { namespace AppExecFwk { class EventRunner; } +namespace AbilityRuntime { + struct CommonHspBundleInfo; +} } extern "C" { @@ -45,7 +48,9 @@ struct ETSEnvFuncs { void (*SetAppLibPath)(const std::map &abcPathsToBundleModuleNameMap, std::function &cb) = nullptr; void (*FinishPreload)() = nullptr; - void (*PostFork)(void *napiEnv, const std::string &aotPath) = nullptr; + void (*PostFork)(void *napiEnv, const std::string &aotPath, + const std::vector &appInnerHspPathList, + const std::vector &commonHspBundleInfos) = nullptr; void (*PreloadSystemClass)(const char *className) = nullptr; void (*RemoveInstance)(uint32_t instanceId) = nullptr; void (*StopDebugMode)(void *jsVm) = nullptr; diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index e5ceb9110c429634d075e3e17ec81f9af2407e25..545d5c42098730e8281c20e3b781f12c90b8ca7f 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -1713,10 +1713,18 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con for (auto hapModuleInfo : bundleInfo.hapModuleInfos) { options.hapModulePath[hapModuleInfo.moduleName] = hapModuleInfo.hapPath; options.packageNameList[hapModuleInfo.moduleName] = hapModuleInfo.packageName; + if (hapModuleInfo.moduleType == AppExecFwk::ModuleType::SHARED && + hapModuleInfo.moduleArkTSMode != AppExecFwk::Constants::ARKTS_MODE_DYNAMIC) { + TAG_LOGD(AAFwkTag::APPKIT, "appInnerHspPathList: %{public}s", hapModuleInfo.hapPath.c_str()); + options.appInnerHspPathList.push_back(hapModuleInfo.hapPath); + } options.aotCompileStatusMap[hapModuleInfo.moduleName] = static_cast(hapModuleInfo.aotCompileStatus); } } + for (const auto &hsp : hspList) { + options.commonHspBundleInfos.push_back({hsp.bundleName, hsp.moduleName, hsp.hapPath, hsp.moduleArkTSMode}); + } options.enableWarmStartupSmartGC = (appLaunchData.GetAppPreloadMode() == AppExecFwk::PreloadMode::PRE_MAKE || appLaunchData.GetAppPreloadMode() == AppExecFwk::PreloadMode::PRELOAD_MODULE); diff --git a/frameworks/native/runtime/ets_runtime.cpp b/frameworks/native/runtime/ets_runtime.cpp index e5c0886feaa019a06ce205c2f9933e4ae92a410d..98ed7221404c4a20b535adcaf28fc1695f16e051 100644 --- a/frameworks/native/runtime/ets_runtime.cpp +++ b/frameworks/native/runtime/ets_runtime.cpp @@ -278,7 +278,8 @@ void ETSRuntime::PostFork(const Options &options, std::unique_ptr &js aotFilePath = SANDBOX_ARK_CACHE_PATH + options.arkNativeFilePath + options.moduleName + ".an"; } napi_env napiEnv = static_cast(jsRuntime_.get())->GetNapiEnv(); - g_etsEnvFuncs->PostFork(reinterpret_cast(napiEnv), aotFilePath); + g_etsEnvFuncs->PostFork(reinterpret_cast(napiEnv), aotFilePath, options.appInnerHspPathList, + options.commonHspBundleInfos); } std::unique_ptr ETSRuntime::Create(const Options &options, std::unique_ptr &jsRuntime) @@ -699,4 +700,4 @@ void ETSRuntime::StopDebugMode() g_etsEnvFuncs->StopDebugMode(vm); } } // namespace AbilityRuntime -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/interfaces/inner_api/runtime/include/runtime.h b/interfaces/inner_api/runtime/include/runtime.h index 0a0bd6ebd28bd15cb860b2cfb263ff251d6342c6..721d67dd6e24e90edefd928dd922eff0c99aa698 100644 --- a/interfaces/inner_api/runtime/include/runtime.h +++ b/interfaces/inner_api/runtime/include/runtime.h @@ -27,6 +27,12 @@ namespace AppExecFwk { class EventRunner; } // namespace AppExecFwk namespace AbilityRuntime { +struct CommonHspBundleInfo { + std::string bundleName; + std::string moduleName; + std::string hapPath; + std::string moduleArkTSMode; +}; namespace { const std::string CODE_LANGUAGE_ARKTS_1_0 = "dynamic"; const std::string CODE_LANGUAGE_ARKTS_1_2 = "static"; @@ -55,6 +61,8 @@ public: std::vector assetBasePathStr; std::shared_ptr eventRunner = nullptr; std::map hapModulePath; + std::vector appInnerHspPathList; + std::vector commonHspBundleInfos; bool loadAce = true; bool preload = false; bool isBundle = true; diff --git a/test/unittest/multi_user_config_mgr_test/multi_user_config_mgr_test.cpp b/test/unittest/multi_user_config_mgr_test/multi_user_config_mgr_test.cpp index 8c9c1a0363bc0370e16c5dfedda1b8691c961409..093ecb4fc16e6992fbabde7ffa1b35d4b7bf30cc 100644 --- a/test/unittest/multi_user_config_mgr_test/multi_user_config_mgr_test.cpp +++ b/test/unittest/multi_user_config_mgr_test/multi_user_config_mgr_test.cpp @@ -308,6 +308,19 @@ HWTEST_F(MultiUserConfigMgrTest, GetConfigurationByUserId_0100, TestSize.Level1) EXPECT_NE(multiUserConfigurationMgr->GetConfigurationByUserId(userId), nullptr); } +/** +* @tc.name: GetConfigurationByUserId_0300 +* @tc.desc: GetConfigurationByUserId. +* @tc.type: FUNC +*/ +HWTEST_F(MultiUserConfigMgrTest, GetConfigurationByUserId_0300, TestSize.Level1) +{ + auto multiUserConfigurationMgr = + std::make_shared(); + multiUserConfigurationMgr->globalConfiguration_ = nullptr; + EXPECT_EQ(multiUserConfigurationMgr->GetConfigurationByUserId(100), nullptr); +} + /** * @tc.name: GetConfigurationByUserId_0400 * @tc.desc: GetConfigurationByUserId. @@ -319,6 +332,5 @@ HWTEST_F(MultiUserConfigMgrTest, GetConfigurationByUserId_0400, TestSize.Level1) multiUserConfigurationMgr->globalConfiguration_ = std::make_shared(); EXPECT_NE(multiUserConfigurationMgr->GetConfigurationByUserId(100), nullptr); } - } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/runtime_test/BUILD.gn b/test/unittest/runtime_test/BUILD.gn index 709cca198469e7e10a8adf232458cb9c80a764e0..07f8a6615e3ebdde1b5e4874885a9a03fc98b834 100644 --- a/test/unittest/runtime_test/BUILD.gn +++ b/test/unittest/runtime_test/BUILD.gn @@ -289,6 +289,7 @@ ohos_unittest("ets_runtime_test") { ] external_deps = [ + "ability_base:string_utils", "ability_runtime:runtime", "bundle_framework:appexecfwk_core", "c_utils:utils",