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 ee3ed919acd6833ef612b93802d65553d9b8e29e..3f7c9ca92ae53da2d10685c153f149f433affd2a 100644 --- a/ets_environment/frameworks/ets_environment/src/ets_environment.cpp +++ b/ets_environment/frameworks/ets_environment/src/ets_environment.cpp @@ -25,6 +25,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 "ets_ani_expo.h" @@ -437,18 +441,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; } @@ -515,7 +525,9 @@ bool ETSEnvironment::FinishPreload() { return true; } -bool ETSEnvironment::PostFork(void *napiEnv, const std::string &aotPath) +bool ETSEnvironment::PostFork(void *napiEnv, const std::string &aotPath, + const std::vector &appInnerHspPathList, + const std::vector &commonHspBundleInfos) { std::vector options; std::string aotPathString = ""; @@ -534,6 +546,9 @@ bool ETSEnvironment::PostFork(void *napiEnv, const std::string &aotPath) return false; } ark::ets::ETSAni::Postfork(env, options); + + appInnerHspPathList_ = appInnerHspPathList; + commonHspBundleInfos_ = commonHspBundleInfos; return true; } @@ -588,8 +603,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); @@ -710,6 +726,163 @@ 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 diff --git a/ets_environment/interfaces/inner_api/ets_environment.h b/ets_environment/interfaces/inner_api/ets_environment.h index 06780e1571e5989e2067407604e5dc310661f65d..54ce7956b8ed7822e908dccdd9a78be58b9b0c84 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); bool FinishPreload(); - bool PostFork(void *napiEnv, const std::string &aotPath); + bool PostFork(void *napiEnv, const std::string &aotPath, const std::vector& appInnerHspPathList, + const std::vector &commonHspBundleInfos); bool 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 124563013b299e06c2e9bf88f13df33c438c852c..5b4e82fb89612f7e809dbc0f58bb345357e3e96d 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 (*SetExtensionApiCheckCallback)( std::function &cb) = nullptr; diff --git a/ets_environment/test/unittest/ets_environment_test/ets_environment_test.cpp b/ets_environment/test/unittest/ets_environment_test/ets_environment_test.cpp index 146d2d4001339b06433aeb34731a74a4905ec32d..89314833ffa5b18953aecb005c1f1c611248bfb9 100644 --- a/ets_environment/test/unittest/ets_environment_test/ets_environment_test.cpp +++ b/ets_environment/test/unittest/ets_environment_test/ets_environment_test.cpp @@ -336,7 +336,9 @@ HWTEST_F(EtsEnvironmentTest, PostFork_0100, TestSize.Level0) ASSERT_NE(etsEnv, nullptr); void *napiEnv = nullptr; std::string aotPath = "aotPath"; - auto result = etsEnv->PostFork(napiEnv, aotPath); + std::vector appInnerHspPathList; + std::vector commonHspBundleInfos; + auto result = etsEnv->PostFork(napiEnv, aotPath, appInnerHspPathList, commonHspBundleInfos); EXPECT_FALSE(result); } @@ -393,4 +395,4 @@ HWTEST_F(EtsEnvironmentTest, ParseHdcRegisterOption_0100, TestSize.Level2) ASSERT_EQ(result5, 456); } } // namespace StsEnv -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index c3ca7b8e1b394e644eb657f27197b290d56dfb5d..6b53420cb51daf738419cbb79e0537c351f4f26a 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -1718,10 +1718,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 bd546e081bbcfbfed060cf4c7ab8d231c6a77820..0ca968a97742321480f27c0fba1cdf9b31e54dcc 100644 --- a/frameworks/native/runtime/ets_runtime.cpp +++ b/frameworks/native/runtime/ets_runtime.cpp @@ -36,6 +36,7 @@ #ifdef SUPPORT_SCREEN #include "ace_forward_compatibility.h" +#include "arkts_module_preloader.h" #include "declarative_module_preloader.h" #include "hot_reloader.h" #endif //SUPPORT_SCREEN @@ -158,7 +159,9 @@ bool 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); return true; } @@ -281,6 +284,15 @@ bool ETSRuntime::Initialize(const Options &options, std::unique_ptr & apiTargetVersion_ = options.apiTargetVersion; TAG_LOGD(AAFwkTag::ETSRUNTIME, "Initialize: %{public}d", apiTargetVersion_); + +#ifdef SUPPORT_SCREEN + auto aniEngine = GetAniEnv(); + if (aniEngine == nullptr) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "GetAniEnv failed"); + return false; + } + OHOS::Ace::ArkTSModulePreloader::Preload(aniEngine); +#endif return true; } @@ -600,4 +612,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 d39a14c84ab92490a1ce17180be28f8248363c58..309e8f9b306b5d7b6a51e6c26304161ce5b0748a 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 9804e4a10024ae7aaaca480082a415ce9adf6e53..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,5 +308,29 @@ 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. +* @tc.type: FUNC +*/ +HWTEST_F(MultiUserConfigMgrTest, GetConfigurationByUserId_0400, TestSize.Level1) +{ + auto multiUserConfigurationMgr = std::make_shared(); + 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",