1 /*
2 * Copyright (c) 2021 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 "kernal_system_app_manager.h"
17 #include "hilog_wrapper.h"
18 #include "ability_util.h"
19 #include "ability_manager_errors.h"
20 #include "ability_manager_service.h"
21 #include "app_scheduler.h"
22
23 namespace OHOS {
24 namespace AAFwk {
KernalSystemAppManager(int userId)25 KernalSystemAppManager::KernalSystemAppManager(int userId) : userId_(userId)
26 {}
27
~KernalSystemAppManager()28 KernalSystemAppManager::~KernalSystemAppManager()
29 {}
30
StartAbility(const AbilityRequest & abilityRequest)31 int KernalSystemAppManager::StartAbility(const AbilityRequest &abilityRequest)
32 {
33 HILOG_INFO("start kernal systerm ability.");
34 std::lock_guard<std::recursive_mutex> guard(stackLock_);
35 if (!waittingAbilityQueue_.empty()) {
36 HILOG_INFO("waiting queue is not empty, so enqueue systerm ui ability for waiting.");
37 EnqueueWaittingAbility(abilityRequest);
38 return START_ABILITY_WAITING;
39 }
40
41 std::shared_ptr<AbilityRecord> topAbilityRecord = GetCurrentTopAbility();
42 auto requestFlag = GetFlagOfAbility(abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name);
43 if (topAbilityRecord != nullptr) {
44 auto topFlag =
45 GetFlagOfAbility(topAbilityRecord->GetAbilityInfo().bundleName, topAbilityRecord->GetAbilityInfo().name);
46 if (topFlag == requestFlag && topAbilityRecord->GetAbilityState() == INITIAL) {
47 HILOG_INFO("top systerm ui ability need to restart.");
48 }
49 if (topAbilityRecord->GetAbilityState() == ACTIVATING) {
50 HILOG_INFO("top systerm ui ability is not active, so enqueue ability for waiting.");
51 EnqueueWaittingAbility(abilityRequest);
52 return START_ABILITY_WAITING;
53 }
54 }
55
56 return StartAbilityLocked(abilityRequest);
57 }
58
StartAbilityLocked(const AbilityRequest & abilityRequest)59 int KernalSystemAppManager::StartAbilityLocked(const AbilityRequest &abilityRequest)
60 {
61 std::shared_ptr<AbilityRecord> targetAbility;
62 GetOrCreateAbilityRecord(abilityRequest, targetAbility);
63 CHECK_POINTER_AND_RETURN(targetAbility, ERR_INVALID_VALUE);
64 targetAbility->SetKernalSystemAbility();
65
66 HILOG_INFO("Load kernal system ability, bundleName:%{public}s , abilityName:%{public}s",
67 abilityRequest.abilityInfo.bundleName.c_str(),
68 abilityRequest.abilityInfo.name.c_str());
69
70 if (targetAbility->IsAbilityState(AbilityState::ACTIVE) ||
71 targetAbility->IsAbilityState(AbilityState::ACTIVATING)) {
72 HILOG_INFO("kernal system ability is already activing or activated.");
73 targetAbility->Activate();
74 return ERR_OK;
75 }
76 return targetAbility->LoadAbility();
77 }
78
AttachAbilityThread(const sptr<IAbilityScheduler> & scheduler,const sptr<IRemoteObject> & token)79 int KernalSystemAppManager::AttachAbilityThread(
80 const sptr<IAbilityScheduler> &scheduler, const sptr<IRemoteObject> &token)
81 {
82 HILOG_INFO("Attach ability thread.");
83 std::lock_guard<std::recursive_mutex> guard(stackLock_);
84 auto abilityRecord = GetAbilityRecordByToken(token);
85 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
86
87 std::string flag = KernalSystemAppManager::GetFlagOfAbility(
88 abilityRecord->GetAbilityInfo().bundleName, abilityRecord->GetAbilityInfo().name);
89 HILOG_INFO("ability: %{public}s", flag.c_str());
90
91 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
92 CHECK_POINTER_AND_RETURN(handler, ERR_INVALID_VALUE);
93
94 handler->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecord->GetEventId());
95
96 abilityRecord->SetScheduler(scheduler);
97 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForground(token);
98
99 return ERR_OK;
100 }
101
OnAbilityRequestDone(const sptr<IRemoteObject> & token,const int32_t state)102 void KernalSystemAppManager::OnAbilityRequestDone(const sptr<IRemoteObject> &token, const int32_t state)
103 {
104 HILOG_INFO("On ability request done.");
105 std::lock_guard<std::recursive_mutex> guard(stackLock_);
106 AppAbilityState abilitState = DelayedSingleton<AppScheduler>::GetInstance()->ConvertToAppAbilityState(state);
107 if (abilitState == AppAbilityState::ABILITY_STATE_FOREGROUND) {
108 auto abilityRecord = GetAbilityRecordByToken(token);
109 CHECK_POINTER(abilityRecord);
110 abilityRecord->Activate();
111 }
112 }
113
OnAppStateChanged(const AppInfo & info)114 void KernalSystemAppManager::OnAppStateChanged(const AppInfo &info)
115 {
116 std::lock_guard<std::recursive_mutex> guard(stackLock_);
117 for (auto ability : abilities_) {
118 if (ability && ability->GetApplicationInfo().name == info.appName &&
119 (info.processName == ability->GetAbilityInfo().process ||
120 info.processName == ability->GetApplicationInfo().bundleName)) {
121 ability->SetAppState(info.state);
122 }
123 }
124 }
125
AbilityTransitionDone(const sptr<IRemoteObject> & token,int state)126 int KernalSystemAppManager::AbilityTransitionDone(const sptr<IRemoteObject> &token, int state)
127 {
128 HILOG_INFO("Ability transition done.");
129 std::lock_guard<std::recursive_mutex> guard(stackLock_);
130 auto abilityRecord = GetAbilityRecordByToken(token);
131 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
132
133 std::string flag = KernalSystemAppManager::GetFlagOfAbility(
134 abilityRecord->GetAbilityInfo().bundleName, abilityRecord->GetAbilityInfo().name);
135 int targetState = AbilityRecord::ConvertLifeCycleToAbilityState(static_cast<AbilityLifeCycleState>(state));
136 std::string abilityState = AbilityRecord::ConvertAbilityState(static_cast<AbilityState>(targetState));
137 HILOG_INFO("ability: %{public}s, state: %{public}s", flag.c_str(), abilityState.c_str());
138
139 switch (targetState) {
140 case AbilityState::ACTIVE: {
141 return DispatchActive(abilityRecord, targetState);
142 }
143 default: {
144 HILOG_WARN("don't support transiting state: %d", targetState);
145 return ERR_INVALID_VALUE;
146 }
147 }
148 }
149
DispatchActive(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)150 int KernalSystemAppManager::DispatchActive(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
151 {
152 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
153 CHECK_POINTER_AND_RETURN(handler, ERR_INVALID_VALUE);
154 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
155
156 if (!abilityRecord->IsAbilityState(AbilityState::ACTIVATING)) {
157 HILOG_ERROR("kernal ability transition life state error. start:%{public}d", state);
158 return ERR_INVALID_VALUE;
159 }
160 handler->RemoveEvent(AbilityManagerService::ACTIVE_TIMEOUT_MSG, abilityRecord->GetEventId());
161
162 auto task = [kernalManager = shared_from_this(), abilityRecord]() { kernalManager->CompleteActive(abilityRecord); };
163 handler->PostTask(task);
164 return ERR_OK;
165 }
166
CompleteActive(const std::shared_ptr<AbilityRecord> & abilityRecord)167 void KernalSystemAppManager::CompleteActive(const std::shared_ptr<AbilityRecord> &abilityRecord)
168 {
169 HILOG_INFO("Complete active.");
170 std::lock_guard<std::recursive_mutex> guard(stackLock_);
171 abilityRecord->SetAbilityState(AbilityState::ACTIVE);
172
173 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
174 CHECK_POINTER(handler);
175
176 auto task = [kernalManager = shared_from_this()]() { kernalManager->DequeueWaittingAbility(); };
177 handler->PostTask(task, "DequeueWaittingAbility");
178 }
179
GetOrCreateAbilityRecord(const AbilityRequest & abilityRequest,std::shared_ptr<AbilityRecord> & targetAbility)180 void KernalSystemAppManager::GetOrCreateAbilityRecord(
181 const AbilityRequest &abilityRequest, std::shared_ptr<AbilityRecord> &targetAbility)
182 {
183 std::string abilityFlag = KernalSystemAppManager::GetFlagOfAbility(
184 abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name);
185 auto isExist = [targetFlag = abilityFlag](const std::shared_ptr<AbilityRecord> &ability) {
186 if (ability == nullptr) {
187 return false;
188 }
189 return KernalSystemAppManager::GetFlagOfAbility(
190 ability->GetAbilityInfo().bundleName,
191 ability->GetAbilityInfo().name) == targetFlag;
192 };
193 auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist);
194 if (iter != abilities_.end()) {
195 targetAbility = *iter;
196 targetAbility->SetWant(abilityRequest.want);
197 targetAbility->SetIsNewWant(true);
198 return;
199 }
200 targetAbility = AbilityRecord::CreateAbilityRecord(abilityRequest);
201 auto configSptr = std::make_shared<DummyConfiguration>();
202 targetAbility->SetConfiguration(configSptr);
203 abilities_.push_front(targetAbility);
204 }
205
GetFlagOfAbility(const std::string & bundleName,const std::string & abilityName)206 std::string KernalSystemAppManager::GetFlagOfAbility(const std::string &bundleName, const std::string &abilityName)
207 {
208 return bundleName + ":" + abilityName;
209 }
210
GetManagerUserId() const211 int KernalSystemAppManager::GetManagerUserId() const
212 {
213 return userId_;
214 }
215
GetCurrentTopAbility() const216 std::shared_ptr<AbilityRecord> KernalSystemAppManager::GetCurrentTopAbility() const
217 {
218 if (abilities_.empty()) {
219 return nullptr;
220 }
221 return abilities_.front();
222 }
223
GetAbilityRecordByToken(const sptr<IRemoteObject> & token)224 std::shared_ptr<AbilityRecord> KernalSystemAppManager::GetAbilityRecordByToken(const sptr<IRemoteObject> &token)
225 {
226 std::lock_guard<std::recursive_mutex> guard(stackLock_);
227 auto abilityToFind = Token::GetAbilityRecordByToken(token);
228 CHECK_POINTER_AND_RETURN(abilityToFind, nullptr);
229
230 auto isExist = [targetAbility = abilityToFind](const std::shared_ptr<AbilityRecord> &ability) {
231 if (ability == nullptr) {
232 return false;
233 }
234 return targetAbility == ability;
235 };
236 auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist);
237 if (iter != abilities_.end()) {
238 return *iter;
239 }
240
241 return nullptr;
242 }
243
GetAbilityRecordByEventId(const int64_t eventId) const244 std::shared_ptr<AbilityRecord> KernalSystemAppManager::GetAbilityRecordByEventId(const int64_t eventId) const
245 {
246 auto isExist = [targetEventId = eventId](const std::shared_ptr<AbilityRecord> &ability) {
247 if (ability == nullptr) {
248 return false;
249 }
250 return (ability->GetEventId() == targetEventId);
251 };
252 auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist);
253 if (iter != abilities_.end()) {
254 return *iter;
255 }
256 return nullptr;
257 }
258
RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)259 bool KernalSystemAppManager::RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)
260 {
261 CHECK_POINTER_RETURN_BOOL(ability);
262 for (auto iter = abilities_.begin(); iter != abilities_.end(); iter++) {
263 if ((*iter) == ability) {
264 abilities_.erase(iter);
265 return true;
266 }
267 }
268 HILOG_ERROR("can not find ability");
269 return false;
270 }
271
EnqueueWaittingAbility(const AbilityRequest & abilityRequest)272 void KernalSystemAppManager::EnqueueWaittingAbility(const AbilityRequest &abilityRequest)
273 {
274 waittingAbilityQueue_.push(abilityRequest);
275 return;
276 }
277
DequeueWaittingAbility()278 void KernalSystemAppManager::DequeueWaittingAbility()
279 {
280 std::lock_guard<std::recursive_mutex> guard(stackLock_);
281 std::shared_ptr<AbilityRecord> topAbility = GetCurrentTopAbility();
282 if (topAbility != nullptr && topAbility->GetAbilityState() != ACTIVE) {
283 HILOG_INFO("top ability is not active, must return for waiting again");
284 return;
285 }
286 if (!waittingAbilityQueue_.empty()) {
287 AbilityRequest abilityRequest = waittingAbilityQueue_.front();
288 waittingAbilityQueue_.pop();
289 HILOG_INFO("bundleName: %{public}s, abilityName: %{public}s",
290 abilityRequest.abilityInfo.bundleName.c_str(),
291 abilityRequest.abilityInfo.name.c_str());
292
293 StartAbilityLocked(abilityRequest);
294 }
295 }
DumpState(std::vector<std::string> & info)296 void KernalSystemAppManager::DumpState(std::vector<std::string> &info)
297 {
298 info.emplace_back("SystemUIRecords:");
299 for (auto &ability : abilities_) {
300 ability->Dump(info);
301 }
302 }
303
OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)304 void KernalSystemAppManager::OnAbilityDied(std::shared_ptr<AbilityRecord> abilityRecord)
305 {
306 std::lock_guard<std::recursive_mutex> guard(stackLock_);
307 CHECK_POINTER(abilityRecord);
308 if (!abilityRecord->IsKernalSystemAbility()) {
309 HILOG_ERROR("System UI on scheduler died, ability type is not system ui");
310 return;
311 }
312
313 if (GetAbilityRecordByToken(abilityRecord->GetToken()) == nullptr) {
314 HILOG_ERROR("System UI on scheduler died, record is not exist.");
315 return;
316 }
317 auto ams = DelayedSingleton<AbilityManagerService>::GetInstance();
318 CHECK_POINTER(ams);
319
320 auto handler = ams->GetEventHandler();
321 CHECK_POINTER(handler);
322
323 HILOG_INFO("System UI on scheduler died: '%{public}s'", abilityRecord->GetAbilityInfo().name.c_str());
324 std::string name = abilityRecord->GetAbilityInfo().name;
325 abilityRecord->SetAbilityState(AbilityState::INITIAL);
326 auto timeoutTask = [ams, abilityRecord]() {
327 if (abilityRecord) {
328 ams->StartSystemUi(abilityRecord->GetAbilityInfo().name);
329 }
330 };
331 handler->PostTask(timeoutTask, "SystemUi_Die_" + name, AbilityManagerService::RESTART_TIMEOUT);
332 }
OnTimeOut(uint32_t msgId,int64_t eventId)333 void KernalSystemAppManager::OnTimeOut(uint32_t msgId, int64_t eventId)
334 {
335 std::lock_guard<std::recursive_mutex> guard(stackLock_);
336 if (abilities_.empty()) {
337 HILOG_ERROR("System UI on time out event: ability stack is empty.");
338 return;
339 }
340
341 auto abilityRecord = GetAbilityRecordByEventId(eventId);
342 CHECK_POINTER(abilityRecord);
343
344 auto ams = DelayedSingleton<AbilityManagerService>::GetInstance();
345 CHECK_POINTER(ams);
346
347 auto handler = ams->GetEventHandler();
348 CHECK_POINTER(handler);
349
350 switch (msgId) {
351 case AbilityManagerService::LOAD_TIMEOUT_MSG:
352 case AbilityManagerService::ACTIVE_TIMEOUT_MSG: {
353 std::string bundleName = abilityRecord->GetAbilityInfo().bundleName;
354 std::string name = abilityRecord->GetAbilityInfo().name;
355 RemoveAbilityRecord(abilityRecord);
356 auto task = [ams, bundleName]() {
357 ams->KillProcess(bundleName);
358 HILOG_ERROR("System UI on time out event: KillProcess:%{public}s", bundleName.c_str());
359 };
360 handler->PostTask(task);
361 auto timeoutTask = [ams, name]() {
362 ams->StartSystemUi(name);
363 HILOG_ERROR("System UI on time out event: restart:%{public}s", name.c_str());
364 };
365 handler->PostTask(timeoutTask, "SystemUi_Timeout_" + name, AbilityManagerService::RESTART_TIMEOUT);
366 break;
367 }
368 default:
369 break;
370 }
371 }
372
UpdateConfiguration(const DummyConfiguration & config)373 int KernalSystemAppManager::UpdateConfiguration(const DummyConfiguration &config)
374 {
375 std::lock_guard<std::recursive_mutex> guard(stackLock_);
376 std::shared_ptr<DummyConfiguration> configPtr = std::make_shared<DummyConfiguration>(config);
377 for (auto &ability : abilities_) {
378 if (ability) {
379 if (ability->IsAbilityState(AbilityState::ACTIVE)) {
380 HILOG_DEBUG("system ui update configuration.");
381 ability->ForceProcessConfigurationChange(configPtr);
382 }
383 }
384 }
385 return ERR_OK;
386 }
387
RestartAbility(const std::shared_ptr<AbilityRecord> abilityRecord)388 void KernalSystemAppManager::RestartAbility(const std::shared_ptr<AbilityRecord> abilityRecord)
389 {
390 CHECK_POINTER(abilityRecord);
391 HILOG_DEBUG("Restart ability system ui. %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
392 return;
393 }
394 } // namespace AAFwk
395 } // namespace OHOS