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>> ¤tStartupTasks)
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>> ¤tTasks)
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