• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "startup_manager.h"
17 
18 #include <set>
19 #include <nlohmann/json.hpp>
20 
21 #include "hilog_tag_wrapper.h"
22 #include "extractor.h"
23 #include "hitrace_meter.h"
24 #include "native_startup_task.h"
25 #include "preload_so_startup_task.h"
26 
27 namespace OHOS {
28 namespace AbilityRuntime {
29 namespace {
30 constexpr char LOAD_APP_STARTUP_CONFIG_TASK[] = "_LoadAppStartupConfigTask";
31 constexpr char APP_AUTO_PRELOAD_SO_TASK[] = "_AppPreloadSoTask";
32 constexpr char APP_PRELOAD_SO_TASK[] = "_AppLoadSoTask";
33 constexpr const char* PROFILE_FILE_PREFIX = "$profile:";
34 constexpr const char* PROFILE_PATH = "resources/base/profile/";
35 constexpr const char* JSON_SUFFIX = ".json";
36 constexpr const char* STARTUP_TASKS = "startupTasks";
37 constexpr const char* PRELOAD_STARTUP_TASKS = "appPreloadHintStartupTasks";
38 constexpr const char* NAME = "name";
39 constexpr const char* SRC_ENTRY = "srcEntry";
40 constexpr const char* DEPENDENCIES = "dependencies";
41 constexpr const char* EXCLUDE_FROM_AUTO_START = "excludeFromAutoStart";
42 constexpr const char* RUN_ON_THREAD = "runOnThread";
43 constexpr const char* WAIT_ON_MAIN_THREAD = "waitOnMainThread";
44 constexpr const char* CONFIG_ENTRY = "configEntry";
45 constexpr const char* TASK_POOL = "taskPool";
46 constexpr const char* TASK_POOL_LOWER = "taskpool";
47 constexpr const char* MAIN_THREAD = "mainThread";
48 constexpr const char* OHMURL = "ohmurl";
49 
50 struct StartupTaskResultCallbackInfo {
51     std::unique_ptr<StartupTaskResultCallback> callback_;
52 
StartupTaskResultCallbackInfoOHOS::AbilityRuntime::__anona7188aca0111::StartupTaskResultCallbackInfo53     explicit StartupTaskResultCallbackInfo(std::unique_ptr<StartupTaskResultCallback> callback)
54         : callback_(std::move(callback))
55     {
56     }
57 };
58 } // namespace
59 
ModuleStartupConfigInfo(std::string name,std::string startupConfig,std::string hapPath,const AppExecFwk::ModuleType & moduleType,bool esModule)60 ModuleStartupConfigInfo::ModuleStartupConfigInfo(std::string name, std::string startupConfig, std::string hapPath,
61     const AppExecFwk::ModuleType& moduleType, bool esModule)
62     : name_(std::move(name)), startupConfig_(std::move(startupConfig)), hapPath_(std::move(hapPath)),
63       moduleType_(moduleType), esModule_(esModule)
64 {
65 }
66 
StartupManager()67 StartupManager::StartupManager()
68 {
69     mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
70 }
71 
72 StartupManager::~StartupManager() = default;
73 
PreloadAppHintStartup(const AppExecFwk::BundleInfo & bundleInfo,const AppExecFwk::HapModuleInfo & entryInfo,const std::string & preloadModuleName)74 int32_t StartupManager::PreloadAppHintStartup(const AppExecFwk::BundleInfo& bundleInfo,
75     const AppExecFwk::HapModuleInfo& entryInfo, const std::string &preloadModuleName)
76 {
77     moduleStartupConfigInfos_.clear();
78     if (entryInfo.appStartup.empty()) {
79         TAG_LOGD(AAFwkTag::STARTUP, "entry module no app startup config");
80         return ERR_OK;
81     }
82     moduleStartupConfigInfos_.emplace_back(entryInfo.name, entryInfo.appStartup, entryInfo.hapPath,
83         entryInfo.moduleType, entryInfo.compileMode == AppExecFwk::CompileMode::ES_MODULE);
84 
85     for (const auto& module : bundleInfo.hapModuleInfos) {
86         if (module.appStartup.empty()) {
87             continue;
88         }
89         if (module.moduleType != AppExecFwk::ModuleType::SHARED) {
90             // ENTRY has been added and FEATURE is not supported.
91             continue;
92         }
93         moduleStartupConfigInfos_.emplace_back(module.name, module.appStartup, module.hapPath, module.moduleType,
94             module.compileMode == AppExecFwk::CompileMode::ES_MODULE);
95     }
96     preloadHandler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::Create());
97     if (preloadHandler_ == nullptr) {
98         TAG_LOGE(AAFwkTag::STARTUP, "failed to create handler");
99         return ERR_STARTUP_INTERNAL_ERROR;
100     }
101 
102     if (entryInfo.name != preloadModuleName) {
103         // not entry module, no need to load app startup config and preload so now.
104         TAG_LOGD(AAFwkTag::STARTUP, "not entry module: %{public}s", preloadModuleName.c_str());
105         return ERR_OK;
106     }
107     TAG_LOGD(AAFwkTag::STARTUP, "appStartup modules: %{public}zu", moduleStartupConfigInfos_.size());
108     preloadHandler_->PostTask([weak = weak_from_this()]() {
109         auto self = weak.lock();
110         if (self == nullptr) {
111             TAG_LOGE(AAFwkTag::STARTUP, "self is null");
112             return;
113         }
114         self->PreloadAppHintStartupTask();
115     });
116     return ERR_OK;
117 }
118 
BuildAutoAppStartupTaskManager(std::shared_ptr<StartupTaskManager> & startupTaskManager)119 int32_t StartupManager::BuildAutoAppStartupTaskManager(std::shared_ptr<StartupTaskManager> &startupTaskManager)
120 {
121     std::map<std::string, std::shared_ptr<StartupTask>> autoStartupTasks;
122     std::set<std::string> dependenciesSet;
123     for (auto &iter : appStartupTasks_) {
124         if (iter.second == nullptr) {
125             TAG_LOGE(AAFwkTag::STARTUP, "startup task null");
126             return ERR_STARTUP_INTERNAL_ERROR;
127         }
128         if (iter.second->GetIsExcludeFromAutoStart()) {
129             continue;
130         }
131         autoStartupTasks.emplace(iter.first, iter.second);
132         auto dependencies = iter.second->GetDependencies();
133         for (auto &dep : dependencies) {
134             dependenciesSet.insert(dep);
135         }
136     }
137     for (auto &dep : dependenciesSet) {
138         if (autoStartupTasks.find(dep) != autoStartupTasks.end()) {
139             continue;
140         }
141         TAG_LOGI(AAFwkTag::STARTUP, "try to add excludeFromAutoStart task: %{public}s", dep.c_str());
142         AddStartupTask(dep, autoStartupTasks, appStartupTasks_);
143     }
144 
145     std::lock_guard guard(startupTaskManagerMutex_);
146     TAG_LOGD(AAFwkTag::STARTUP, "autoStartupTasksManager build, id: %{public}u, tasks num: %{public}zu",
147         startupTaskManagerId, autoStartupTasks.size());
148     startupTaskManager = std::make_shared<StartupTaskManager>(startupTaskManagerId, autoStartupTasks);
149     startupTaskManager->SetConfig(defaultConfig_);
150     startupTaskManagerMap_.emplace(startupTaskManagerId, startupTaskManager);
151     startupTaskManagerId++;
152     return ERR_OK;
153 }
154 
LoadAppStartupTaskConfig(bool & needRunAutoStartupTask)155 int32_t StartupManager::LoadAppStartupTaskConfig(bool &needRunAutoStartupTask)
156 {
157     needRunAutoStartupTask = false;
158     if (moduleStartupConfigInfos_.empty()) {
159         return ERR_OK;
160     }
161     int32_t result = RunLoadAppStartupConfigTask();
162     if (result != ERR_OK) {
163         return result;
164     }
165     if (pendingStartupTaskInfos_.empty()) {
166         TAG_LOGD(AAFwkTag::STARTUP, "no app startup task");
167         return ERR_OK;
168     }
169     needRunAutoStartupTask = true;
170     return ERR_OK;
171 }
172 
BuildAppStartupTaskManager(const std::vector<std::string> & inputDependencies,std::shared_ptr<StartupTaskManager> & startupTaskManager)173 int32_t StartupManager::BuildAppStartupTaskManager(const std::vector<std::string> &inputDependencies,
174     std::shared_ptr<StartupTaskManager> &startupTaskManager)
175 {
176     std::map<std::string, std::shared_ptr<StartupTask>> currentStartupTasks;
177     std::set<std::string> dependenciesSet;
178     std::vector<std::string> preloadSoTaskName;
179     for (auto &iter : inputDependencies) {
180         auto findResult = appStartupTasks_.find(iter);
181         if (findResult == appStartupTasks_.end()) {
182             // Not found in appStartupTasks_, tried later in preloadSoStartupTasks_
183             preloadSoTaskName.emplace_back(iter);
184             continue;
185         }
186         if (findResult->second == nullptr) {
187             TAG_LOGE(AAFwkTag::STARTUP, "%{public}s startup task null", iter.c_str());
188             return ERR_STARTUP_INTERNAL_ERROR;
189         }
190         currentStartupTasks.emplace(iter, findResult->second);
191         auto dependencies = findResult->second->GetDependencies();
192         for (auto &dep : dependencies) {
193             dependenciesSet.insert(dep);
194         }
195     }
196     for (auto &dep : dependenciesSet) {
197         if (currentStartupTasks.find(dep) != currentStartupTasks.end()) {
198             continue;
199         }
200         AddStartupTask(dep, currentStartupTasks, appStartupTasks_);
201     }
202 
203     int32_t result = AddAppPreloadSoTask(preloadSoTaskName, currentStartupTasks);
204     if (result != ERR_OK) {
205         return result;
206     }
207 
208     std::lock_guard guard(startupTaskManagerMutex_);
209     TAG_LOGD(AAFwkTag::STARTUP, "startupTasksManager build, id: %{public}u, tasks num: %{public}zu",
210         startupTaskManagerId, currentStartupTasks.size());
211     startupTaskManager = std::make_shared<StartupTaskManager>(startupTaskManagerId, currentStartupTasks);
212     startupTaskManager->SetConfig(defaultConfig_);
213     startupTaskManagerMap_.emplace(startupTaskManagerId, startupTaskManager);
214     startupTaskManagerId++;
215     return ERR_OK;
216 }
217 
OnStartupTaskManagerComplete(uint32_t id)218 int32_t StartupManager::OnStartupTaskManagerComplete(uint32_t id)
219 {
220     std::lock_guard guard(startupTaskManagerMutex_);
221     auto result = startupTaskManagerMap_.find(id);
222     if (result == startupTaskManagerMap_.end()) {
223         TAG_LOGE(AAFwkTag::STARTUP, "StartupTaskManager id: %{public}u not found", id);
224         return ERR_STARTUP_INTERNAL_ERROR;
225     }
226     TAG_LOGD(AAFwkTag::STARTUP, "erase StartupTaskManager id: %{public}u", id);
227     startupTaskManagerMap_.erase(result);
228     return ERR_OK;
229 }
230 
SetDefaultConfig(const std::shared_ptr<StartupConfig> & config)231 void StartupManager::SetDefaultConfig(const std::shared_ptr<StartupConfig> &config)
232 {
233     defaultConfig_ = config;
234 }
235 
GetDefaultConfig() const236 const std::shared_ptr<StartupConfig>& StartupManager::GetDefaultConfig() const
237 {
238     return defaultConfig_;
239 }
240 
RemoveAllResult()241 int32_t StartupManager::RemoveAllResult()
242 {
243     TAG_LOGD(AAFwkTag::STARTUP, "called");
244     for (auto &iter : appStartupTasks_) {
245         if (iter.second != nullptr) {
246             iter.second->RemoveResult();
247         }
248     }
249     for (auto &iter: preloadSoStartupTasks_) {
250         if (iter.second != nullptr) {
251             iter.second->RemoveResult();
252         }
253     }
254     return ERR_OK;
255 }
256 
RemoveResult(const std::string & name)257 int32_t StartupManager::RemoveResult(const std::string &name)
258 {
259     TAG_LOGD(AAFwkTag::STARTUP, "called, name: %{public}s", name.c_str());
260     auto findResult = appStartupTasks_.find(name);
261     if (findResult == appStartupTasks_.end() || findResult->second == nullptr) {
262         findResult = preloadSoStartupTasks_.find(name);
263         if (findResult == preloadSoStartupTasks_.end() || findResult->second == nullptr) {
264             TAG_LOGE(AAFwkTag::STARTUP, "%{public}s not found", name.c_str());
265             return ERR_STARTUP_INVALID_VALUE;
266         }
267     }
268     return findResult->second->RemoveResult();
269 }
270 
GetResult(const std::string & name,std::shared_ptr<StartupTaskResult> & result)271 int32_t StartupManager::GetResult(const std::string &name, std::shared_ptr<StartupTaskResult> &result)
272 {
273     TAG_LOGD(AAFwkTag::STARTUP, "called, name: %{public}s", name.c_str());
274     auto findResult = appStartupTasks_.find(name);
275     if (findResult == appStartupTasks_.end() || findResult->second == nullptr) {
276         findResult = preloadSoStartupTasks_.find(name);
277         if (findResult == preloadSoStartupTasks_.end() || findResult->second == nullptr) {
278             TAG_LOGE(AAFwkTag::STARTUP, "%{public}s not found", name.c_str());
279             return ERR_STARTUP_INVALID_VALUE;
280         }
281     }
282     StartupTask::State state = findResult->second->GetState();
283     if (state != StartupTask::State::INITIALIZED) {
284         TAG_LOGE(AAFwkTag::STARTUP, "%{public}s not initialized", name.c_str());
285         return ERR_STARTUP_INVALID_VALUE;
286     }
287     result = findResult->second->GetResult();
288     return ERR_OK;
289 }
290 
IsInitialized(const std::string & name,bool & isInitialized)291 int32_t StartupManager::IsInitialized(const std::string &name, bool &isInitialized)
292 {
293     TAG_LOGD(AAFwkTag::STARTUP, "called, name: %{public}s", name.c_str());
294     auto findResult = appStartupTasks_.find(name);
295     if (findResult == appStartupTasks_.end() || findResult->second == nullptr) {
296         findResult = preloadSoStartupTasks_.find(name);
297         if (findResult == preloadSoStartupTasks_.end() || findResult->second == nullptr) {
298             TAG_LOGE(AAFwkTag::STARTUP, "%{public}s not found", name.c_str());
299             return ERR_STARTUP_INVALID_VALUE;
300         }
301     }
302     StartupTask::State state = findResult->second->GetState();
303     isInitialized = state == StartupTask::State::INITIALIZED;
304     return ERR_OK;
305 }
306 
PostMainThreadTask(const std::function<void ()> & task)307 int32_t StartupManager::PostMainThreadTask(const std::function<void()> &task)
308 {
309     if (mainHandler_ == nullptr) {
310         TAG_LOGE(AAFwkTag::STARTUP, "null mainHandler");
311         return ERR_STARTUP_INTERNAL_ERROR;
312     }
313     mainHandler_->PostTask(task);
314     return ERR_OK;
315 }
316 
StopAutoPreloadSoTask()317 void StartupManager::StopAutoPreloadSoTask()
318 {
319     std::lock_guard guard(autoPreloadSoTaskManagerMutex_);
320     autoPreloadSoStopped_ = true;
321     auto task = autoPreloadSoTaskManager_.lock();
322     if (task == nullptr) {
323         return;
324     }
325     task->TimeoutStop();
326 }
327 
HasAppStartupConfig() const328 bool StartupManager::HasAppStartupConfig() const
329 {
330     return !moduleStartupConfigInfos_.empty();
331 }
332 
GetStartupTaskInfos() const333 const std::vector<StartupTaskInfo> &StartupManager::GetStartupTaskInfos() const
334 {
335     return pendingStartupTaskInfos_;
336 }
337 
GetPendingConfigEntry() const338 const std::string &StartupManager::GetPendingConfigEntry() const
339 {
340     return pendingConfigEntry_;
341 }
342 
AddStartupTask(const std::string & name,std::map<std::string,std::shared_ptr<StartupTask>> & taskMap,std::map<std::string,std::shared_ptr<AppStartupTask>> & allTasks)343 int32_t StartupManager::AddStartupTask(const std::string &name,
344     std::map<std::string, std::shared_ptr<StartupTask>> &taskMap,
345     std::map<std::string, std::shared_ptr<AppStartupTask>> &allTasks)
346 {
347     auto isAdded = taskMap.find(name);
348     if (isAdded != taskMap.end()) {
349         // already added
350         return ERR_OK;
351     }
352     std::stack<std::string> taskStack;
353     taskStack.push(name);
354     while (!taskStack.empty()) {
355         auto taskName = taskStack.top();
356         taskStack.pop();
357         auto findResult = allTasks.find(taskName);
358         if (findResult == allTasks.end()) {
359             TAG_LOGE(AAFwkTag::STARTUP, "startup task not found %{public}s", taskName.c_str());
360             return ERR_STARTUP_DEPENDENCY_NOT_FOUND;
361         }
362         taskMap.emplace(taskName, findResult->second);
363         if (findResult->second == nullptr) {
364             TAG_LOGE(AAFwkTag::STARTUP, "null task:%{public}s", taskName.c_str());
365             return ERR_STARTUP_INTERNAL_ERROR;
366         }
367         auto dependencies = findResult->second->GetDependencies();
368         for (auto &dep : dependencies) {
369             if (taskMap.find(dep) == taskMap.end()) {
370                 taskStack.push(dep);
371             }
372         }
373     }
374     return ERR_OK;
375 }
376 
RegisterPreloadSoStartupTask(const std::string & name,const std::shared_ptr<PreloadSoStartupTask> & startupTask)377 int32_t StartupManager::RegisterPreloadSoStartupTask(
378     const std::string &name, const std::shared_ptr<PreloadSoStartupTask> &startupTask)
379 {
380     auto findResult = appStartupTasks_.find(name);
381     if (findResult != appStartupTasks_.end()) {
382         TAG_LOGE(AAFwkTag::STARTUP, "exist app startup task %{public}s", name.c_str());
383         return ERR_STARTUP_INVALID_VALUE;
384     }
385 
386     auto result = preloadSoStartupTasks_.emplace(name, startupTask);
387     if (!result.second) {
388         TAG_LOGE(AAFwkTag::STARTUP, "exist preload so startup task %{public}s", name.c_str());
389         return ERR_STARTUP_INVALID_VALUE;
390     }
391     return ERR_OK;
392 }
393 
RegisterAppStartupTask(const std::string & name,const std::shared_ptr<AppStartupTask> & startupTask)394 int32_t StartupManager::RegisterAppStartupTask(
395     const std::string &name, const std::shared_ptr<AppStartupTask> &startupTask)
396 {
397     auto findResult = preloadSoStartupTasks_.find(name);
398     if (findResult != preloadSoStartupTasks_.end()) {
399         TAG_LOGE(AAFwkTag::STARTUP, "exist preload so startup task %{public}s", name.c_str());
400         return ERR_STARTUP_INVALID_VALUE;
401     }
402 
403     auto result = appStartupTasks_.emplace(name, startupTask);
404     if (!result.second) {
405         TAG_LOGE(AAFwkTag::STARTUP, "exist app startup task %{public}s", name.c_str());
406         return ERR_STARTUP_INVALID_VALUE;
407     }
408     return ERR_OK;
409 }
410 
BuildStartupTaskManager(const std::map<std::string,std::shared_ptr<StartupTask>> & tasks,std::shared_ptr<StartupTaskManager> & startupTaskManager)411 int32_t StartupManager::BuildStartupTaskManager(const std::map<std::string, std::shared_ptr<StartupTask>> &tasks,
412     std::shared_ptr<StartupTaskManager> &startupTaskManager)
413 {
414     if (tasks.empty()) {
415         TAG_LOGE(AAFwkTag::STARTUP, "input tasks empty.");
416         return ERR_STARTUP_INTERNAL_ERROR;
417     }
418     std::lock_guard guard(startupTaskManagerMutex_);
419     startupTaskManager = std::make_shared<StartupTaskManager>(startupTaskManagerId, tasks);
420     if (startupTaskManager == nullptr) {
421         TAG_LOGE(AAFwkTag::STARTUP, "startupTaskManager is null.");
422         return ERR_STARTUP_INTERNAL_ERROR;
423     }
424     // does not time out and no complete callback
425     auto config = std::make_shared<StartupConfig>(StartupConfig::NO_AWAIT_TIMEOUT, nullptr);
426     startupTaskManager->SetConfig(config);
427     startupTaskManagerMap_.emplace(startupTaskManagerId, startupTaskManager);
428     TAG_LOGD(AAFwkTag::STARTUP, "build startup task manager, id: %{public}u, tasks num: %{public}zu",
429         startupTaskManagerId, tasks.size());
430     startupTaskManagerId++;
431     return ERR_OK;
432 }
433 
AddAppPreloadSoTask(const std::vector<std::string> & preloadSoList,std::map<std::string,std::shared_ptr<StartupTask>> & currentStartupTasks)434 int32_t StartupManager::AddAppPreloadSoTask(const std::vector<std::string> &preloadSoList,
435     std::map<std::string, std::shared_ptr<StartupTask>> &currentStartupTasks)
436 {
437     std::map<std::string, std::shared_ptr<StartupTask>> currentPreloadSoTasks;
438     std::set<std::string> dependenciesSet;
439     for (auto &iter : preloadSoList) {
440         auto findResult = preloadSoStartupTasks_.find(iter);
441         if (findResult == preloadSoStartupTasks_.end()) {
442             TAG_LOGE(AAFwkTag::STARTUP, "startup task %{public}s not found", iter.c_str());
443             return ERR_STARTUP_DEPENDENCY_NOT_FOUND;
444         }
445         if (findResult->second == nullptr) {
446             TAG_LOGE(AAFwkTag::STARTUP, "%{public}s startup task null", iter.c_str());
447             return ERR_STARTUP_INTERNAL_ERROR;
448         }
449         currentPreloadSoTasks.emplace(iter, findResult->second);
450         auto dependencies = findResult->second->GetDependencies();
451         for (auto &dep : dependencies) {
452             dependenciesSet.insert(dep);
453         }
454     }
455     for (auto &dep : dependenciesSet) {
456         if (currentPreloadSoTasks.find(dep) != currentPreloadSoTasks.end()) {
457             continue;
458         }
459         int32_t result = AddStartupTask(dep, currentPreloadSoTasks, preloadSoStartupTasks_);
460         if (result != ERR_OK) {
461             return result;
462         }
463     }
464     if (currentPreloadSoTasks.empty()) {
465         // no preload so tasks
466         return ERR_OK;
467     }
468     std::shared_ptr<NativeStartupTask> task = CreateAppPreloadSoTask(currentPreloadSoTasks);
469     if (task == nullptr) {
470         TAG_LOGE(AAFwkTag::STARTUP, "Failed to create load app startup config task");
471         return ERR_STARTUP_INTERNAL_ERROR;
472     }
473     task->SetCallCreateOnMainThread(true);
474     task->SetWaitOnMainThread(false);
475     currentStartupTasks.emplace(task->GetName(), task);
476     return ERR_OK;
477 }
478 
CreateAppPreloadSoTask(const std::map<std::string,std::shared_ptr<StartupTask>> & currentTasks)479 std::shared_ptr<NativeStartupTask> StartupManager::CreateAppPreloadSoTask(
480     const std::map<std::string, std::shared_ptr<StartupTask>> &currentTasks)
481 {
482     auto task = std::make_shared<NativeStartupTask>(APP_PRELOAD_SO_TASK,
483         [weak = weak_from_this(), currentTasks](std::unique_ptr<StartupTaskResultCallback> callback)-> int32_t {
484             auto self = weak.lock();
485             if (self == nullptr) {
486                 TAG_LOGE(AAFwkTag::STARTUP, "self is null");
487                 OnCompletedCallback::OnCallback(std::move(callback), ERR_STARTUP_INTERNAL_ERROR,
488                     "add preload so task failed");
489                 return ERR_STARTUP_INTERNAL_ERROR;
490             }
491             int32_t result = self->RunAppPreloadSoTaskMainThread(currentTasks, std::move(callback));
492             return result;
493         });
494     return task;
495 }
496 
PreloadAppHintStartupTask()497 void StartupManager::PreloadAppHintStartupTask()
498 {
499     std::map<std::string, std::shared_ptr<StartupTask>> preloadAppHintTasks;
500     int32_t result = AddLoadAppStartupConfigTask(preloadAppHintTasks);
501     if (result != ERR_OK) {
502         return;
503     }
504     result = AddAppAutoPreloadSoTask(preloadAppHintTasks);
505     if (result != ERR_OK) {
506         return;
507     }
508     std::shared_ptr<StartupTaskManager> startupTaskManager;
509     result = BuildStartupTaskManager(preloadAppHintTasks, startupTaskManager);
510     if (result != ERR_OK || startupTaskManager == nullptr) {
511         TAG_LOGE(AAFwkTag::STARTUP, "build preload startup task manager failed, result: %{public}d", result);
512         return;
513     }
514     result = startupTaskManager->Prepare();
515     if (result != ERR_OK) {
516         TAG_LOGE(AAFwkTag::STARTUP, "preload startup task manager prepare failed, result: %{public}d", result);
517         return;
518     }
519     TAG_LOGD(AAFwkTag::STARTUP, "preload startup task manager run");
520     startupTaskManager->Run(nullptr);
521 }
522 
AddLoadAppStartupConfigTask(std::map<std::string,std::shared_ptr<StartupTask>> & preloadAppHintTasks)523 int32_t StartupManager::AddLoadAppStartupConfigTask(
524     std::map<std::string, std::shared_ptr<StartupTask>> &preloadAppHintTasks)
525 {
526     auto task = std::make_shared<NativeStartupTask>(LOAD_APP_STARTUP_CONFIG_TASK,
527         [weak = weak_from_this()](std::unique_ptr<StartupTaskResultCallback> callback)-> int32_t {
528             auto self = weak.lock();
529             if (self == nullptr) {
530                 TAG_LOGE(AAFwkTag::STARTUP, "self is null");
531                 OnCompletedCallback::OnCallback(std::move(callback), ERR_STARTUP_INTERNAL_ERROR,
532                     "AddLoadAppStartupConfigTask failed");
533                 return ERR_STARTUP_INTERNAL_ERROR;
534             }
535             int32_t result = self->RunLoadAppStartupConfigTask();
536             OnCompletedCallback::OnCallback(std::move(callback), result);
537             return result;
538         });
539     if (task == nullptr) {
540         TAG_LOGE(AAFwkTag::STARTUP, "Failed to create load app startup config task");
541         return ERR_STARTUP_INTERNAL_ERROR;
542     }
543     task->SetCallCreateOnMainThread(true);
544     task->SetWaitOnMainThread(true);
545     // no dependencies
546     preloadAppHintTasks.emplace(task->GetName(), task);
547     return ERR_OK;
548 }
549 
RunLoadAppStartupConfigTask()550 int32_t StartupManager::RunLoadAppStartupConfigTask()
551 {
552     if (isAppStartupConfigInited_) {
553         TAG_LOGD(AAFwkTag::STARTUP, "module startup config already loaded");
554         return ERR_OK;
555     }
556 
557     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
558     std::map<std::string, std::shared_ptr<AppStartupTask>> preloadSoStartupTasks;
559     std::vector<StartupTaskInfo> pendingStartupTaskInfos;
560     std::string pendingConfigEntry;
561     for (const auto& item : moduleStartupConfigInfos_) {
562         if (item.startupConfig_.empty()) {
563             continue;
564         }
565         TAG_LOGD(AAFwkTag::STARTUP, "load module %{public}s, type: %{public}d", item.name_.c_str(), item.moduleType_);
566         std::string configStr;
567         int32_t result = GetStartupConfigString(item, configStr);
568         if (result != ERR_OK) {
569             return result;
570         }
571         bool success = AnalyzeStartupConfig(item, configStr,
572             preloadSoStartupTasks, pendingStartupTaskInfos, pendingConfigEntry);
573         if (!success) {
574             TAG_LOGE(AAFwkTag::STARTUP, "failed to parse app startup module %{public}s, type: %{public}d",
575                 item.name_.c_str(), item.moduleType_);
576             return ERR_STARTUP_CONFIG_PARSE_ERROR;
577         }
578     }
579 
580     std::lock_guard guard(appStartupConfigInitializationMutex_);
581     if (isAppStartupConfigInited_) {
582         // double check
583         TAG_LOGD(AAFwkTag::STARTUP, "module startup config already loaded");
584         return ERR_OK;
585     }
586     preloadSoStartupTasks_ = preloadSoStartupTasks;
587     pendingStartupTaskInfos_ = pendingStartupTaskInfos;
588     pendingConfigEntry_ = pendingConfigEntry;
589     isAppStartupConfigInited_ = true;
590     TAG_LOGI(AAFwkTag::STARTUP, "preload so: %{public}zu, app: %{public}zu",
591         preloadSoStartupTasks_.size(), pendingStartupTaskInfos_.size());
592     return ERR_OK;
593 }
594 
AddAppAutoPreloadSoTask(std::map<std::string,std::shared_ptr<StartupTask>> & preloadAppHintTasks)595 int32_t StartupManager::AddAppAutoPreloadSoTask(
596     std::map<std::string, std::shared_ptr<StartupTask>> &preloadAppHintTasks)
597 {
598     auto task = std::make_shared<NativeStartupTask>(APP_AUTO_PRELOAD_SO_TASK,
599         [weak = weak_from_this()](std::unique_ptr<StartupTaskResultCallback> callback)-> int32_t {
600             auto self = weak.lock();
601             if (self == nullptr) {
602                 TAG_LOGE(AAFwkTag::STARTUP, "self is null");
603                 OnCompletedCallback::OnCallback(std::move(callback), ERR_STARTUP_INTERNAL_ERROR,
604                     "AddAppAutoPreloadSoTask failed");
605                 return ERR_STARTUP_INTERNAL_ERROR;
606             }
607             int32_t result = self->RunAppAutoPreloadSoTask();
608             OnCompletedCallback::OnCallback(std::move(callback), result);
609             return result;
610         });
611     if (task == nullptr) {
612         TAG_LOGE(AAFwkTag::STARTUP, "Failed to create app preload so task");
613         return ERR_STARTUP_INTERNAL_ERROR;
614     }
615     task->SetCallCreateOnMainThread(true);
616     task->SetWaitOnMainThread(true);
617     task->SetDependencies({ LOAD_APP_STARTUP_CONFIG_TASK });
618     preloadAppHintTasks.emplace(task->GetName(), task);
619     return ERR_OK;
620 }
621 
RunAppAutoPreloadSoTask()622 int32_t StartupManager::RunAppAutoPreloadSoTask()
623 {
624     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
625     std::map<std::string, std::shared_ptr<StartupTask>> appAutoPreloadSoTasks;
626     int32_t result = GetAppAutoPreloadSoTasks(appAutoPreloadSoTasks);
627     if (result != ERR_OK) {
628         return result;
629     }
630     if (appAutoPreloadSoTasks.empty()) {
631         TAG_LOGD(AAFwkTag::STARTUP, "no preload so startup task");
632         return ERR_OK;
633     }
634 
635     return RunAppPreloadSoTask(appAutoPreloadSoTasks);
636 }
637 
RunAppPreloadSoTask(const std::map<std::string,std::shared_ptr<StartupTask>> & appPreloadSoTasks)638 int32_t StartupManager::RunAppPreloadSoTask(
639     const std::map<std::string, std::shared_ptr<StartupTask>> &appPreloadSoTasks)
640 {
641     std::shared_ptr<StartupTaskManager> startupTaskManager;
642     int32_t result = BuildStartupTaskManager(appPreloadSoTasks, startupTaskManager);
643     if (result != ERR_OK || startupTaskManager == nullptr) {
644         TAG_LOGE(AAFwkTag::STARTUP, "build preload so startup task manager failed, result: %{public}d", result);
645         return ERR_STARTUP_INTERNAL_ERROR;
646     }
647     {
648         std::lock_guard guard(autoPreloadSoTaskManagerMutex_);
649         if (autoPreloadSoStopped_) {
650             TAG_LOGI(AAFwkTag::STARTUP, "auto preload so is stopped, remove startupTaskManager");
651             startupTaskManager->OnTimeout();
652             return ERR_STARTUP_TIMEOUT;
653         }
654         autoPreloadSoTaskManager_ = startupTaskManager;
655     }
656 
657     result = startupTaskManager->Prepare();
658     if (result != ERR_OK) {
659         TAG_LOGE(AAFwkTag::STARTUP, "preload so startup task manager prepare failed, result: %{public}d", result);
660         return result;
661     }
662     TAG_LOGI(AAFwkTag::STARTUP, "preload so startup task manager count: %{public}zu", appPreloadSoTasks.size());
663     result = startupTaskManager->Run(nullptr);
664     if (result != ERR_OK) {
665         TAG_LOGE(AAFwkTag::STARTUP, "preload so startup task manager run failed, result: %{public}d", result);
666     }
667     return result;
668 }
669 
GetAppAutoPreloadSoTasks(std::map<std::string,std::shared_ptr<StartupTask>> & appAutoPreloadSoTasks)670 int32_t StartupManager::GetAppAutoPreloadSoTasks(
671     std::map<std::string, std::shared_ptr<StartupTask>> &appAutoPreloadSoTasks)
672 {
673     std::set<std::string> dependenciesSet;
674     for (const auto &iter : preloadSoStartupTasks_) {
675         if (iter.second == nullptr) {
676             continue;
677         }
678         if (iter.second->GetIsExcludeFromAutoStart()) {
679             continue;
680         }
681         appAutoPreloadSoTasks.emplace(iter.first, iter.second);
682         auto dependencies = iter.second->GetDependencies();
683         for (auto &dep : dependencies) {
684             dependenciesSet.insert(dep);
685         }
686     }
687     for (auto &dep : dependenciesSet) {
688         if (appAutoPreloadSoTasks.find(dep) != appAutoPreloadSoTasks.end()) {
689             continue;
690         }
691         TAG_LOGD(AAFwkTag::STARTUP, "try to add excludeFromAutoStart task: %{public}s", dep.c_str());
692         int32_t result = AddStartupTask(dep, appAutoPreloadSoTasks, preloadSoStartupTasks_);
693         if (result != ERR_OK) {
694             return result;
695         }
696     }
697     return ERR_OK;
698 }
699 
RunAppPreloadSoTaskMainThread(const std::map<std::string,std::shared_ptr<StartupTask>> & appPreloadSoTasks,std::unique_ptr<StartupTaskResultCallback> callback)700 int32_t StartupManager::RunAppPreloadSoTaskMainThread(
701     const std::map<std::string, std::shared_ptr<StartupTask>> &appPreloadSoTasks,
702     std::unique_ptr<StartupTaskResultCallback> callback)
703 {
704     std::shared_ptr<StartupTaskManager> startupTaskManager;
705     int32_t result = BuildStartupTaskManager(appPreloadSoTasks, startupTaskManager);
706     if (result != ERR_OK || startupTaskManager == nullptr) {
707         TAG_LOGE(AAFwkTag::STARTUP, "build preload so startup task manager failed, result: %{public}d", result);
708         OnCompletedCallback::OnCallback(std::move(callback), ERR_STARTUP_INTERNAL_ERROR,
709             "RunAppPreloadSoTaskMainThread build failed");
710         return ERR_STARTUP_INTERNAL_ERROR;
711     }
712 
713     result = startupTaskManager->Prepare();
714     if (result != ERR_OK) {
715         TAG_LOGE(AAFwkTag::STARTUP, "preload so startup task manager prepare failed, result: %{public}d", result);
716         OnCompletedCallback::OnCallback(std::move(callback), result,
717             "RunAppPreloadSoTaskMainThread prepare failed");
718         return result;
719     }
720     TAG_LOGI(AAFwkTag::STARTUP, "preload so startup task manager count: %{public}zu", appPreloadSoTasks.size());
721 
722     if (preloadHandler_ == nullptr) {
723         TAG_LOGE(AAFwkTag::STARTUP, "no preload thread");
724         OnCompletedCallback::OnCallback(std::move(callback), result,
725             "RunAppPreloadSoTaskMainThread no preload thread");
726         return ERR_STARTUP_INTERNAL_ERROR;
727     }
728     auto callbackInfo = std::make_shared<StartupTaskResultCallbackInfo>(std::move(callback));
729     std::shared_ptr<StartupListener> listener = std::make_shared<StartupListener>(
730         [callbackInfo, weak = weak_from_this()](const std::shared_ptr<StartupTaskResult> &result) {
731         auto self = weak.lock();
732         if (self == nullptr) {
733             TAG_LOGE(AAFwkTag::STARTUP, "self is null");
734             return;
735         }
736         self->PostMainThreadTask([callbackInfo, result]() {
737             if (callbackInfo == nullptr) {
738                 TAG_LOGE(AAFwkTag::STARTUP, "callbackInfo is null");
739                 return;
740             }
741             OnCompletedCallback::OnCallback(std::move(callbackInfo->callback_), result);
742         });
743     });
744     startupTaskManager->SetConfig(std::make_shared<StartupConfig>(listener));
745     preloadHandler_->PostTask([startupTaskManager]() {
746         int32_t result = startupTaskManager->Run(nullptr);
747         if (result != ERR_OK) {
748             TAG_LOGE(AAFwkTag::STARTUP, "preload so startup task manager run failed, result: %{public}d", result);
749         }
750     });
751     return ERR_OK;
752 }
753 
GetStartupConfigString(const ModuleStartupConfigInfo & info,std::string & config)754 int32_t StartupManager::GetStartupConfigString(const ModuleStartupConfigInfo &info, std::string &config)
755 {
756     TAG_LOGD(AAFwkTag::STARTUP, "start");
757     std::string appStartup = info.startupConfig_;
758     if (appStartup.empty()) {
759         TAG_LOGE(AAFwkTag::STARTUP, "appStartup invalid");
760         return ERR_STARTUP_CONFIG_NOT_FOUND;
761     }
762 
763     size_t pos = appStartup.rfind(PROFILE_FILE_PREFIX);
764     if ((pos == std::string::npos) || (pos == appStartup.length() - strlen(PROFILE_FILE_PREFIX))) {
765         TAG_LOGE(AAFwkTag::STARTUP, "appStartup %{public}s is invalid", appStartup.c_str());
766         return ERR_STARTUP_CONFIG_PATH_ERROR;
767     }
768     std::string profileName = appStartup.substr(pos + strlen(PROFILE_FILE_PREFIX));
769     std::string hapPath = info.hapPath_;
770     std::unique_ptr<uint8_t[]> startupConfig = nullptr;
771     size_t len = 0;
772     std::string profilePath = PROFILE_PATH + profileName + JSON_SUFFIX;
773     std::string loadPath = AbilityBase::ExtractorUtil::GetLoadFilePath(hapPath);
774     bool newCreate = false;
775     std::shared_ptr<AbilityBase::Extractor> extractor =
776         AbilityBase::ExtractorUtil::GetExtractor(loadPath, newCreate);
777     if (!extractor->ExtractToBufByName(profilePath, startupConfig, len)) {
778         TAG_LOGE(AAFwkTag::STARTUP, "failed to get startup config, profilePath: %{private}s, hapPath: %{private}s",
779             profilePath.c_str(), hapPath.c_str());
780         return ERR_STARTUP_CONFIG_PATH_ERROR;
781     }
782     std::string configData(startupConfig.get(), startupConfig.get() + len);
783     nlohmann::json profileJson = nlohmann::json::parse(configData, nullptr, false);
784     if (profileJson.is_discarded()) {
785         TAG_LOGE(AAFwkTag::STARTUP, "bad profile file");
786         return ERR_STARTUP_CONFIG_PARSE_ERROR;
787     }
788     config = profileJson.dump();
789     return ERR_OK;
790 }
791 
AnalyzeStartupConfig(const ModuleStartupConfigInfo & info,const std::string & startupConfig,std::map<std::string,std::shared_ptr<AppStartupTask>> & preloadSoStartupTasks,std::vector<StartupTaskInfo> & pendingStartupTaskInfos,std::string & pendingConfigEntry)792 bool StartupManager::AnalyzeStartupConfig(const ModuleStartupConfigInfo& info, const std::string& startupConfig,
793     std::map<std::string, std::shared_ptr<AppStartupTask>>& preloadSoStartupTasks,
794     std::vector<StartupTaskInfo>& pendingStartupTaskInfos, std::string& pendingConfigEntry)
795 {
796     if (startupConfig.empty()) {
797         TAG_LOGE(AAFwkTag::STARTUP, "startupConfig invalid");
798         return false;
799     }
800 
801     nlohmann::json startupConfigJson = nlohmann::json::parse(startupConfig, nullptr, false);
802     if (startupConfigJson.is_discarded()) {
803         TAG_LOGE(AAFwkTag::STARTUP, "Failed to parse json string");
804         return false;
805     }
806 
807     if (info.moduleType_ == AppExecFwk::ModuleType::ENTRY) {
808         if (!(startupConfigJson.contains(CONFIG_ENTRY) && startupConfigJson[CONFIG_ENTRY].is_string())) {
809             TAG_LOGE(AAFwkTag::STARTUP, "no config entry.");
810             return false;
811         }
812         pendingConfigEntry = startupConfigJson.at(CONFIG_ENTRY).get<std::string>();
813         if (pendingConfigEntry.empty()) {
814             TAG_LOGE(AAFwkTag::STARTUP, "startup config empty.");
815             return false;
816         }
817     }
818 
819     if (!AnalyzeAppStartupTask(info, startupConfigJson, pendingStartupTaskInfos)) {
820         return false;
821     }
822     if (!AnalyzePreloadSoStartupTask(info, startupConfigJson, preloadSoStartupTasks)) {
823         return false;
824     }
825     return true;
826 }
827 
AnalyzeAppStartupTask(const ModuleStartupConfigInfo & info,nlohmann::json & startupConfigJson,std::vector<StartupTaskInfo> & pendingStartupTaskInfos)828 bool StartupManager::AnalyzeAppStartupTask(const ModuleStartupConfigInfo& info, nlohmann::json &startupConfigJson,
829     std::vector<StartupTaskInfo>& pendingStartupTaskInfos)
830 {
831     if (startupConfigJson.contains(STARTUP_TASKS) && startupConfigJson[STARTUP_TASKS].is_array()) {
832         for (const auto& module : startupConfigJson.at(STARTUP_TASKS).get<nlohmann::json>()) {
833             if (!module.contains(SRC_ENTRY) || !module[SRC_ENTRY].is_string() ||
834             !module.contains(NAME) || !module[NAME].is_string()) {
835                 TAG_LOGE(AAFwkTag::STARTUP, "Invalid module data");
836                 return false;
837             }
838             int32_t result = AnalyzeAppStartupTaskInner(info, module, pendingStartupTaskInfos);
839             if (!result) {
840                 return false;
841             }
842         }
843         return true;
844     }
845     return true;
846 }
847 
AnalyzePreloadSoStartupTask(const ModuleStartupConfigInfo & info,nlohmann::json & startupConfigJson,std::map<std::string,std::shared_ptr<AppStartupTask>> & preloadSoStartupTasks)848 bool StartupManager::AnalyzePreloadSoStartupTask(const ModuleStartupConfigInfo& info, nlohmann::json &startupConfigJson,
849     std::map<std::string, std::shared_ptr<AppStartupTask>>& preloadSoStartupTasks)
850 {
851     if (startupConfigJson.contains(PRELOAD_STARTUP_TASKS) && startupConfigJson[PRELOAD_STARTUP_TASKS].is_array()) {
852         for (const auto& module : startupConfigJson.at(PRELOAD_STARTUP_TASKS).get<nlohmann::json>()) {
853             if (!module.contains(SRC_ENTRY) || !module[SRC_ENTRY].is_string() ||
854             !module.contains(NAME) || !module[NAME].is_string()) {
855                 TAG_LOGE(AAFwkTag::STARTUP, "Invalid module data");
856                 return false;
857             }
858             int32_t result = AnalyzePreloadSoStartupTaskInner(info, module, preloadSoStartupTasks);
859             if (!result) {
860                 return false;
861             }
862         }
863         return true;
864     }
865     return true;
866 }
867 
AnalyzeAppStartupTaskInner(const ModuleStartupConfigInfo & info,const nlohmann::json & startupTaskJson,std::vector<StartupTaskInfo> & pendingStartupTaskInfos)868 bool StartupManager::AnalyzeAppStartupTaskInner(const ModuleStartupConfigInfo& info,
869     const nlohmann::json& startupTaskJson,
870     std::vector<StartupTaskInfo>& pendingStartupTaskInfos)
871 {
872     if (!startupTaskJson.contains(SRC_ENTRY) || !startupTaskJson[SRC_ENTRY].is_string() ||
873         !startupTaskJson.contains(NAME) || !startupTaskJson[NAME].is_string()) {
874         TAG_LOGE(AAFwkTag::STARTUP, "Invalid startupTaskJson data");
875         return false;
876     }
877     StartupTaskInfo startupTaskInfo;
878     startupTaskInfo.moduleName = info.name_;
879     startupTaskInfo.hapPath = info.hapPath_;
880     startupTaskInfo.esModule = info.esModule_;
881 
882     startupTaskInfo.name = startupTaskJson.at(NAME).get<std::string>();
883     startupTaskInfo.srcEntry = startupTaskJson.at(SRC_ENTRY).get<std::string>();
884     if (startupTaskInfo.name.empty()) {
885         TAG_LOGE(AAFwkTag::STARTUP, "startup task name is empty");
886         return false;
887     }
888     if (startupTaskInfo.srcEntry.empty()) {
889         TAG_LOGE(AAFwkTag::STARTUP, "startup task %{public}s no srcEntry", startupTaskInfo.name.c_str());
890         return false;
891     }
892     SetOptionalParameters(startupTaskJson, info.moduleType_, startupTaskInfo);
893     pendingStartupTaskInfos.emplace_back(startupTaskInfo);
894     return true;
895 }
896 
AnalyzePreloadSoStartupTaskInner(const ModuleStartupConfigInfo & info,const nlohmann::json & preloadStartupTaskJson,std::map<std::string,std::shared_ptr<AppStartupTask>> & preloadSoStartupTasks)897 bool StartupManager::AnalyzePreloadSoStartupTaskInner(const ModuleStartupConfigInfo& info,
898     const nlohmann::json &preloadStartupTaskJson,
899     std::map<std::string, std::shared_ptr<AppStartupTask>>& preloadSoStartupTasks)
900 {
901     if (!preloadStartupTaskJson.contains(NAME) || !preloadStartupTaskJson[NAME].is_string() ||
902         !preloadStartupTaskJson.contains(OHMURL) || !preloadStartupTaskJson[OHMURL].is_string()) {
903         TAG_LOGE(AAFwkTag::STARTUP, "Invalid startupTaskJson data");
904         return false;
905     }
906 
907     std::string name = preloadStartupTaskJson.at(NAME).get<std::string>();
908     std::string ohmUrl = preloadStartupTaskJson.at(OHMURL).get<std::string>();
909     auto task = std::make_shared<PreloadSoStartupTask>(name, ohmUrl);
910     if (task == nullptr) {
911         TAG_LOGE(AAFwkTag::STARTUP, "task is null");
912         return false;
913     }
914 
915     SetOptionalParameters(preloadStartupTaskJson, info.moduleType_, task);
916     preloadSoStartupTasks.emplace(name, task);
917     return true;
918 }
919 
SetOptionalParameters(const nlohmann::json & module,AppExecFwk::ModuleType moduleType,StartupTaskInfo & startupTaskInfo)920 void StartupManager::SetOptionalParameters(const nlohmann::json& module, AppExecFwk::ModuleType moduleType,
921     StartupTaskInfo& startupTaskInfo)
922 {
923     if (module.contains(DEPENDENCIES) && module[DEPENDENCIES].is_array()) {
924         for (const auto& dependency : module.at(DEPENDENCIES)) {
925             if (dependency.is_string()) {
926                 startupTaskInfo.dependencies.push_back(dependency.get<std::string>());
927             }
928         }
929     }
930 
931     if (module.contains(RUN_ON_THREAD) && module[RUN_ON_THREAD].is_string()) {
932         std::string profileName = module.at(RUN_ON_THREAD).get<std::string>();
933         if (profileName == TASK_POOL || profileName == TASK_POOL_LOWER) {
934             startupTaskInfo.callCreateOnMainThread = false;
935         } else {
936             startupTaskInfo.callCreateOnMainThread = true;
937         }
938     }
939 
940     if (module.contains(WAIT_ON_MAIN_THREAD) && module[WAIT_ON_MAIN_THREAD].is_boolean()) {
941         startupTaskInfo.waitOnMainThread = module.at(WAIT_ON_MAIN_THREAD).get<bool>();
942     } else {
943         startupTaskInfo.waitOnMainThread = true;
944     }
945 
946     if (module.contains(OHMURL) && module[OHMURL].is_string()) {
947         startupTaskInfo.ohmUrl = module.at(OHMURL).get<std::string>();
948     }
949 
950     if (moduleType != AppExecFwk::ModuleType::ENTRY) {
951         startupTaskInfo.excludeFromAutoStart = true;
952         return;
953     }
954     if (module.contains(EXCLUDE_FROM_AUTO_START) && module[EXCLUDE_FROM_AUTO_START].is_boolean()) {
955         startupTaskInfo.excludeFromAutoStart = module.at(EXCLUDE_FROM_AUTO_START).get<bool>();
956     } else {
957         startupTaskInfo.excludeFromAutoStart = false;
958     }
959 }
960 
SetOptionalParameters(const nlohmann::json & module,AppExecFwk::ModuleType moduleType,std::shared_ptr<PreloadSoStartupTask> & task)961 void StartupManager::SetOptionalParameters(const nlohmann::json &module, AppExecFwk::ModuleType moduleType,
962     std::shared_ptr<PreloadSoStartupTask> &task)
963 {
964     if (module.contains(DEPENDENCIES) && module[DEPENDENCIES].is_array()) {
965         std::vector<std::string> dependencies;
966         for (const auto& dependency : module.at(DEPENDENCIES)) {
967             if (dependency.is_string()) {
968                 dependencies.push_back(dependency.get<std::string>());
969             }
970         }
971         task->SetDependencies(dependencies);
972     }
973 
974     if (moduleType != AppExecFwk::ModuleType::ENTRY) {
975         task->SetIsExcludeFromAutoStart(true);
976         return;
977     }
978     if (module.contains(EXCLUDE_FROM_AUTO_START) && module[EXCLUDE_FROM_AUTO_START].is_boolean()) {
979         task->SetIsExcludeFromAutoStart(module.at(EXCLUDE_FROM_AUTO_START).get<bool>());
980     } else {
981         task->SetIsExcludeFromAutoStart(false);
982     }
983 }
984 } // namespace AbilityRuntime
985 } // namespace OHOS
986