• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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