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
20 #include "hilog_tag_wrapper.h"
21
22 namespace OHOS {
23 namespace AbilityRuntime {
StartupManager()24 StartupManager::StartupManager()
25 {
26 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
27 }
28
29 StartupManager::~StartupManager() = default;
30
RegisterStartupTask(const std::string & name,const std::shared_ptr<StartupTask> & startupTask)31 int32_t StartupManager::RegisterStartupTask(const std::string &name, const std::shared_ptr<StartupTask> &startupTask)
32 {
33 auto result = startupTasks_.emplace(name, startupTask);
34 if (!result.second) {
35 TAG_LOGE(AAFwkTag::STARTUP, "%{public}s exist", name.c_str());
36 return ERR_STARTUP_INVALID_VALUE;
37 }
38 return ERR_OK;
39 }
40
BuildAutoStartupTaskManager(std::shared_ptr<StartupTaskManager> & startupTaskManager)41 int32_t StartupManager::BuildAutoStartupTaskManager(std::shared_ptr<StartupTaskManager> &startupTaskManager)
42 {
43 std::map<std::string, std::shared_ptr<StartupTask>> autoStartupTasks;
44 std::set<std::string> dependenciesSet;
45 for (auto &iter : startupTasks_) {
46 if (iter.second == nullptr) {
47 TAG_LOGE(AAFwkTag::STARTUP, "startup task null");
48 return ERR_STARTUP_INTERNAL_ERROR;
49 }
50 if (iter.second->GetIsExcludeFromAutoStart()) {
51 continue;
52 }
53 autoStartupTasks.emplace(iter.first, iter.second);
54 auto dependencies = iter.second->GetDependencies();
55 for (auto &dep : dependencies) {
56 dependenciesSet.insert(dep);
57 }
58 }
59 for (auto &dep : dependenciesSet) {
60 if (autoStartupTasks.find(dep) != autoStartupTasks.end()) {
61 continue;
62 }
63 TAG_LOGI(AAFwkTag::STARTUP, "try to add excludeFromAutoStart task: %{public}s", dep.c_str());
64 AddStartupTask(dep, autoStartupTasks);
65 }
66
67 TAG_LOGD(AAFwkTag::STARTUP, "autoStartupTasksManager build, id: %{public}u, tasks num: %{public}zu",
68 startupTaskManagerId, autoStartupTasks.size());
69 startupTaskManager = std::make_shared<StartupTaskManager>(startupTaskManagerId, autoStartupTasks);
70 startupTaskManager->SetConfig(defaultConfig_);
71 startupTaskManagerMap_.emplace(startupTaskManagerId, startupTaskManager);
72 startupTaskManagerId++;
73 return ERR_OK;
74 }
75
BuildStartupTaskManager(const std::vector<std::string> & inputDependencies,std::shared_ptr<StartupTaskManager> & startupTaskManager)76 int32_t StartupManager::BuildStartupTaskManager(const std::vector<std::string> &inputDependencies,
77 std::shared_ptr<StartupTaskManager> &startupTaskManager)
78 {
79 std::map<std::string, std::shared_ptr<StartupTask>> currentStartupTasks;
80 std::set<std::string> dependenciesSet;
81 for (auto &iter : inputDependencies) {
82 auto findResult = startupTasks_.find(iter);
83 if (findResult == startupTasks_.end()) {
84 TAG_LOGE(AAFwkTag::STARTUP, "startup task %{public}s not found", iter.c_str());
85 return ERR_STARTUP_DEPENDENCY_NOT_FOUND;
86 }
87 if (findResult->second == nullptr) {
88 TAG_LOGE(AAFwkTag::STARTUP, "%{public}s startup task null", iter.c_str());
89 return ERR_STARTUP_INTERNAL_ERROR;
90 }
91 currentStartupTasks.emplace(iter, findResult->second);
92 auto dependencies = findResult->second->GetDependencies();
93 for (auto &dep : dependencies) {
94 dependenciesSet.insert(dep);
95 }
96 }
97
98 for (auto &dep : dependenciesSet) {
99 if (currentStartupTasks.find(dep) != currentStartupTasks.end()) {
100 continue;
101 }
102 AddStartupTask(dep, currentStartupTasks);
103 }
104 TAG_LOGD(AAFwkTag::STARTUP, "startupTasksManager build, id: %{public}u, tasks num: %{public}zu",
105 startupTaskManagerId, currentStartupTasks.size());
106 startupTaskManager = std::make_shared<StartupTaskManager>(startupTaskManagerId, currentStartupTasks);
107 startupTaskManager->SetConfig(defaultConfig_);
108 startupTaskManagerMap_.emplace(startupTaskManagerId, startupTaskManager);
109 startupTaskManagerId++;
110 return ERR_OK;
111 }
112
OnStartupTaskManagerComplete(uint32_t id)113 int32_t StartupManager::OnStartupTaskManagerComplete(uint32_t id)
114 {
115 auto result = startupTaskManagerMap_.find(id);
116 if (result == startupTaskManagerMap_.end()) {
117 TAG_LOGE(AAFwkTag::STARTUP, "StartupTaskManager id: %{public}u not found", id);
118 return ERR_STARTUP_INTERNAL_ERROR;
119 }
120 TAG_LOGD(AAFwkTag::STARTUP, "erase StartupTaskManager id: %{public}u", id);
121 startupTaskManagerMap_.erase(result);
122 return ERR_OK;
123 }
124
SetDefaultConfig(const std::shared_ptr<StartupConfig> & config)125 void StartupManager::SetDefaultConfig(const std::shared_ptr<StartupConfig> &config)
126 {
127 defaultConfig_ = config;
128 }
129
GetDefaultConfig() const130 const std::shared_ptr<StartupConfig>& StartupManager::GetDefaultConfig() const
131 {
132 return defaultConfig_;
133 }
134
RemoveAllResult()135 int32_t StartupManager::RemoveAllResult()
136 {
137 TAG_LOGD(AAFwkTag::STARTUP, "called");
138 for (auto &iter : startupTasks_) {
139 if (iter.second != nullptr) {
140 iter.second->RemoveResult();
141 }
142 }
143 return ERR_OK;
144 }
145
RemoveResult(const std::string & name)146 int32_t StartupManager::RemoveResult(const std::string &name)
147 {
148 TAG_LOGD(AAFwkTag::STARTUP, "called, name: %{public}s", name.c_str());
149 auto findResult = startupTasks_.find(name);
150 if (findResult == startupTasks_.end() || findResult->second == nullptr) {
151 TAG_LOGE(AAFwkTag::STARTUP, "%{public}s not found", name.c_str());
152 return ERR_STARTUP_INVALID_VALUE;
153 }
154 return findResult->second->RemoveResult();
155 }
156
GetResult(const std::string & name,std::shared_ptr<StartupTaskResult> & result)157 int32_t StartupManager::GetResult(const std::string &name, std::shared_ptr<StartupTaskResult> &result)
158 {
159 TAG_LOGD(AAFwkTag::STARTUP, "called, name: %{public}s", name.c_str());
160 auto findResult = startupTasks_.find(name);
161 if (findResult == startupTasks_.end() || findResult->second == nullptr) {
162 TAG_LOGE(AAFwkTag::STARTUP, "%{public}s not found", name.c_str());
163 return ERR_STARTUP_INVALID_VALUE;
164 }
165 StartupTask::State state = findResult->second->GetState();
166 if (state != StartupTask::State::INITIALIZED) {
167 TAG_LOGE(AAFwkTag::STARTUP, "%{public}s not initialized", name.c_str());
168 return ERR_STARTUP_INVALID_VALUE;
169 }
170 result = findResult->second->GetResult();
171 return ERR_OK;
172 }
173
IsInitialized(const std::string & name,bool & isInitialized)174 int32_t StartupManager::IsInitialized(const std::string &name, bool &isInitialized)
175 {
176 TAG_LOGD(AAFwkTag::STARTUP, "called, name: %{public}s", name.c_str());
177 auto findResult = startupTasks_.find(name);
178 if (findResult == startupTasks_.end() || findResult->second == nullptr) {
179 TAG_LOGE(AAFwkTag::STARTUP, "%{public}s, not found", name.c_str());
180 return ERR_STARTUP_INVALID_VALUE;
181 }
182 StartupTask::State state = findResult->second->GetState();
183 isInitialized = state == StartupTask::State::INITIALIZED;
184 return ERR_OK;
185 }
186
PostMainThreadTask(const std::function<void ()> & task)187 int32_t StartupManager::PostMainThreadTask(const std::function<void()> &task)
188 {
189 if (mainHandler_ == nullptr) {
190 TAG_LOGE(AAFwkTag::STARTUP, "get mainHandler failed");
191 return ERR_STARTUP_INTERNAL_ERROR;
192 }
193 mainHandler_->PostTask(task);
194 return ERR_OK;
195 }
196
AddStartupTask(const std::string & name,std::map<std::string,std::shared_ptr<StartupTask>> & taskMap)197 int32_t StartupManager::AddStartupTask(const std::string &name,
198 std::map<std::string, std::shared_ptr<StartupTask>> &taskMap)
199 {
200 auto isAdded = taskMap.find(name);
201 if (isAdded != taskMap.end()) {
202 // already added
203 return ERR_OK;
204 }
205 std::stack<std::string> taskStack;
206 taskStack.push(name);
207 while (!taskStack.empty()) {
208 auto taskName = taskStack.top();
209 taskStack.pop();
210 auto findResult = startupTasks_.find(taskName);
211 if (findResult == startupTasks_.end()) {
212 TAG_LOGE(AAFwkTag::STARTUP, "startup task not found %{public}s", taskName.c_str());
213 return ERR_STARTUP_DEPENDENCY_NOT_FOUND;
214 }
215 taskMap.emplace(taskName, findResult->second);
216 if (findResult->second == nullptr) {
217 TAG_LOGE(AAFwkTag::STARTUP, "null task:%{public}s", taskName.c_str());
218 return ERR_STARTUP_INTERNAL_ERROR;
219 }
220 auto dependencies = findResult->second->GetDependencies();
221 for (auto &dep : dependencies) {
222 if (taskMap.find(dep) == taskMap.end()) {
223 taskStack.push(dep);
224 }
225 }
226 }
227 return ERR_OK;
228 }
229 } // namespace AbilityRuntime
230 } // namespace OHOS
231