From 188e9275a0a35b34e3952abb65e944badfa74a62 Mon Sep 17 00:00:00 2001 From: yangzk Date: Tue, 22 Jul 2025 18:56:07 +0800 Subject: [PATCH] =?UTF-8?q?Description:=20=E5=90=AF=E5=8A=A8=E6=A1=86?= =?UTF-8?q?=E6=9E=B6matchRules=E5=9C=BA=E6=99=AF=E4=B8=8B=E5=BB=B6?= =?UTF-8?q?=E8=BF=9F=E5=8A=A0=E8=BD=BD=E5=90=AF=E5=8A=A8=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=20IssueNo:#ICO3BP=20Sig:=20SIG=5FApplicationFramework=20Featur?= =?UTF-8?q?e=20or=20Bugfix:=20Bugfix=20Binary=20Source:=20No?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangzk Change-Id: I141102420750b7084416cf7049570da4f6bce630 --- .../ability_runtime/app/js_ability_stage.cpp | 18 +++-- .../appkit/app_startup/js_startup_task.cpp | 45 ++++++++++- .../appkit/app_startup/startup_manager.cpp | 15 +++- .../appkit/app_startup/app_startup_task.h | 14 ++++ .../appkit/app_startup/js_startup_task.h | 11 ++- .../appkit/app_startup/startup_manager.h | 27 ++----- .../startup_manager_mock_test.cpp | 78 +++++++++++++++++++ .../startup_manager_test.cpp | 14 ++++ 8 files changed, 191 insertions(+), 31 deletions(-) diff --git a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp index 83fe532464c..a8136fe61d8 100644 --- a/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp +++ b/frameworks/native/appkit/ability_runtime/app/js_ability_stage.cpp @@ -655,13 +655,19 @@ int32_t JsAbilityStage::RegisterAppStartupTask(const std::shared_ptr startupTaskInfos = startupManager->GetStartupTaskInfos(hapModuleInfo->name); for (const auto& item : startupTaskInfos) { - std::unique_ptr startupJsRef = LoadJsOhmUrl( - item.srcEntry, item.ohmUrl, item.moduleName, item.hapPath, item.esModule); - if (startupJsRef == nullptr) { - TAG_LOGE(AAFwkTag::APPKIT, "load js appStartup tasks failed."); - continue; + std::shared_ptr jsStartupTask; + if (startupManager->EnableLazyLoadingAppStartupTasks()) { + jsStartupTask = std::make_shared(item.name, jsRuntime_, item, shellContextRef_); + } else { + std::unique_ptr startupJsRef = LoadJsOhmUrl( + item.srcEntry, item.ohmUrl, item.moduleName, item.hapPath, item.esModule); + if (startupJsRef == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "load js appStartup tasks failed."); + continue; + } + jsStartupTask = std::make_shared(item.name, jsRuntime_, startupJsRef, shellContextRef_); } - auto jsStartupTask = std::make_shared(item.name, jsRuntime_, startupJsRef, shellContextRef_); + jsStartupTask->SetDependencies(item.dependencies); jsStartupTask->SetIsExcludeFromAutoStart(item.excludeFromAutoStart); jsStartupTask->SetCallCreateOnMainThread(item.callCreateOnMainThread); diff --git a/frameworks/native/appkit/app_startup/js_startup_task.cpp b/frameworks/native/appkit/app_startup/js_startup_task.cpp index 1beb8f98f2a..3eee08a8861 100644 --- a/frameworks/native/appkit/app_startup/js_startup_task.cpp +++ b/frameworks/native/appkit/app_startup/js_startup_task.cpp @@ -80,6 +80,14 @@ std::map> AsyncTaskCallBack::jsStartup const std::string JsStartupTask::TASK_TYPE = "Js"; +JsStartupTask::JsStartupTask(const std::string &name, JsRuntime &jsRuntime, const StartupTaskInfo &info, + const std::shared_ptr &contextJsRef) + : AppStartupTask(name), jsRuntime_(jsRuntime), startupJsRef_(nullptr), contextJsRef_(contextJsRef), + srcEntry_(info.srcEntry), ohmUrl_(info.ohmUrl), hapPath_(info.hapPath), esModule_(info.esModule) +{ + SetModuleName(info.moduleName); +} + JsStartupTask::JsStartupTask(const std::string& name, JsRuntime& jsRuntime, std::unique_ptr& startupJsRef, std::shared_ptr& contextJsRef) : AppStartupTask(name), jsRuntime_(jsRuntime), startupJsRef_(std::move(startupJsRef)), contextJsRef_(contextJsRef) @@ -96,6 +104,12 @@ const std::string &JsStartupTask::GetType() const int32_t JsStartupTask::RunTaskInit(std::unique_ptr callback) { TAG_LOGI(AAFwkTag::STARTUP, "task: %{public}s init", GetName().c_str()); + if (startupJsRef_ == nullptr) { + int32_t result = LoadJsOhmUrl(); + if (result != ERR_OK) { + return result; + } + } if (callCreateOnMainThread_) { return JsStartupTaskExecutor::RunOnMainThread(jsRuntime_, startupJsRef_, contextJsRef_, std::move(callback)); } @@ -121,6 +135,31 @@ int32_t JsStartupTask::RunTaskInit(std::unique_ptr ca return result; } +int32_t JsStartupTask::LoadJsOhmUrl() +{ + TAG_LOGD(AAFwkTag::STARTUP, "call"); + if (srcEntry_.empty() && ohmUrl_.empty()) { + TAG_LOGE(AAFwkTag::STARTUP, "srcEntry and ohmUrl empty"); + return ERR_STARTUP_INTERNAL_ERROR; + } + + std::string moduleNameWithStartupTask = moduleName_ + "::startupTask"; + std::string srcPath(moduleName_ + "/" + srcEntry_); + auto pos = srcPath.rfind('.'); + if (pos == std::string::npos) { + TAG_LOGE(AAFwkTag::STARTUP, "invalid srcEntry"); + return ERR_STARTUP_INTERNAL_ERROR; + } + srcPath.erase(pos); + srcPath.append(".abc"); + startupJsRef_ = jsRuntime_.LoadModule(moduleNameWithStartupTask, srcPath, hapPath_, esModule_, false, ohmUrl_); + if (startupJsRef_ == nullptr) { + TAG_LOGE(AAFwkTag::STARTUP, "startup task null"); + return ERR_STARTUP_INTERNAL_ERROR; + } + return ERR_OK; +} + int32_t JsStartupTask::LoadJsAsyncTaskExecutor() { TAG_LOGD(AAFwkTag::STARTUP, "called"); @@ -183,8 +222,10 @@ int32_t JsStartupTask::RunTaskOnDependencyCompleted(const std::string &dependenc auto env = jsRuntime_.GetNapiEnv(); if (startupJsRef_ == nullptr) { - TAG_LOGE(AAFwkTag::STARTUP, "null ref_:%{public}s", name_.c_str()); - return ERR_STARTUP_INTERNAL_ERROR; + int32_t result = LoadJsOhmUrl(); + if (result != ERR_OK) { + return result; + } } napi_value startupValue = startupJsRef_->GetNapiValue(); if (!CheckTypeForNapiValue(env, startupValue, napi_object)) { diff --git a/frameworks/native/appkit/app_startup/startup_manager.cpp b/frameworks/native/appkit/app_startup/startup_manager.cpp index 4a54f659374..ef56a145c7c 100644 --- a/frameworks/native/appkit/app_startup/startup_manager.cpp +++ b/frameworks/native/appkit/app_startup/startup_manager.cpp @@ -575,6 +575,11 @@ std::shared_ptr StartupManager::CreateAppPreloadSoTask( return task; } +bool StartupManager::EnableLazyLoadingAppStartupTasks() const +{ + return enableLazyLoadingAppStartupTasks_; +} + void StartupManager::PreloadAppHintStartupTask(std::shared_ptr startupTaskData) { std::map> preloadAppHintTasks; @@ -1163,7 +1168,7 @@ void StartupManager::SetOptionalParameters(const nlohmann::json& module, AppExec startupTaskInfo.excludeFromAutoStart = false; } - SetMatchRules(module, startupTaskInfo.matchRules); + SetMatchRules(module, startupTaskInfo.matchRules, false); } void StartupManager::SetOptionalParameters(const nlohmann::json &module, AppExecFwk::ModuleType moduleType, @@ -1188,15 +1193,19 @@ void StartupManager::SetOptionalParameters(const nlohmann::json &module, AppExec } StartupTaskMatchRules matchRules; - SetMatchRules(module, matchRules); + SetMatchRules(module, matchRules, true); task->SetMatchRules(matchRules); } -void StartupManager::SetMatchRules(const nlohmann::json &module, StartupTaskMatchRules &matchRules) +void StartupManager::SetMatchRules(const nlohmann::json &module, StartupTaskMatchRules &matchRules, + bool isPreloadSoStartupTask) { if (!module.contains(MATCH_RULES) || !module.at(MATCH_RULES).is_object()) { return; } + if (!isPreloadSoStartupTask) { + enableLazyLoadingAppStartupTasks_ = true; + } const nlohmann::json &matchRulesJson = module.at(MATCH_RULES); ParseJsonStringArray(matchRulesJson, URIS, matchRules.uris); diff --git a/interfaces/kits/native/appkit/app_startup/app_startup_task.h b/interfaces/kits/native/appkit/app_startup/app_startup_task.h index 5a0f1654db3..1eac952ac69 100644 --- a/interfaces/kits/native/appkit/app_startup/app_startup_task.h +++ b/interfaces/kits/native/appkit/app_startup/app_startup_task.h @@ -30,6 +30,20 @@ struct StartupTaskMatchRules { std::vector customization; }; +struct StartupTaskInfo { + std::string name; + std::string srcEntry; + std::string ohmUrl; + std::string moduleName; + std::string hapPath; + std::vector dependencies; + bool excludeFromAutoStart = false; + bool callCreateOnMainThread = true; + bool waitOnMainThread = true; + bool esModule = true; + StartupTaskMatchRules matchRules; +}; + class AppStartupTask : public StartupTask { public: explicit AppStartupTask(const std::string& name); diff --git a/interfaces/kits/native/appkit/app_startup/js_startup_task.h b/interfaces/kits/native/appkit/app_startup/js_startup_task.h index ca10a873535..ba1608f24b2 100644 --- a/interfaces/kits/native/appkit/app_startup/js_startup_task.h +++ b/interfaces/kits/native/appkit/app_startup/js_startup_task.h @@ -27,8 +27,11 @@ class JsStartupTask : public AppStartupTask { public: static const std::string TASK_TYPE; + JsStartupTask(const std::string &name, JsRuntime &jsRuntime, const StartupTaskInfo &info, + const std::shared_ptr &contextJsRef); + JsStartupTask(const std::string &name, JsRuntime &jsRuntime, - std::unique_ptr &startupJsRef, std::shared_ptr &contextJsRef_); + std::unique_ptr &startupJsRef, std::shared_ptr &contextJsRef); ~JsStartupTask() override; @@ -50,10 +53,16 @@ private: std::unique_ptr AsyncTaskExecutorJsRef_; std::unique_ptr AsyncTaskExecutorCallbackJsRef_; std::unique_ptr startupTaskResultCallback_; + std::string srcEntry_; + std::string ohmUrl_; + std::string hapPath_; + bool esModule_ = true; static napi_value GetDependencyResult(napi_env env, const std::string &dependencyName, const std::shared_ptr &result); + int32_t LoadJsOhmUrl(); + int32_t LoadJsAsyncTaskExecutor(); void LoadJsAsyncTaskCallback(); diff --git a/interfaces/kits/native/appkit/app_startup/startup_manager.h b/interfaces/kits/native/appkit/app_startup/startup_manager.h index c242104e59a..687f9556605 100644 --- a/interfaces/kits/native/appkit/app_startup/startup_manager.h +++ b/interfaces/kits/native/appkit/app_startup/startup_manager.h @@ -46,20 +46,6 @@ struct ModuleStartupConfigInfo { const AppExecFwk::ModuleType& moduleType, bool esModule); }; -struct StartupTaskInfo { - std::string name; - std::string srcEntry; - std::string ohmUrl; - std::string moduleName; - std::string hapPath; - std::vector dependencies; - bool excludeFromAutoStart = false; - bool callCreateOnMainThread = true; - bool waitOnMainThread = true; - bool esModule = true; - StartupTaskMatchRules matchRules; -}; - class StartupManager : public std::enable_shared_from_this { DECLARE_DELAYED_SINGLETON(StartupManager) @@ -114,6 +100,8 @@ public: int32_t BuildStartupTaskManager(const std::map> &tasks, std::shared_ptr &startupTaskManager); + bool EnableLazyLoadingAppStartupTasks() const; + private: // read only after initialization std::vector moduleStartupConfigInfos_; @@ -139,6 +127,7 @@ private: std::weak_ptr autoPreloadSoTaskManager_; std::weak_ptr autoPreloadSystemSoTaskManager_; bool autoPreloadSoStopped_ = false; + bool enableLazyLoadingAppStartupTasks_ = false; std::shared_ptr defaultConfig_; std::map> moduleConfigs_; @@ -182,11 +171,11 @@ private: std::map>& preloadSoStartupTasks, std::map>& preloadSystemSoStartupTasks, std::vector& pendingStartupTaskInfos, std::string& pendingConfigEntry); - static bool AnalyzeAppStartupTask(const ModuleStartupConfigInfo& info, nlohmann::json &startupConfigJson, + bool AnalyzeAppStartupTask(const ModuleStartupConfigInfo& info, nlohmann::json &startupConfigJson, std::vector& pendingStartupTaskInfos); bool AnalyzePreloadSoStartupTask(const ModuleStartupConfigInfo& info, nlohmann::json &startupConfigJson, std::map>& preloadSoStartupTasks); - static bool AnalyzeAppStartupTaskInner(const ModuleStartupConfigInfo& info, + bool AnalyzeAppStartupTaskInner(const ModuleStartupConfigInfo& info, const nlohmann::json &startupTaskJson, std::vector& pendingStartupTaskInfos); bool AnalyzePreloadSoStartupTaskInner(const ModuleStartupConfigInfo& info, @@ -196,11 +185,11 @@ private: std::map>& preloadSoStartupTasks); void AnalyzePreloadSystemSoStartupTaskInner(const nlohmann::json &preloadStartupTaskJson, std::map>& preloadSoStartupTasks); - static void SetOptionalParameters(const nlohmann::json& module, AppExecFwk::ModuleType moduleType, + void SetOptionalParameters(const nlohmann::json& module, AppExecFwk::ModuleType moduleType, StartupTaskInfo& startupTaskInfo); - static void SetOptionalParameters(const nlohmann::json &module, AppExecFwk::ModuleType moduleType, + void SetOptionalParameters(const nlohmann::json &module, AppExecFwk::ModuleType moduleType, std::shared_ptr &task); - static void SetMatchRules(const nlohmann::json &module, StartupTaskMatchRules &matchRules); + void SetMatchRules(const nlohmann::json &module, StartupTaskMatchRules &matchRules, bool isPreloadSoStartupTask); static bool ParseJsonStringArray(const nlohmann::json &json, const std::string &key, std::vector &arr); }; } // namespace AbilityRuntime diff --git a/test/unittest/frameworks_kits_appkit_native_test/startup_manager_mock_test.cpp b/test/unittest/frameworks_kits_appkit_native_test/startup_manager_mock_test.cpp index f73f42553cc..a4b33787a1b 100644 --- a/test/unittest/frameworks_kits_appkit_native_test/startup_manager_mock_test.cpp +++ b/test/unittest/frameworks_kits_appkit_native_test/startup_manager_mock_test.cpp @@ -90,6 +90,84 @@ HWTEST_F(StartupManagerMockTest, JsStartupTask_0100, Function | MediumTest | Lev EXPECT_EQ(ret, ERR_STARTUP_INTERNAL_ERROR); } +/** + * @tc.name: JsStartupTask_0200 + * @tc.type: FUNC + * @tc.Function: RunTaskInit + */ +HWTEST_F(StartupManagerMockTest, JsStartupTask_0200, Function | MediumTest | Level1) +{ + std::string name = "test_name"; + JsRuntime jsRuntime; + StartupTaskInfo info; + info.ohmUrl = "ohmurl"; + std::shared_ptr contextJsRef = nullptr; + std::shared_ptr startupTask = std::make_shared( + name, jsRuntime, info, contextJsRef); + startupTask->callCreateOnMainThread_ = false; + auto ret = startupTask->RunTaskInit(nullptr); + EXPECT_EQ(ret, ERR_STARTUP_INTERNAL_ERROR); +} + +/** + * @tc.name: JsStartupTask_0300 + * @tc.type: FUNC + * @tc.Function: RunTaskOnDependencyCompleted + */ +HWTEST_F(StartupManagerMockTest, JsStartupTask_0300, Function | MediumTest | Level1) +{ + std::string name = "test_name"; + JsRuntime jsRuntime; + StartupTaskInfo info; + info.srcEntry = "startup_task.ets"; + std::shared_ptr contextJsRef = nullptr; + std::shared_ptr startupTask = std::make_shared( + name, jsRuntime, info, contextJsRef); + startupTask->callCreateOnMainThread_ = false; + auto ret = startupTask->RunTaskOnDependencyCompleted("", nullptr); + EXPECT_EQ(ret, ERR_STARTUP_INTERNAL_ERROR); +} + +/** + * @tc.name: JsStartupTask_0400 + * @tc.type: FUNC + * @tc.Function: RunTaskOnDependencyCompleted + */ +HWTEST_F(StartupManagerMockTest, JsStartupTask_0400, Function | MediumTest | Level1) +{ + std::string name = "test_name"; + JsRuntime jsRuntime; + StartupTaskInfo info; + info.ohmUrl = "ohmurl"; + info.srcEntry = "startup_task"; + std::shared_ptr contextJsRef = nullptr; + std::shared_ptr startupTask = std::make_shared( + name, jsRuntime, info, contextJsRef); + startupTask->callCreateOnMainThread_ = false; + auto ret = startupTask->RunTaskOnDependencyCompleted("", nullptr); + EXPECT_EQ(ret, ERR_STARTUP_INTERNAL_ERROR); +} + +/** + * @tc.name: JsStartupTask_0500 + * @tc.type: FUNC + * @tc.Function: RunTaskOnDependencyCompleted + */ +HWTEST_F(StartupManagerMockTest, JsStartupTask_0500, Function | MediumTest | Level1) +{ + std::string name = "test_name"; + JsRuntime jsRuntime; + StartupTaskInfo info; + info.ohmUrl = "ohmurl"; + info.srcEntry = "startup_task.ets"; + std::shared_ptr contextJsRef = nullptr; + std::shared_ptr startupTask = std::make_shared( + name, jsRuntime, info, contextJsRef); + startupTask->callCreateOnMainThread_ = false; + auto ret = startupTask->RunTaskOnDependencyCompleted("", nullptr); + EXPECT_EQ(ret, ERR_STARTUP_INTERNAL_ERROR); +} + /** * @tc.name: js_insight_intent_executor_0100 * @tc.type: FUNC diff --git a/test/unittest/frameworks_kits_appkit_native_test/startup_manager_test.cpp b/test/unittest/frameworks_kits_appkit_native_test/startup_manager_test.cpp index 6241ba3a608..03becf770d9 100644 --- a/test/unittest/frameworks_kits_appkit_native_test/startup_manager_test.cpp +++ b/test/unittest/frameworks_kits_appkit_native_test/startup_manager_test.cpp @@ -1335,5 +1335,19 @@ HWTEST_F(StartupManagerTest, ParseJsonStringArray_001, Function | MediumTest | L EXPECT_EQ(arr3.size(), 2); GTEST_LOG_(INFO) << "ParseJsonStringArray_001 end"; } + +/** + * @tc.name: EnableLazyLoadingAppStartupTasks_001 + * @tc.desc: test EnableLazyLoadingAppStartupTasks + * @tc.type: FUNC + */ +HWTEST_F(StartupManagerTest, EnableLazyLoadingAppStartupTasks_001, Function | MediumTest | Level1) +{ + GTEST_LOG_(INFO) << "EnableLazyLoadingAppStartupTasks_001 start"; + std::shared_ptr startupManager = DelayedSingleton::GetInstance(); + ASSERT_NE(startupManager, nullptr); + EXPECT_EQ(startupManager->EnableLazyLoadingAppStartupTasks(), startupManager->enableLazyLoadingAppStartupTasks_); + GTEST_LOG_(INFO) << "EnableLazyLoadingAppStartupTasks_001 end"; +} } } \ No newline at end of file -- Gitee