• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <algorithm>
17 
18 #include "ability_death_recipient.h"
19 #include "datetime_ex.h"
20 #include "ipc_skeleton.h"
21 #include "memory_guard.h"
22 #ifdef RESSCHED_ENABLE
23 #include "res_sched_client.h"
24 #endif
25 #include "sam_log.h"
26 #include "string_ex.h"
27 #include "system_ability_manager.h"
28 #include "schedule/system_ability_state_scheduler.h"
29 
30 namespace OHOS {
31 namespace {
32 constexpr int64_t RESTART_TIME_INTERVAL_LIMIT = 20 * 1000;
33 constexpr int32_t RESTART_TIMES_LIMIT = 4;
34 constexpr int32_t MAX_SUBSCRIBE_COUNT = 256;
35 constexpr int32_t UNLOAD_TIMEOUT_TIME = 5 * 1000;
36 const std::string LOCAL_DEVICE = "local";
37 constexpr int32_t MAX_DELAY_TIME = 5 * 60 * 1000;
38 constexpr const char* CANCEL_UNLOAD = "cancelUnload";
39 const std::string KEY_EVENT_ID = "eventId";
40 const std::string KEY_NAME = "name";
41 const std::string KEY_VALUE = "value";
42 const std::string KEY_EXTRA_DATA_ID = "extraDataId";
43 const std::string KEY_UNLOAD_TIMEOUT = "unloadTimeout";
44 }
Init(const std::list<SaProfile> & saProfiles)45 void SystemAbilityStateScheduler::Init(const std::list<SaProfile>& saProfiles)
46 {
47     HILOGI("[SA Scheduler] init start");
48     InitStateContext(saProfiles);
49     processListenerDeath_ = sptr<IRemoteObject::DeathRecipient>(new SystemProcessListenerDeathRecipient());
50     auto unloadRunner = AppExecFwk::EventRunner::Create("UnloadHandler");
51     unloadEventHandler_ = std::make_shared<UnloadEventHandler>(unloadRunner, weak_from_this());
52     unloadEventHandler_->PostTask([]() { Samgr::MemoryGuard cacheGuard; });
53 
54     auto listener =  std::dynamic_pointer_cast<SystemAbilityStateListener>(shared_from_this());
55     stateMachine_ = std::make_shared<SystemAbilityStateMachine>(listener);
56     stateEventHandler_ = std::make_shared<SystemAbilityEventHandler>(stateMachine_);
57 
58     auto processRunner = AppExecFwk::EventRunner::Create("ProcessHandler");
59     processHandler_ = std::make_shared<AppExecFwk::EventHandler>(processRunner);
60     processHandler_->PostTask([]() { Samgr::MemoryGuard cacheGuard; });
61     HILOGI("[SA Scheduler] init end");
62 }
63 
InitStateContext(const std::list<SaProfile> & saProfiles)64 void SystemAbilityStateScheduler::InitStateContext(const std::list<SaProfile>& saProfiles)
65 {
66     for (auto& saProfile : saProfiles) {
67         if (saProfile.process.empty()) {
68             continue;
69         }
70         std::unique_lock<std::shared_mutex> processWriteLock(processMapLock_);
71         if (processContextMap_.count(saProfile.process) == 0) {
72             auto processContext = std::make_shared<SystemProcessContext>();
73             processContext->processName = saProfile.process;
74             processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED] = 0;
75             processContext->abilityStateCountMap[SystemAbilityState::LOADING] = 0;
76             processContext->abilityStateCountMap[SystemAbilityState::LOADED] = 0;
77             processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE] = 0;
78             processContext->abilityStateCountMap[SystemAbilityState::UNLOADING] = 0;
79             processContextMap_[saProfile.process] = processContext;
80         }
81         processContextMap_[saProfile.process]->saList.push_back(saProfile.saId);
82         processContextMap_[saProfile.process]->abilityStateCountMap[SystemAbilityState::NOT_LOADED]++;
83         auto abilityContext = std::make_shared<SystemAbilityContext>();
84         abilityContext->systemAbilityId = saProfile.saId;
85         abilityContext->isAutoRestart = saProfile.autoRestart;
86         int32_t delayUnloadTime = LimitDelayUnloadTime(saProfile.stopOnDemand.delayTime);
87         abilityContext->delayUnloadTime = delayUnloadTime;
88         abilityContext->ownProcessContext = processContextMap_[saProfile.process];
89         std::unique_lock<std::shared_mutex> abiltyWriteLock(abiltyMapLock_);
90         abilityContextMap_[saProfile.saId] = abilityContext;
91     }
92 }
93 
LimitDelayUnloadTime(int32_t delayUnloadTime)94 int32_t SystemAbilityStateScheduler::LimitDelayUnloadTime(int32_t delayUnloadTime)
95 {
96     if (delayUnloadTime < 0) {
97         return 0;
98     }
99     if (delayUnloadTime > MAX_DELAY_TIME) {
100         return MAX_DELAY_TIME;
101     }
102     return delayUnloadTime;
103 }
104 
GetSystemAbilityContext(int32_t systemAbilityId,std::shared_ptr<SystemAbilityContext> & abilityContext)105 bool SystemAbilityStateScheduler::GetSystemAbilityContext(int32_t systemAbilityId,
106     std::shared_ptr<SystemAbilityContext>& abilityContext)
107 {
108     std::shared_lock<std::shared_mutex> readLock(abiltyMapLock_);
109     if (abilityContextMap_.count(systemAbilityId) == 0) {
110         HILOGE("[SA Scheduler][SA: %{public}d] not in SA profiles", systemAbilityId);
111         return false;
112     }
113     abilityContext = abilityContextMap_[systemAbilityId];
114     if (abilityContext == nullptr) {
115         HILOGE("[SA Scheduler][SA: %{public}d] context is nullptr", systemAbilityId);
116         return false;
117     }
118     if (abilityContext->ownProcessContext == nullptr) {
119         HILOGE("[SA Scheduler][SA: %{public}d] not in any process", systemAbilityId);
120         return false;
121     }
122     return true;
123 }
124 
GetSystemProcessContext(const std::u16string & processName,std::shared_ptr<SystemProcessContext> & processContext)125 bool SystemAbilityStateScheduler::GetSystemProcessContext(const std::u16string& processName,
126     std::shared_ptr<SystemProcessContext>& processContext)
127 {
128     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
129     if (processContextMap_.count(processName) == 0) {
130         HILOGE("[SA Scheduler][processName: %{public}s] invalid", Str16ToStr8(processName).c_str());
131         return false;
132     }
133     processContext = processContextMap_[processName];
134     if (processContext == nullptr) {
135         HILOGE("[SA Scheduler][processName: %{public}s] context is nullptr", Str16ToStr8(processName).c_str());
136         return false;
137     }
138     return true;
139 }
140 
IsSystemAbilityUnloading(int32_t systemAbilityId)141 bool SystemAbilityStateScheduler::IsSystemAbilityUnloading(int32_t systemAbilityId)
142 {
143     std::shared_ptr<SystemAbilityContext> abilityContext;
144     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
145         return false;
146     }
147     std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);
148     if (abilityContext->state ==SystemAbilityState::UNLOADING
149         || abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
150         return true;
151     }
152     return false;
153 }
154 
HandleLoadAbilityEvent(int32_t systemAbilityId,bool & isExist)155 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEvent(int32_t systemAbilityId, bool& isExist)
156 {
157     HILOGI("[SA Scheduler][SA: %{public}d] handle load event by check start",
158         systemAbilityId);
159     std::shared_ptr<SystemAbilityContext> abilityContext;
160     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
161         isExist = false;
162         return ERR_INVALID_VALUE;
163     }
164     std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);
165     if (abilityContext->ownProcessContext->state == SystemProcessState::NOT_STARTED) {
166         isExist = false;
167         return ERR_INVALID_VALUE;
168     }
169     if (abilityContext->ownProcessContext->state == SystemProcessState::STARTED
170         && abilityContext->state ==SystemAbilityState::NOT_LOADED) {
171         bool result = SystemAbilityManager::GetInstance()->DoLoadOnDemandAbility(systemAbilityId, isExist);
172         if (result) {
173             return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADING);
174         }
175         return ERR_INVALID_VALUE;
176     }
177     isExist = true;
178     return ERR_OK;
179 }
180 
HandleLoadAbilityEvent(const LoadRequestInfo & loadRequestInfo)181 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEvent(const LoadRequestInfo& loadRequestInfo)
182 {
183     HILOGI("[SA Scheduler][SA: %{public}d] handle load event start, callingpid: %{public}d",
184         loadRequestInfo.systemAbilityId, loadRequestInfo.callingPid);
185     std::shared_ptr<SystemAbilityContext> abilityContext;
186     if (!GetSystemAbilityContext(loadRequestInfo.systemAbilityId, abilityContext)) {
187         return ERR_INVALID_VALUE;
188     }
189     std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);
190     return HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
191 }
192 
HandleLoadAbilityEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)193 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEventLocked(
194     const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)
195 {
196     if (abilityContext->state ==SystemAbilityState::UNLOADING
197         || abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
198         return PendLoadEventLocked(abilityContext, loadRequestInfo);
199     }
200     nlohmann::json activeReason;
201     activeReason[KEY_EVENT_ID] = loadRequestInfo.loadEvent.eventId;
202     activeReason[KEY_NAME] = loadRequestInfo.loadEvent.name;
203     activeReason[KEY_VALUE] = loadRequestInfo.loadEvent.value;
204     activeReason[KEY_EXTRA_DATA_ID] = loadRequestInfo.loadEvent.extraDataId;
205     int32_t result = ERR_INVALID_VALUE;
206     switch (abilityContext->state) {
207         case SystemAbilityState::LOADING:
208             result = RemovePendingUnloadEventLocked(abilityContext);
209             break;
210         case SystemAbilityState::LOADED:
211             result = RemoveDelayUnloadEventLocked(abilityContext->systemAbilityId);
212             break;
213         case SystemAbilityState::UNLOADABLE:
214             result = ActiveSystemAbilityLocked(abilityContext, activeReason);
215             break;
216         case SystemAbilityState::NOT_LOADED:
217             result = ERR_OK;
218             break;
219         default:
220             result = ERR_INVALID_VALUE;
221             HILOGI("[SA Scheduler][SA: %{public}d] in state %{public}d, cannot load ability",
222                 loadRequestInfo.systemAbilityId, abilityContext->state);
223             break;
224     }
225     if (result == ERR_OK) {
226         return DoLoadSystemAbilityLocked(abilityContext, loadRequestInfo);
227     }
228     return result;
229 }
230 
HandleUnloadAbilityEvent(const UnloadRequestInfo & unloadRequestInfo)231 int32_t SystemAbilityStateScheduler::HandleUnloadAbilityEvent(const UnloadRequestInfo& unloadRequestInfo)
232 {
233     HILOGI("[SA Scheduler][SA: %{public}d] handle unload event start", unloadRequestInfo.systemAbilityId);
234     std::shared_ptr<SystemAbilityContext> abilityContext;
235     if (!GetSystemAbilityContext(unloadRequestInfo.systemAbilityId, abilityContext)) {
236         return ERR_INVALID_VALUE;
237     }
238     std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);
239     return HandleUnloadAbilityEventLocked(abilityContext, unloadRequestInfo);
240 }
241 
HandleUnloadAbilityEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const UnloadRequestInfo & unloadRequestInfo)242 int32_t SystemAbilityStateScheduler::HandleUnloadAbilityEventLocked(
243     const std::shared_ptr<SystemAbilityContext>& abilityContext, const UnloadRequestInfo& unloadRequestInfo)
244 {
245     abilityContext->unloadRequest = unloadRequestInfo;
246     int32_t result = ERR_INVALID_VALUE;
247     switch (abilityContext->state) {
248         case SystemAbilityState::LOADING:
249             result = PendUnloadEventLocked(abilityContext, unloadRequestInfo);
250             break;
251         case SystemAbilityState::LOADED:
252             if (unloadRequestInfo.unloadEvent.eventId == INTERFACE_CALL) {
253                 result = ProcessDelayUnloadEvent(abilityContext->systemAbilityId);
254             } else {
255                 result = SendDelayUnloadEventLocked(abilityContext->systemAbilityId, abilityContext->delayUnloadTime);
256             }
257             break;
258         default:
259             result = ERR_OK;
260             HILOGI("[SA Scheduler][SA: %{public}d] in state %{public}d, not need unload ability",
261                 abilityContext->systemAbilityId, abilityContext->state);
262             break;
263     }
264     return result;
265 }
266 
HandleCancelUnloadAbilityEvent(int32_t systemAbilityId)267 int32_t SystemAbilityStateScheduler::HandleCancelUnloadAbilityEvent(int32_t systemAbilityId)
268 {
269     HILOGI("[SA Scheduler][SA: %{public}d] cancel unload start", systemAbilityId);
270     std::shared_ptr<SystemAbilityContext> abilityContext;
271     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
272         return ERR_INVALID_VALUE;
273     }
274     nlohmann::json activeReason;
275     activeReason[KEY_EVENT_ID] = INTERFACE_CALL;
276     activeReason[KEY_NAME] = CANCEL_UNLOAD;
277     activeReason[KEY_VALUE] = "";
278     activeReason[KEY_EXTRA_DATA_ID] = -1;
279     int32_t result = ERR_INVALID_VALUE;
280     std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);
281     switch (abilityContext->state) {
282         case SystemAbilityState::UNLOADABLE:
283             result = ActiveSystemAbilityLocked(abilityContext, activeReason);
284             break;
285         default:
286             result = ERR_OK;
287             HILOGI("[SA Scheduler][SA: %{public}d] in state %{public}d, not need cancel unload",
288                 systemAbilityId, abilityContext->state);
289             break;
290     }
291     return result;
292 }
293 
ActiveSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const nlohmann::json & activeReason)294 int32_t SystemAbilityStateScheduler::ActiveSystemAbilityLocked(
295     const std::shared_ptr<SystemAbilityContext>& abilityContext,
296     const nlohmann::json& activeReason)
297 {
298     bool result = SystemAbilityManager::GetInstance()->ActiveSystemAbility(abilityContext->systemAbilityId,
299         abilityContext->ownProcessContext->processName, activeReason);
300     if (!result) {
301         HILOGE("[SA Scheduler][SA: %{public}d] active ability failed", abilityContext->systemAbilityId);
302         return ERR_INVALID_VALUE;
303     }
304     return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADED);
305 }
306 
SendAbilityStateEvent(int32_t systemAbilityId,AbilityStateEvent event)307 int32_t SystemAbilityStateScheduler::SendAbilityStateEvent(int32_t systemAbilityId, AbilityStateEvent event)
308 {
309     HILOGD("[SA Scheduler][SA: %{public}d] receive state event", systemAbilityId);
310     std::shared_ptr<SystemAbilityContext> abilityContext;
311     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
312         return ERR_INVALID_VALUE;
313     }
314     std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);
315     return stateEventHandler_->HandleAbilityEventLocked(abilityContext, event);
316 }
317 
SendProcessStateEvent(const ProcessInfo & processInfo,ProcessStateEvent event)318 int32_t SystemAbilityStateScheduler::SendProcessStateEvent(const ProcessInfo& processInfo, ProcessStateEvent event)
319 {
320     HILOGD("[SA Scheduler][process: %{public}s] receive state event",
321         Str16ToStr8(processInfo.processName).c_str());
322     std::shared_ptr<SystemProcessContext> processContext;
323     if (!GetSystemProcessContext(processInfo.processName, processContext)) {
324         return ERR_INVALID_VALUE;
325     }
326     std::lock_guard<std::recursive_mutex> autoLock(processContext->processLock);
327     return stateEventHandler_->HandleProcessEventLocked(processContext, processInfo, event);
328 }
329 
SendDelayUnloadEventLocked(uint32_t systemAbilityId,int32_t delayTime)330 int32_t SystemAbilityStateScheduler::SendDelayUnloadEventLocked(uint32_t systemAbilityId, int32_t delayTime)
331 {
332     if (unloadEventHandler_ == nullptr) {
333         HILOGE("[SA Scheduler] unload handler not initialized!");
334         return ERR_INVALID_VALUE;
335     }
336     if (unloadEventHandler_->HasInnerEvent(systemAbilityId)) {
337         return ERR_OK;
338     }
339     HILOGI("[SA Scheduler][SA: %{public}d] send delay unload event", systemAbilityId);
340     bool ret = unloadEventHandler_->SendEvent(systemAbilityId, 0, delayTime);
341     if (!ret) {
342         HILOGE("[SA Scheduler] send event failed!");
343         return ERR_INVALID_VALUE;
344     }
345     return ERR_OK;
346 }
347 
RemoveDelayUnloadEventLocked(uint32_t systemAbilityId)348 int32_t SystemAbilityStateScheduler::RemoveDelayUnloadEventLocked(uint32_t systemAbilityId)
349 {
350     if (unloadEventHandler_ == nullptr) {
351         HILOGE("[SA Scheduler] unload handler not initialized!");
352         return ERR_INVALID_VALUE;
353     }
354     if (!unloadEventHandler_->HasInnerEvent(systemAbilityId)) {
355         return ERR_OK;
356     }
357     HILOGI("[SA Scheduler][SA: %{public}d] remove delay unload event", systemAbilityId);
358     unloadEventHandler_->RemoveEvent(systemAbilityId);
359     return ERR_OK;
360 }
361 
PendLoadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)362 int32_t SystemAbilityStateScheduler::PendLoadEventLocked(const std::shared_ptr<SystemAbilityContext>& abilityContext,
363     const LoadRequestInfo& loadRequestInfo)
364 {
365     HILOGI("[SA Scheduler][SA: %{public}d] save load event", abilityContext->systemAbilityId);
366     if (loadRequestInfo.callback == nullptr) {
367         HILOGW("[SA Scheduler] callback invalid!");
368         return ERR_INVALID_VALUE;
369     }
370     bool isExist = std::any_of(abilityContext->pendingLoadEventList.begin(),
371         abilityContext->pendingLoadEventList.end(), [&loadRequestInfo](const auto& loadEventItem) {
372             return loadRequestInfo.callback->AsObject() == loadEventItem.callback->AsObject();
373         });
374     if (isExist) {
375         HILOGI("[SA Scheduler][SA: %{public}d] already existed callback object", abilityContext->systemAbilityId);
376         return ERR_OK;
377     }
378     auto& count = abilityContext->pendingLoadEventCountMap[loadRequestInfo.callingPid];
379     if (count >= MAX_SUBSCRIBE_COUNT) {
380         HILOGE("[SA Scheduler][SA: %{public}d] pid:%{public}d overflow max callback count!",
381             abilityContext->systemAbilityId, loadRequestInfo.callingPid);
382         return ERR_PERMISSION_DENIED;
383     }
384     ++count;
385     abilityContext->pendingLoadEventList.emplace_back(loadRequestInfo);
386     abilityContext->pendingEvent = PendingEvent::LOAD_ABILITY_EVENT;
387     return ERR_OK;
388 }
389 
PendUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const UnloadRequestInfo & unloadRequestInfo)390 int32_t SystemAbilityStateScheduler::PendUnloadEventLocked(
391     const std::shared_ptr<SystemAbilityContext>& abilityContext, const UnloadRequestInfo& unloadRequestInfo)
392 {
393     HILOGI("[SA Scheduler][SA: %{public}d] save unload event", abilityContext->systemAbilityId);
394     abilityContext->pendingEvent = PendingEvent::UNLOAD_ABILITY_EVENT;
395     abilityContext->pendingUnloadEvent = unloadRequestInfo;
396     return ERR_OK;
397 }
398 
RemovePendingUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)399 int32_t SystemAbilityStateScheduler::RemovePendingUnloadEventLocked(
400     const std::shared_ptr<SystemAbilityContext>& abilityContext)
401 {
402     if (abilityContext->pendingEvent == PendingEvent::UNLOAD_ABILITY_EVENT) {
403         HILOGI("[SA Scheduler][SA: %{public}d] remove pending unload event", abilityContext->systemAbilityId);
404         abilityContext->pendingEvent = PendingEvent::NO_EVENT;
405     }
406     return ERR_OK;
407 }
408 
HandlePendingLoadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)409 int32_t SystemAbilityStateScheduler::HandlePendingLoadEventLocked(
410     const std::shared_ptr<SystemAbilityContext>& abilityContext)
411 {
412     if (abilityContext->pendingEvent != PendingEvent::LOAD_ABILITY_EVENT) {
413         HILOGD("[SA Scheduler][SA: %{public}d] no pending load event", abilityContext->systemAbilityId);
414         return ERR_OK;
415     }
416     HILOGI("[SA Scheduler][SA: %{public}d] handle pending load event start", abilityContext->systemAbilityId);
417     abilityContext->pendingEvent = PendingEvent::NO_EVENT;
418     for (auto& loadRequestInfo : abilityContext->pendingLoadEventList) {
419         int32_t result = HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
420         if (result != ERR_OK) {
421             HILOGE("[SA Scheduler][SA: %{public}d] handle pending load event failed, callingPid: %{public}d",
422                 abilityContext->systemAbilityId, loadRequestInfo.callingPid);
423         }
424     }
425     abilityContext->pendingLoadEventList.clear();
426     abilityContext->pendingLoadEventCountMap.clear();
427     return ERR_OK;
428 }
429 
HandlePendingUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)430 int32_t SystemAbilityStateScheduler::HandlePendingUnloadEventLocked(
431     const std::shared_ptr<SystemAbilityContext>& abilityContext)
432 {
433     if (abilityContext->pendingEvent != PendingEvent::UNLOAD_ABILITY_EVENT) {
434         HILOGD("[SA Scheduler][SA: %{public}d] no pending unload event", abilityContext->systemAbilityId);
435         return ERR_OK;
436     }
437     HILOGI("[SA Scheduler][SA: %{public}d] handle pending unload event start", abilityContext->systemAbilityId);
438     abilityContext->pendingEvent = PendingEvent::NO_EVENT;
439     return HandleUnloadAbilityEventLocked(abilityContext, abilityContext->pendingUnloadEvent);
440 }
441 
DoLoadSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)442 int32_t SystemAbilityStateScheduler::DoLoadSystemAbilityLocked(
443     const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)
444 {
445     int32_t result = ERR_OK;
446     if (loadRequestInfo.deviceId == LOCAL_DEVICE) {
447         HILOGD("[SA Scheduler][SA: %{public}d] load ability from local start", abilityContext->systemAbilityId);
448         result = SystemAbilityManager::GetInstance()->DoLoadSystemAbility(abilityContext->systemAbilityId,
449             abilityContext->ownProcessContext->processName, loadRequestInfo.callback, loadRequestInfo.callingPid,
450             loadRequestInfo.loadEvent);
451     } else {
452         HILOGD("[SA Scheduler][SA: %{public}d] load ability from remote start", abilityContext->systemAbilityId);
453         result = SystemAbilityManager::GetInstance()->DoLoadSystemAbilityFromRpc(loadRequestInfo.deviceId,
454             abilityContext->systemAbilityId, abilityContext->ownProcessContext->processName, loadRequestInfo.callback,
455             loadRequestInfo.loadEvent);
456     }
457     if (result == ERR_OK && abilityContext->state == SystemAbilityState::NOT_LOADED) {
458         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADING);
459     }
460     return result;
461 }
462 
TryUnloadAllSystemAbility(const std::shared_ptr<SystemProcessContext> & processContext)463 int32_t SystemAbilityStateScheduler::TryUnloadAllSystemAbility(
464     const std::shared_ptr<SystemProcessContext>& processContext)
465 {
466     if (processContext == nullptr) {
467         HILOGE("[SA Scheduler] process context is nullptr");
468         return ERR_INVALID_VALUE;
469     }
470     std::lock_guard<std::recursive_mutex> autoLock(processContext->processLock);
471     if (CanUnloadAllSystemAbility(processContext)) {
472         return UnloadAllSystemAbilityLocked(processContext);
473     }
474     return ERR_OK;
475 }
476 
CanUnloadAllSystemAbility(const std::shared_ptr<SystemProcessContext> & processContext)477 bool SystemAbilityStateScheduler::CanUnloadAllSystemAbility(
478     const std::shared_ptr<SystemProcessContext>& processContext)
479 {
480     std::shared_lock<std::shared_mutex> sharedLock(processContext->stateCountLock);
481     uint32_t notLoadAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED];
482     uint32_t unloadableAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE];
483     HILOGI("[SA Scheduler][process: %{public}s] SA num: %{public}zu, notloaded: %{public}d, unloadable: %{public}d",
484         Str16ToStr8(processContext->processName).c_str(), processContext->saList.size(), notLoadAbilityCount,
485         unloadableAbilityCount);
486     if (unloadableAbilityCount == 0) {
487         return false;
488     }
489     if (notLoadAbilityCount + unloadableAbilityCount == processContext->saList.size()) {
490         return true;
491     }
492     return false;
493 }
494 
PostTryUnloadAllAbilityTask(const std::shared_ptr<SystemProcessContext> & processContext)495 int32_t SystemAbilityStateScheduler::PostTryUnloadAllAbilityTask(
496     const std::shared_ptr<SystemProcessContext>& processContext)
497 {
498     bool result = processHandler_->PostTask([this, processContext] () {
499         int32_t ret = TryUnloadAllSystemAbility(processContext);
500         if (ret != ERR_OK) {
501             HILOGE("[SA Scheduler][process: %{public}s] unload all SA failed",
502                 Str16ToStr8(processContext->processName).c_str());
503         }
504     });
505     if (!result) {
506         HILOGW("[SA Scheduler][process: %{public}s] post task failed",
507             Str16ToStr8(processContext->processName).c_str());
508         return ERR_INVALID_VALUE;
509     }
510     return ERR_OK;
511 }
512 
PostUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext> & processContext)513 int32_t SystemAbilityStateScheduler::PostUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext>& processContext)
514 {
515     auto timeoutTask = [this, processContext] () {
516         std::lock_guard<std::recursive_mutex> autoLock(processContext->processLock);
517         if (processContext->state == SystemProcessState::STOPPING) {
518             HILOGW("[SA Scheduler][process: %{public}s] unload SA timeout",
519                 Str16ToStr8(processContext->processName).c_str());
520             int32_t result = KillSystemProcessLocked(processContext);
521             HILOGI("[SA Scheduler][process: %{public}s] kill timeout process ret: %{public}d",
522                 Str16ToStr8(processContext->processName).c_str(), result);
523         }
524     };
525     bool ret = processHandler_->PostTask(timeoutTask, KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName),
526         UNLOAD_TIMEOUT_TIME);
527     if (!ret) {
528         HILOGW("[SA Scheduler][process: %{public}s] post timeout task failed",
529             Str16ToStr8(processContext->processName).c_str());
530         return ERR_INVALID_VALUE;
531     }
532     return ERR_OK;
533 }
534 
RemoveUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext> & processContext)535 void SystemAbilityStateScheduler::RemoveUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext>& processContext)
536 {
537     processHandler_->RemoveTask(KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName));
538 }
539 
PostTryKillProcessTask(const std::shared_ptr<SystemProcessContext> & processContext)540 int32_t SystemAbilityStateScheduler::PostTryKillProcessTask(
541     const std::shared_ptr<SystemProcessContext>& processContext)
542 {
543     bool result = processHandler_->PostTask([this, processContext] () {
544         int32_t ret = TryKillSystemProcess(processContext);
545         if (ret != ERR_OK) {
546             HILOGE("[SA Scheduler][process: %{public}s] kill process failed",
547                 Str16ToStr8(processContext->processName).c_str());
548         }
549     });
550     if (!result) {
551         HILOGW("[SA Scheduler][process: %{public}s] post task failed",
552             Str16ToStr8(processContext->processName).c_str());
553         return ERR_INVALID_VALUE;
554     }
555     return ERR_OK;
556 }
557 
UnloadAllSystemAbilityLocked(const std::shared_ptr<SystemProcessContext> & processContext)558 int32_t SystemAbilityStateScheduler::UnloadAllSystemAbilityLocked(
559     const std::shared_ptr<SystemProcessContext>& processContext)
560 {
561     HILOGI("[SA Scheduler][process: %{public}s] unload all SA", Str16ToStr8(processContext->processName).c_str());
562     for (auto& saId : processContext->saList) {
563         std::shared_ptr<SystemAbilityContext> abilityContext;
564         if (!GetSystemAbilityContext(saId, abilityContext)) {
565             continue;
566         }
567         int32_t result = ERR_OK;
568         if (abilityContext->state == SystemAbilityState::UNLOADABLE) {
569             result = DoUnloadSystemAbilityLocked(abilityContext);
570         }
571         if (result != ERR_OK) {
572             HILOGE("[SA Scheduler][SA: %{public}d] unload failed", saId);
573         }
574     }
575     PostUnloadTimeoutTask(processContext);
576     return stateMachine_->ProcessStateTransitionLocked(processContext, SystemProcessState::STOPPING);
577 }
578 
DoUnloadSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)579 int32_t SystemAbilityStateScheduler::DoUnloadSystemAbilityLocked(
580     const std::shared_ptr<SystemAbilityContext>& abilityContext)
581 {
582     int32_t result = ERR_OK;
583     HILOGI("[SA Scheduler][SA: %{public}d] unload ability start", abilityContext->systemAbilityId);
584     result = SystemAbilityManager::GetInstance()->DoUnloadSystemAbility(abilityContext->systemAbilityId,
585         abilityContext->ownProcessContext->processName, abilityContext->unloadRequest.unloadEvent);
586     if (result == ERR_OK) {
587         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::UNLOADING);
588     }
589     return result;
590 }
591 
TryKillSystemProcess(const std::shared_ptr<SystemProcessContext> & processContext)592 int32_t SystemAbilityStateScheduler::TryKillSystemProcess(
593     const std::shared_ptr<SystemProcessContext>& processContext)
594 {
595     if (processContext == nullptr) {
596         HILOGE("[SA Scheduler] process context is nullptr");
597         return ERR_INVALID_VALUE;
598     }
599     std::lock_guard<std::recursive_mutex> autoLock(processContext->processLock);
600     if (CanKillSystemProcess(processContext)) {
601         return KillSystemProcessLocked(processContext);
602     }
603     return ERR_OK;
604 }
605 
CanKillSystemProcess(const std::shared_ptr<SystemProcessContext> & processContext)606 bool SystemAbilityStateScheduler::CanKillSystemProcess(
607     const std::shared_ptr<SystemProcessContext>& processContext)
608 {
609     std::shared_lock<std::shared_mutex> sharedLock(processContext->stateCountLock);
610     uint32_t notLoadAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED];
611     HILOGI("[SA Scheduler][process: %{public}s] SA num: %{public}zu, not loaded num: %{public}d",
612         Str16ToStr8(processContext->processName).c_str(), processContext->saList.size(), notLoadAbilityCount);
613     if (notLoadAbilityCount == processContext->saList.size()) {
614         return true;
615     }
616     return false;
617 }
618 
KillSystemProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)619 int32_t SystemAbilityStateScheduler::KillSystemProcessLocked(
620     const std::shared_ptr<SystemProcessContext>& processContext)
621 {
622     int32_t result = ERR_OK;
623     #ifdef RESSCHED_ENABLE
624     std::unordered_map<std::string, std::string> payload;
625     payload["pid"] = std::to_string(processContext->pid);
626     payload["uid"] = std::to_string(processContext->uid);
627     payload["processName"] = Str16ToStr8(processContext->processName);
628     result = ResourceSchedule::ResSchedClient::GetInstance().KillProcess(payload);
629     HILOGI("[SA Scheduler][process: %{public}s] kill process, pid: %{public}d, uid: %{public}d, result: %{public}d",
630         Str16ToStr8(processContext->processName).c_str(), processContext->pid, processContext->uid, result);
631     #endif
632     return result;
633 }
634 
CanRestartProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)635 bool SystemAbilityStateScheduler::CanRestartProcessLocked(const std::shared_ptr<SystemProcessContext>& processContext)
636 {
637     if (!processContext->enableRestart) {
638         return false;
639     }
640     int64_t curtime = GetTickCount();
641     if (processContext->restartCountsCtrl.size() < RESTART_TIMES_LIMIT) {
642         processContext->restartCountsCtrl.push_back(curtime);
643         return true;
644     } else if (processContext->restartCountsCtrl.size() == RESTART_TIMES_LIMIT) {
645         if (curtime - processContext->restartCountsCtrl.front() < RESTART_TIME_INTERVAL_LIMIT) {
646             processContext->enableRestart = false;
647             return false;
648         }
649         processContext->restartCountsCtrl.push_back(curtime);
650         processContext->restartCountsCtrl.pop_front();
651         return true;
652     } else {
653         HILOGE("[SA Scheduler][process: %{public}s] unkown error",
654             Str16ToStr8(processContext->processName).c_str());
655     }
656     return false;
657 }
658 
GetAbnormallyDiedAbilityLocked(std::shared_ptr<SystemProcessContext> & processContext,std::list<std::shared_ptr<SystemAbilityContext>> & abnormallyDiedAbilityList)659 int32_t SystemAbilityStateScheduler::GetAbnormallyDiedAbilityLocked(
660     std::shared_ptr<SystemProcessContext>& processContext,
661     std::list<std::shared_ptr<SystemAbilityContext>>& abnormallyDiedAbilityList)
662 {
663     for (auto& saId : processContext->saList) {
664         std::shared_ptr<SystemAbilityContext> abilityContext;
665         if (!GetSystemAbilityContext(saId, abilityContext)) {
666             continue;
667         }
668         if (abilityContext->state == SystemAbilityState::LOADED
669             || abilityContext->state == SystemAbilityState::LOADING) {
670             HILOGI("[SA Scheduler][SA: %{public}d] abnormally died", abilityContext->systemAbilityId);
671             if (abilityContext->isAutoRestart) {
672                 HILOGI("[SA Scheduler][SA: %{public}d] is auto restart", abilityContext->systemAbilityId);
673                 abnormallyDiedAbilityList.emplace_back(abilityContext);
674             }
675         }
676     }
677     return ERR_OK;
678 }
679 
680 
HandleAbnormallyDiedAbilityLocked(std::shared_ptr<SystemProcessContext> & processContext,std::list<std::shared_ptr<SystemAbilityContext>> & abnormallyDiedAbilityList)681 int32_t SystemAbilityStateScheduler::HandleAbnormallyDiedAbilityLocked(
682     std::shared_ptr<SystemProcessContext>& processContext,
683     std::list<std::shared_ptr<SystemAbilityContext>>& abnormallyDiedAbilityList)
684 {
685     if (abnormallyDiedAbilityList.empty()) {
686         return ERR_OK;
687     }
688     if (!CanRestartProcessLocked(processContext)) {
689         HILOGW("[SA Scheduler][process: %{public}s] can't restart: More than 4 restarts in 20 seconds",
690             Str16ToStr8(processContext->processName).c_str());
691         return ERR_OK;
692     }
693     OnDemandEvent onDemandEvent = {INTERFACE_CALL, "restart"};
694     sptr<ISystemAbilityLoadCallback> callback(new SystemAbilityLoadCallbackStub());
695     for (auto& abilityContext : abnormallyDiedAbilityList) {
696         LoadRequestInfo loadRequestInfo = {abilityContext->systemAbilityId,
697             LOCAL_DEVICE, callback, -1, onDemandEvent};
698         HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
699     }
700     return ERR_OK;
701 }
702 
NotifyProcessStarted(const std::shared_ptr<SystemProcessContext> & processContext)703 void SystemAbilityStateScheduler::NotifyProcessStarted(const std::shared_ptr<SystemProcessContext>& processContext)
704 {
705     std::shared_lock<std::shared_mutex> readLock(listenerSetLock_);
706     for (auto& listener : processListeners_) {
707         if (listener->AsObject() != nullptr) {
708             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
709                 processContext->uid};
710             listener->OnSystemProcessStarted(systemProcessInfo);
711         }
712     }
713 }
714 
NotifyProcessStopped(const std::shared_ptr<SystemProcessContext> & processContext)715 void SystemAbilityStateScheduler::NotifyProcessStopped(const std::shared_ptr<SystemProcessContext>& processContext)
716 {
717     std::shared_lock<std::shared_mutex> readLock(listenerSetLock_);
718     for (auto& listener : processListeners_) {
719         if (listener->AsObject() != nullptr) {
720             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
721                 processContext->uid};
722             listener->OnSystemProcessStopped(systemProcessInfo);
723         }
724     }
725 }
726 
OnProcessStartedLocked(const std::u16string & processName)727 void SystemAbilityStateScheduler::OnProcessStartedLocked(const std::u16string& processName)
728 {
729     HILOGI("[SA Scheduler][process: %{public}s] started", Str16ToStr8(processName).c_str());
730     std::shared_ptr<SystemProcessContext> processContext;
731     if (!GetSystemProcessContext(processName, processContext)) {
732         return;
733     }
734     NotifyProcessStarted(processContext);
735 }
736 
OnProcessNotStartedLocked(const std::u16string & processName)737 void SystemAbilityStateScheduler::OnProcessNotStartedLocked(const std::u16string& processName)
738 {
739     HILOGI("[SA Scheduler][process: %{public}s] stopped", Str16ToStr8(processName).c_str());
740     std::shared_ptr<SystemProcessContext> processContext;
741     if (!GetSystemProcessContext(processName, processContext)) {
742         return;
743     }
744     NotifyProcessStopped(processContext);
745     RemoveUnloadTimeoutTask(processContext);
746 
747     std::list<std::shared_ptr<SystemAbilityContext>> abnormallyDiedAbilityList;
748     GetAbnormallyDiedAbilityLocked(processContext, abnormallyDiedAbilityList);
749     for (auto& saId : processContext->saList) {
750         std::shared_ptr<SystemAbilityContext> abilityContext;
751         if (!GetSystemAbilityContext(saId, abilityContext)) {
752             continue;
753         }
754         int32_t result = stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::NOT_LOADED);
755         if (result != ERR_OK) {
756             continue;
757         }
758         HandlePendingLoadEventLocked(abilityContext);
759     }
760     HandleAbnormallyDiedAbilityLocked(processContext, abnormallyDiedAbilityList);
761 }
762 
HandleAbilityDiedEvent(int32_t systemAbilityId)763 int32_t SystemAbilityStateScheduler::HandleAbilityDiedEvent(int32_t systemAbilityId)
764 {
765     HILOGD("[SA Scheduler][SA: %{public}d] handle ability died event", systemAbilityId);
766     return ERR_OK;
767 }
768 
OnAbilityNotLoadedLocked(int32_t systemAbilityId)769 void SystemAbilityStateScheduler::OnAbilityNotLoadedLocked(int32_t systemAbilityId)
770 {
771     HILOGI("[SA Scheduler][SA: %{public}d] not loaded", systemAbilityId);
772     std::shared_ptr<SystemAbilityContext> abilityContext;
773     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
774         return;
775     }
776     RemoveDelayUnloadEventLocked(abilityContext->systemAbilityId);
777     RemovePendingUnloadEventLocked(abilityContext);
778     if (abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
779         PostTryKillProcessTask(abilityContext->ownProcessContext);
780     } else if (abilityContext->ownProcessContext->state == SystemProcessState::STARTED) {
781         PostTryUnloadAllAbilityTask(abilityContext->ownProcessContext);
782     }
783 }
784 
OnAbilityLoadedLocked(int32_t systemAbilityId)785 void SystemAbilityStateScheduler::OnAbilityLoadedLocked(int32_t systemAbilityId)
786 {
787     HILOGI("[SA Scheduler][SA: %{public}d] loaded", systemAbilityId);
788     std::shared_ptr<SystemAbilityContext> abilityContext;
789     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
790         return;
791     }
792     HandlePendingUnloadEventLocked(abilityContext);
793 }
794 
OnAbilityUnloadableLocked(int32_t systemAbilityId)795 void SystemAbilityStateScheduler::OnAbilityUnloadableLocked(int32_t systemAbilityId)
796 {
797     HILOGI("[SA Scheduler][SA: %{public}d] unloadable", systemAbilityId);
798     std::shared_ptr<SystemAbilityContext> abilityContext;
799     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
800         return;
801     }
802     PostTryUnloadAllAbilityTask(abilityContext->ownProcessContext);
803 }
804 
GetRunningSystemProcess(std::list<SystemProcessInfo> & systemProcessInfos)805 int32_t SystemAbilityStateScheduler::GetRunningSystemProcess(std::list<SystemProcessInfo>& systemProcessInfos)
806 {
807     HILOGI("[SA Scheduler] get running process");
808     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
809     for (auto it : processContextMap_) {
810         auto& processContext = it.second;
811         if (processContext == nullptr) {
812             continue;
813         }
814         std::lock_guard<std::recursive_mutex> autoLock(processContext->processLock);
815         if (processContext->state == SystemProcessState::STARTED) {
816             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
817                 processContext->uid};
818             systemProcessInfos.emplace_back(systemProcessInfo);
819         }
820     }
821     return ERR_OK;
822 }
823 
SubscribeSystemProcess(const sptr<ISystemProcessStatusChange> & listener)824 int32_t SystemAbilityStateScheduler::SubscribeSystemProcess(const sptr<ISystemProcessStatusChange>& listener)
825 {
826     std::unique_lock<std::shared_mutex> writeLock(listenerSetLock_);
827     auto iter = std::find_if(processListeners_.begin(), processListeners_.end(),
828         [listener](sptr<ISystemProcessStatusChange>& item) {
829         return item->AsObject() == listener->AsObject();
830     });
831     if (iter == processListeners_.end()) {
832         if (processListenerDeath_ != nullptr) {
833             bool ret = listener->AsObject()->AddDeathRecipient(processListenerDeath_);
834             HILOGI("SubscribeSystemProcess AddDeathRecipient %{public}s", ret ? "succeed" : "failed");
835         }
836         processListeners_.emplace_back(listener);
837     } else {
838         HILOGI("SubscribeSystemProcess listener already exists");
839     }
840     return ERR_OK;
841 }
842 
UnSubscribeSystemProcess(const sptr<ISystemProcessStatusChange> & listener)843 int32_t SystemAbilityStateScheduler::UnSubscribeSystemProcess(const sptr<ISystemProcessStatusChange>& listener)
844 {
845     std::unique_lock<std::shared_mutex> writeLock(listenerSetLock_);
846     auto iter = std::find_if(processListeners_.begin(), processListeners_.end(),
847         [listener](sptr<ISystemProcessStatusChange>& item) {
848         return item->AsObject() == listener->AsObject();
849     });
850     if (iter != processListeners_.end()) {
851         if (processListenerDeath_ != nullptr) {
852             listener->AsObject()->RemoveDeathRecipient(processListenerDeath_);
853         }
854         processListeners_.erase(iter);
855         HILOGI("UnSubscribeSystemProcess listener remove success");
856     } else {
857         HILOGI("UnSubscribeSystemProcess listener not exists");
858     }
859     return ERR_OK;
860 }
861 
ProcessDelayUnloadEvent(int32_t systemAbilityId)862 int32_t SystemAbilityStateScheduler::ProcessDelayUnloadEvent(int32_t systemAbilityId)
863 {
864     std::shared_ptr<SystemAbilityContext> abilityContext;
865     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
866         return ERR_INVALID_VALUE;
867     }
868     std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);
869     if (abilityContext->state != SystemAbilityState::LOADED) {
870         HILOGW("[SA Scheduler][SA: %{public}d] cannot process delay unload event", systemAbilityId);
871         return ERR_OK;
872     }
873     HILOGI("[SA Scheduler][SA: %{public}d] process delay unload event", systemAbilityId);
874     int32_t delayTime = 0;
875     nlohmann::json idleReason;
876     idleReason[KEY_EVENT_ID] = abilityContext->unloadRequest.unloadEvent.eventId;
877     idleReason[KEY_NAME] = abilityContext->unloadRequest.unloadEvent.name;
878     idleReason[KEY_VALUE] = abilityContext->unloadRequest.unloadEvent.value;
879     idleReason[KEY_EXTRA_DATA_ID] = abilityContext->unloadRequest.unloadEvent.extraDataId;
880     bool result = SystemAbilityManager::GetInstance()->IdleSystemAbility(abilityContext->systemAbilityId,
881         abilityContext->ownProcessContext->processName, idleReason, delayTime);
882     if (!result) {
883         HILOGE("[SA Scheduler][SA: %{public}d] idle system ability failed", systemAbilityId);
884         return ERR_INVALID_VALUE;
885     }
886     if (delayTime < 0) {
887         HILOGI("[SA Scheduler][SA: %{public}d] reject unload", systemAbilityId);
888         return ERR_OK;
889     } else if (delayTime == 0) {
890         HILOGI("[SA Scheduler][SA: %{public}d] agree unload", systemAbilityId);
891         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::UNLOADABLE);
892     } else {
893         HILOGI("[SA Scheduler][SA: %{public}d] choose delay unload", systemAbilityId);
894         return SendDelayUnloadEventLocked(abilityContext->systemAbilityId, fmin(delayTime, MAX_DELAY_TIME));
895     }
896 }
897 
ProcessEvent(const OHOS::AppExecFwk::InnerEvent::Pointer & event)898 void SystemAbilityStateScheduler::UnloadEventHandler::ProcessEvent(const OHOS::AppExecFwk::InnerEvent::Pointer& event)
899 {
900     if (event == nullptr) {
901         HILOGE("[SA Scheduler] ProcessEvent event is nullptr!");
902         return;
903     }
904     auto eventId = event->GetInnerEventId();
905     int32_t systemAbilityId = static_cast<int32_t>(eventId);
906     auto stateScheduler = stateScheduler_.lock();
907     int32_t result = ERR_OK;
908     if (stateScheduler != nullptr) {
909         result = stateScheduler->ProcessDelayUnloadEvent(systemAbilityId);
910     }
911     if (result != ERR_OK) {
912         HILOGE("[SA Scheduler][SA: %{public}d] process delay unload event failed", systemAbilityId);
913     }
914 }
915 }  // namespace OHOS