• 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 #include "sam_log.h"
23 #include "hisysevent_adapter.h"
24 #include "schedule/system_ability_state_scheduler.h"
25 #include "service_control.h"
26 #include "samgr_err_code.h"
27 #include "string_ex.h"
28 #include "system_ability_manager.h"
29 #include "samgr_xcollie.h"
30 #include "parameters.h"
31 #include "system_ability_manager_util.h"
32 #include "system_ability_definition.h"
33 
34 namespace OHOS {
35 namespace {
36 constexpr int64_t RESTART_TIME_INTERVAL_LIMIT = 20 * 1000;
37 constexpr int32_t RESTART_TIMES_LIMIT = 4;
38 constexpr int32_t MAX_SUBSCRIBE_COUNT = 256;
39 constexpr int32_t UNLOAD_TIMEOUT_TIME = 5 * 1000;
40 constexpr const char* LOCAL_DEVICE = "local";
41 constexpr int32_t MAX_DELAY_TIME = 5 * 60 * 1000;
42 constexpr int32_t MAX_DURATION = 10 * 60 * 1000; // ms
43 constexpr int32_t ONCE_DELAY_TIME = 10 * 1000; // ms
44 constexpr const char* CANCEL_UNLOAD = "cancelUnload";
45 constexpr const char* KEY_EVENT_ID = "eventId";
46 constexpr const char* KEY_NAME = "name";
47 constexpr const char* KEY_VALUE = "value";
48 constexpr const char* KEY_EXTRA_DATA_ID = "extraDataId";
49 constexpr const char* KEY_UNLOAD_TIMEOUT = "unloadTimeout";
50 const std::u16string SAMGR_PROCESS_NAME = u"samgr";
51 constexpr const char *SA_STATE_ENUM_STR[] = {
52     "NOT_LOADED", "LOADING", "LOADED", "UNLOADABLE", "UNLOADING" };
53 constexpr const char *PROCESS_STATE_ENUM_STR[] = {
54     "NOT_STARTED", "STARTED", "STOPPING" };
55 constexpr const char *PENDINGEVENT_ENUM_STR[] = {
56     "NO_EVENT", "LOAD_ABILITY_EVENT", "UNLOAD_ABILITY_EVENT" };
57 }
Init(const std::list<SaProfile> & saProfiles)58 void SystemAbilityStateScheduler::Init(const std::list<SaProfile>& saProfiles)
59 {
60     HILOGI("Scheduler:init start");
61     InitStateContext(saProfiles);
62     processListenerDeath_ = sptr<IRemoteObject::DeathRecipient>(new SystemProcessListenerDeathRecipient());
63     unloadEventHandler_ = std::make_shared<UnloadEventHandler>(weak_from_this());
64 
65     auto listener =  std::dynamic_pointer_cast<SystemAbilityStateListener>(shared_from_this());
66     stateMachine_ = std::make_shared<SystemAbilityStateMachine>(listener);
67     stateEventHandler_ = std::make_shared<SystemAbilityEventHandler>(stateMachine_);
68 
69     processHandler_ = std::make_shared<FFRTHandler>("ProcessHandler");
70     HILOGI("Scheduler:init end");
71 }
72 
CleanFfrt()73 void SystemAbilityStateScheduler::CleanFfrt()
74 {
75     if (processHandler_ != nullptr) {
76         processHandler_->CleanFfrt();
77     }
78     if (unloadEventHandler_ != nullptr) {
79         unloadEventHandler_->CleanFfrt();
80     }
81 }
82 
SetFfrt()83 void SystemAbilityStateScheduler::SetFfrt()
84 {
85     if (processHandler_ != nullptr) {
86         processHandler_->SetFfrt("ProcessHandler");
87     }
88     if (unloadEventHandler_ != nullptr) {
89         unloadEventHandler_->SetFfrt();
90     }
91 }
92 
CleanResource()93 void SystemAbilityStateScheduler::CleanResource()
94 {
95     std::unique_lock<std::shared_mutex> abiltyWriteLock(abiltyMapLock_);
96     HILOGI("Scheduler CleanResource");
97     abilityContextMap_.clear();
98 }
99 
InitStateContext(const std::list<SaProfile> & saProfiles)100 void SystemAbilityStateScheduler::InitStateContext(const std::list<SaProfile>& saProfiles)
101 {
102     for (auto& saProfile : saProfiles) {
103         if (saProfile.process.empty()) {
104             continue;
105         }
106         std::unique_lock<std::shared_mutex> processWriteLock(processMapLock_);
107         if (processContextMap_.count(saProfile.process) == 0) {
108             auto processContext = std::make_shared<SystemProcessContext>();
109             processContext->processName = saProfile.process;
110             processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED] = 0;
111             processContext->abilityStateCountMap[SystemAbilityState::LOADING] = 0;
112             processContext->abilityStateCountMap[SystemAbilityState::LOADED] = 0;
113             processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE] = 0;
114             processContext->abilityStateCountMap[SystemAbilityState::UNLOADING] = 0;
115             processContextMap_[saProfile.process] = processContext;
116         }
117         processContextMap_[saProfile.process]->saList.push_back(saProfile.saId);
118         processContextMap_[saProfile.process]->abilityStateCountMap[SystemAbilityState::NOT_LOADED]++;
119         auto abilityContext = std::make_shared<SystemAbilityContext>();
120         abilityContext->systemAbilityId = saProfile.saId;
121         abilityContext->isAutoRestart = saProfile.autoRestart;
122         int32_t delayUnloadTime = LimitDelayUnloadTime(saProfile.stopOnDemand.delayTime);
123         abilityContext->delayUnloadTime = delayUnloadTime;
124         abilityContext->ownProcessContext = processContextMap_[saProfile.process];
125         std::unique_lock<std::shared_mutex> abiltyWriteLock(abiltyMapLock_);
126         abilityContextMap_[saProfile.saId] = abilityContext;
127     }
128 }
129 
InitSamgrProcessContext()130 void SystemAbilityStateScheduler::InitSamgrProcessContext()
131 {
132     auto processContext = std::make_shared<SystemProcessContext>();
133     processContext->processName = SAMGR_PROCESS_NAME;
134     processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED] = 0;
135     processContext->abilityStateCountMap[SystemAbilityState::LOADING] = 0;
136     processContext->abilityStateCountMap[SystemAbilityState::LOADED] = 1;
137     processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE] = 0;
138     processContext->abilityStateCountMap[SystemAbilityState::UNLOADING] = 0;
139     processContext->pid = getpid();
140     processContext->uid = static_cast<int32_t>(getuid());
141     processContextMap_[SAMGR_PROCESS_NAME] = processContext;
142     processContextMap_[SAMGR_PROCESS_NAME]->saList.push_back(0);
143     processContext->state = SystemProcessState::STARTED;
144 
145     auto abilityContext = std::make_shared<SystemAbilityContext>();
146     abilityContext->systemAbilityId = 0;
147     abilityContext->isAutoRestart = false;
148     abilityContext->delayUnloadTime = MAX_DELAY_TIME;
149     abilityContext->ownProcessContext = processContextMap_[SAMGR_PROCESS_NAME];
150     std::unique_lock<std::shared_mutex> abiltyWriteLock(abiltyMapLock_);
151     abilityContextMap_[0] = abilityContext;
152 }
153 
LimitDelayUnloadTime(int32_t delayUnloadTime)154 int32_t SystemAbilityStateScheduler::LimitDelayUnloadTime(int32_t delayUnloadTime)
155 {
156     if (delayUnloadTime < 0) {
157         return 0;
158     }
159     if (delayUnloadTime > MAX_DELAY_TIME) {
160         return MAX_DELAY_TIME;
161     }
162     return delayUnloadTime;
163 }
164 
GetSystemAbilityContext(int32_t systemAbilityId,std::shared_ptr<SystemAbilityContext> & abilityContext)165 bool SystemAbilityStateScheduler::GetSystemAbilityContext(int32_t systemAbilityId,
166     std::shared_ptr<SystemAbilityContext>& abilityContext)
167 {
168     std::shared_lock<std::shared_mutex> readLock(abiltyMapLock_);
169     if (abilityContextMap_.count(systemAbilityId) == 0) {
170         HILOGD("Scheduler SA:%{public}d not in SA profiles", systemAbilityId);
171         return false;
172     }
173     abilityContext = abilityContextMap_[systemAbilityId];
174     if (abilityContext == nullptr) {
175         HILOGE("Scheduler SA:%{public}d context is null", systemAbilityId);
176         return false;
177     }
178     if (abilityContext->ownProcessContext == nullptr) {
179         HILOGE("Scheduler SA:%{public}d not in any proc", systemAbilityId);
180         return false;
181     }
182     return true;
183 }
184 
UpdateLimitDelayUnloadTime(int32_t systemAbilityId)185 void SystemAbilityStateScheduler::UpdateLimitDelayUnloadTime(int32_t systemAbilityId)
186 {
187     if (processHandler_ == nullptr) {
188         HILOGE("UpdateLimitDelayUnloadTime process handler not init");
189         return;
190     }
191     auto UpdateDelayUnloadTimeTask = [systemAbilityId, this]() {
192         UpdateLimitDelayUnloadTimeTask(systemAbilityId);
193     };
194     bool ret = processHandler_->PostTask(UpdateDelayUnloadTimeTask);
195     if (!ret) {
196         HILOGW("UpdateLimitDelayUnloadTime PostTask fail");
197     }
198 }
199 
UpdateLimitDelayUnloadTimeTask(int32_t systemAbilityId)200 void SystemAbilityStateScheduler::UpdateLimitDelayUnloadTimeTask(int32_t systemAbilityId)
201 {
202     std::shared_ptr<SystemAbilityContext> abilityContext;
203     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
204         return;
205     }
206     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
207     if (abilityContext->lastStartTime != 0) {
208         int64_t begin = abilityContext->lastStartTime;
209         int64_t end = GetTickCount();
210         if (end - begin <= MAX_DURATION) {
211             int64_t onceDelayTime = abilityContext->delayUnloadTime;
212             onceDelayTime += ONCE_DELAY_TIME;
213             abilityContext->delayUnloadTime = LimitDelayUnloadTime(onceDelayTime);
214             HILOGI("DelayUnloadTime is %{public}d, SA:%{public}d", abilityContext->delayUnloadTime, systemAbilityId);
215         }
216     }
217     abilityContext->lastStartTime = GetTickCount();
218 }
219 
GetSystemProcessContext(const std::u16string & processName,std::shared_ptr<SystemProcessContext> & processContext)220 bool SystemAbilityStateScheduler::GetSystemProcessContext(const std::u16string& processName,
221     std::shared_ptr<SystemProcessContext>& processContext)
222 {
223     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
224     if (processContextMap_.count(processName) == 0) {
225         HILOGE("Scheduler proc:%{public}s invalid", Str16ToStr8(processName).c_str());
226         return false;
227     }
228     processContext = processContextMap_[processName];
229     if (processContext == nullptr) {
230         HILOGE("Scheduler proc:%{public}s context is null", Str16ToStr8(processName).c_str());
231         return false;
232     }
233     return true;
234 }
235 
IsSystemAbilityUnloading(int32_t systemAbilityId)236 bool SystemAbilityStateScheduler::IsSystemAbilityUnloading(int32_t systemAbilityId)
237 {
238     std::shared_ptr<SystemAbilityContext> abilityContext;
239     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
240         return false;
241     }
242     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
243     if (abilityContext->state ==SystemAbilityState::UNLOADING
244         || abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
245         return true;
246     }
247     return false;
248 }
249 
HandleLoadAbilityEvent(int32_t systemAbilityId,bool & isExist)250 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEvent(int32_t systemAbilityId, bool& isExist)
251 {
252     std::shared_ptr<SystemAbilityContext> abilityContext;
253     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
254         isExist = false;
255         return ERR_INVALID_VALUE;
256     }
257     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
258     if (abilityContext->ownProcessContext->state == SystemProcessState::NOT_STARTED) {
259         isExist = false;
260         return ERR_INVALID_VALUE;
261     }
262     if (abilityContext->ownProcessContext->state == SystemProcessState::STARTED
263         && abilityContext->state ==SystemAbilityState::NOT_LOADED) {
264         HILOGD("Scheduler SA:%{public}d handle load event by check start", systemAbilityId);
265         bool result = SystemAbilityManager::GetInstance()->DoLoadOnDemandAbility(systemAbilityId, isExist);
266         if (result) {
267             return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADING);
268         }
269         return ERR_INVALID_VALUE;
270     }
271     isExist = true;
272     return ERR_OK;
273 }
274 
HandleLoadAbilityEvent(const LoadRequestInfo & loadRequestInfo)275 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEvent(const LoadRequestInfo& loadRequestInfo)
276 {
277     std::shared_ptr<SystemAbilityContext> abilityContext;
278     if (!GetSystemAbilityContext(loadRequestInfo.systemAbilityId, abilityContext)) {
279         return GET_SA_CONTEXT_FAIL;
280     }
281     HILOGI("Scheduler SA:%{public}d load start %{public}d,%{public}d_"
282         "%{public}d_%{public}d", loadRequestInfo.systemAbilityId, loadRequestInfo.callingPid,
283         loadRequestInfo.loadEvent.eventId, abilityContext->ownProcessContext->state, abilityContext->state);
284     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
285     int32_t result = HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
286     if (result != ERR_OK) {
287         HILOGE("Scheduler SA:%{public}d handle load fail,ret:%{public}d",
288             loadRequestInfo.systemAbilityId, result);
289     }
290     return result;
291 }
292 
HandleLoadAbilityEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)293 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEventLocked(
294     const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)
295 {
296     if (abilityContext->state ==SystemAbilityState::UNLOADING
297         || abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
298         HILOGW("Scheduler SA:%{public}d state %{public}d, proc state %{public}d",
299             abilityContext->systemAbilityId, abilityContext->state, abilityContext->ownProcessContext->state);
300         return PendLoadEventLocked(abilityContext, loadRequestInfo);
301     }
302     nlohmann::json activeReason;
303     activeReason[KEY_EVENT_ID] = loadRequestInfo.loadEvent.eventId;
304     activeReason[KEY_NAME] = loadRequestInfo.loadEvent.name;
305     activeReason[KEY_VALUE] = loadRequestInfo.loadEvent.value;
306     activeReason[KEY_EXTRA_DATA_ID] = loadRequestInfo.loadEvent.extraDataId;
307     int32_t result = INVALID_SA_STATE;
308     switch (abilityContext->state) {
309         case SystemAbilityState::LOADING:
310             result = RemovePendingUnloadEventLocked(abilityContext);
311             break;
312         case SystemAbilityState::LOADED:
313             result = RemoveDelayUnloadEventLocked(abilityContext->systemAbilityId);
314             break;
315         case SystemAbilityState::UNLOADABLE:
316             result = ActiveSystemAbilityLocked(abilityContext, activeReason);
317             break;
318         case SystemAbilityState::NOT_LOADED:
319             result = ERR_OK;
320             break;
321         default:
322             result = INVALID_SA_STATE;
323             HILOGI("Scheduler SA:%{public}d in state %{public}d, can't load SA",
324                 loadRequestInfo.systemAbilityId, abilityContext->state);
325             break;
326     }
327     if (result == ERR_OK) {
328         return DoLoadSystemAbilityLocked(abilityContext, loadRequestInfo);
329     }
330     return result;
331 }
332 
HandleUnloadAbilityEvent(const std::shared_ptr<UnloadRequestInfo> unloadRequestInfo)333 int32_t SystemAbilityStateScheduler::HandleUnloadAbilityEvent(
334     const std::shared_ptr<UnloadRequestInfo> unloadRequestInfo)
335 {
336     if (unloadRequestInfo == nullptr) {
337         HILOGE("Scheduler:HandleUnloadSaEvent unloadRequestInfo is null");
338         return UNLOAD_REQUEST_NULL;
339     }
340     std::shared_ptr<SystemAbilityContext> abilityContext;
341     if (!GetSystemAbilityContext(unloadRequestInfo->systemAbilityId, abilityContext)) {
342         return GET_SA_CONTEXT_FAIL;
343     }
344     HILOGI("Scheduler SA:%{public}d unload start %{public}d,%{public}d_"
345         "%{public}d_%{public}d", unloadRequestInfo->systemAbilityId, unloadRequestInfo->callingPid,
346         unloadRequestInfo->unloadEvent.eventId, abilityContext->ownProcessContext->state, abilityContext->state);
347     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
348     int32_t result = HandleUnloadAbilityEventLocked(abilityContext, unloadRequestInfo);
349     if (result != ERR_OK) {
350         HILOGE("Scheduler SA:%{public}d handle unload fail,ret:%{public}d",
351             unloadRequestInfo->systemAbilityId, result);
352     }
353     return result;
354 }
355 
HandleUnloadAbilityEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const std::shared_ptr<UnloadRequestInfo> unloadRequestInfo)356 int32_t SystemAbilityStateScheduler::HandleUnloadAbilityEventLocked(
357     const std::shared_ptr<SystemAbilityContext>& abilityContext,
358     const std::shared_ptr<UnloadRequestInfo> unloadRequestInfo)
359 {
360     if (unloadRequestInfo == nullptr) {
361         HILOGE("Scheduler SA:%{public}d unloadRequestInfo is null", abilityContext->systemAbilityId);
362         return UNLOAD_REQUEST_NULL;
363     }
364     abilityContext->unloadRequest = unloadRequestInfo;
365     int32_t result = INVALID_SA_STATE;
366     switch (abilityContext->state) {
367         case SystemAbilityState::LOADING:
368             result = PendUnloadEventLocked(abilityContext, unloadRequestInfo);
369             break;
370         case SystemAbilityState::LOADED:
371             if (unloadRequestInfo->unloadEvent.eventId == INTERFACE_CALL) {
372                 result = ProcessDelayUnloadEventLocked(abilityContext->systemAbilityId);
373             } else {
374                 result = SendDelayUnloadEventLocked(abilityContext->systemAbilityId, abilityContext->delayUnloadTime);
375             }
376             break;
377         default:
378             result = ERR_OK;
379             HILOGI("Scheduler SA:%{public}d in state %{public}d,not need unload SA,callPid:%{public}d",
380                 abilityContext->systemAbilityId, abilityContext->state, unloadRequestInfo->callingPid);
381             break;
382     }
383     return result;
384 }
385 
HandleCancelUnloadAbilityEvent(int32_t systemAbilityId)386 int32_t SystemAbilityStateScheduler::HandleCancelUnloadAbilityEvent(int32_t systemAbilityId)
387 {
388     HILOGI("Scheduler SA:%{public}d cancel unload start", systemAbilityId);
389     std::shared_ptr<SystemAbilityContext> abilityContext;
390     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
391         return ERR_INVALID_VALUE;
392     }
393     nlohmann::json activeReason;
394     activeReason[KEY_EVENT_ID] = INTERFACE_CALL;
395     activeReason[KEY_NAME] = CANCEL_UNLOAD;
396     activeReason[KEY_VALUE] = "";
397     activeReason[KEY_EXTRA_DATA_ID] = -1;
398     int32_t result = ERR_INVALID_VALUE;
399     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
400     switch (abilityContext->state) {
401         case SystemAbilityState::UNLOADABLE:
402             result = ActiveSystemAbilityLocked(abilityContext, activeReason);
403             break;
404         default:
405             result = ERR_OK;
406             HILOGI("Scheduler SA:%{public}d in state %{public}d,not need cancel unload",
407                 systemAbilityId, abilityContext->state);
408             break;
409     }
410     return result;
411 }
412 
ActiveSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const nlohmann::json & activeReason)413 int32_t SystemAbilityStateScheduler::ActiveSystemAbilityLocked(
414     const std::shared_ptr<SystemAbilityContext>& abilityContext,
415     const nlohmann::json& activeReason)
416 {
417     bool result = SystemAbilityManager::GetInstance()->ActiveSystemAbility(abilityContext->systemAbilityId,
418         abilityContext->ownProcessContext->processName, activeReason);
419     if (!result) {
420         HILOGE("Scheduler SA:%{public}d active fail", abilityContext->systemAbilityId);
421         return ACTIVE_SA_FAIL;
422     }
423     return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADED);
424 }
425 
SendAbilityStateEvent(int32_t systemAbilityId,AbilityStateEvent event)426 int32_t SystemAbilityStateScheduler::SendAbilityStateEvent(int32_t systemAbilityId, AbilityStateEvent event)
427 {
428     HILOGD("Scheduler SA:%{public}d recv state event", systemAbilityId);
429     std::shared_ptr<SystemAbilityContext> abilityContext;
430     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
431         return ERR_INVALID_VALUE;
432     }
433     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
434     return stateEventHandler_->HandleAbilityEventLocked(abilityContext, event);
435 }
436 
SendProcessStateEvent(const ProcessInfo & processInfo,ProcessStateEvent event)437 int32_t SystemAbilityStateScheduler::SendProcessStateEvent(const ProcessInfo& processInfo, ProcessStateEvent event)
438 {
439     HILOGD("Scheduler proc:%{public}s receive state event",
440         Str16ToStr8(processInfo.processName).c_str());
441     std::shared_ptr<SystemProcessContext> processContext;
442     if (!GetSystemProcessContext(processInfo.processName, processContext)) {
443         return ERR_INVALID_VALUE;
444     }
445     std::lock_guard<std::mutex> autoLock(processContext->processLock);
446     return stateEventHandler_->HandleProcessEventLocked(processContext, processInfo, event);
447 }
448 
SendDelayUnloadEventLocked(uint32_t systemAbilityId,int32_t delayTime)449 int32_t SystemAbilityStateScheduler::SendDelayUnloadEventLocked(uint32_t systemAbilityId, int32_t delayTime)
450 {
451     if (unloadEventHandler_ == nullptr) {
452         HILOGE("Scheduler:unload handler not init");
453         return UNLOAD_EVENT_HANDLER_NULL;
454     }
455     if (unloadEventHandler_->HasInnerEvent(systemAbilityId)) {
456         return ERR_OK;
457     }
458     HILOGI("Scheduler SA:%{public}d send delay unload event", systemAbilityId);
459     bool ret = unloadEventHandler_->SendEvent(systemAbilityId, 0, delayTime);
460     if (!ret) {
461         HILOGE("Scheduler:send event fail");
462         return SEND_EVENT_FAIL;
463     }
464     return ERR_OK;
465 }
466 
RemoveDelayUnloadEventLocked(uint32_t systemAbilityId)467 int32_t SystemAbilityStateScheduler::RemoveDelayUnloadEventLocked(uint32_t systemAbilityId)
468 {
469     if (unloadEventHandler_ == nullptr) {
470         HILOGE("Scheduler:unload handler not init");
471         return UNLOAD_EVENT_HANDLER_NULL;
472     }
473     if (!unloadEventHandler_->HasInnerEvent(systemAbilityId)) {
474         return ERR_OK;
475     }
476     HILOGI("Scheduler SA:%{public}d rm delay unload event", systemAbilityId);
477     unloadEventHandler_->RemoveEvent(systemAbilityId);
478     return ERR_OK;
479 }
480 
PendLoadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)481 int32_t SystemAbilityStateScheduler::PendLoadEventLocked(const std::shared_ptr<SystemAbilityContext>& abilityContext,
482     const LoadRequestInfo& loadRequestInfo)
483 {
484     HILOGI("Scheduler SA:%{public}d save load event", abilityContext->systemAbilityId);
485     if (loadRequestInfo.callback == nullptr) {
486         HILOGW("Scheduler:callback invalid!");
487         return CALLBACK_NULL;
488     }
489     bool isExist = std::any_of(abilityContext->pendingLoadEventList.begin(),
490         abilityContext->pendingLoadEventList.end(), [&loadRequestInfo](const auto& loadEventItem) {
491             return loadRequestInfo.callback->AsObject() == loadEventItem.callback->AsObject();
492         });
493     if (isExist) {
494         HILOGI("Scheduler SA:%{public}d existed callback", abilityContext->systemAbilityId);
495         return ERR_OK;
496     }
497     auto& count = abilityContext->pendingLoadEventCountMap[loadRequestInfo.callingPid];
498     if (count >= MAX_SUBSCRIBE_COUNT) {
499         HILOGE("Scheduler SA:%{public}d pid:%{public}d overflow max callback count!",
500             abilityContext->systemAbilityId, loadRequestInfo.callingPid);
501         return PEND_LOAD_EVENT_SIZE_LIMIT;
502     }
503     ++count;
504     abilityContext->pendingLoadEventList.emplace_back(loadRequestInfo);
505     abilityContext->pendingEvent = PendingEvent::LOAD_ABILITY_EVENT;
506     return ERR_OK;
507 }
508 
PendUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const std::shared_ptr<UnloadRequestInfo> unloadRequestInfo)509 int32_t SystemAbilityStateScheduler::PendUnloadEventLocked(
510     const std::shared_ptr<SystemAbilityContext>& abilityContext,
511     const std::shared_ptr<UnloadRequestInfo> unloadRequestInfo)
512 {
513     HILOGI("Scheduler SA:%{public}d save unload event", abilityContext->systemAbilityId);
514     abilityContext->pendingEvent = PendingEvent::UNLOAD_ABILITY_EVENT;
515     abilityContext->pendingUnloadEvent = unloadRequestInfo;
516     return ERR_OK;
517 }
518 
RemovePendingUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)519 int32_t SystemAbilityStateScheduler::RemovePendingUnloadEventLocked(
520     const std::shared_ptr<SystemAbilityContext>& abilityContext)
521 {
522     if (abilityContext->pendingEvent == PendingEvent::UNLOAD_ABILITY_EVENT) {
523         HILOGI("Scheduler SA:%{public}d rm pending unload event", abilityContext->systemAbilityId);
524         abilityContext->pendingEvent = PendingEvent::NO_EVENT;
525     }
526     return ERR_OK;
527 }
528 
HandlePendingLoadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)529 int32_t SystemAbilityStateScheduler::HandlePendingLoadEventLocked(
530     const std::shared_ptr<SystemAbilityContext>& abilityContext)
531 {
532     if (abilityContext->pendingEvent != PendingEvent::LOAD_ABILITY_EVENT) {
533         HILOGD("Scheduler SA:%{public}d no pending load event", abilityContext->systemAbilityId);
534         return ERR_OK;
535     }
536     HILOGI("Scheduler SA:%{public}d handle pending load event start", abilityContext->systemAbilityId);
537     abilityContext->pendingEvent = PendingEvent::NO_EVENT;
538     for (auto& loadRequestInfo : abilityContext->pendingLoadEventList) {
539         int32_t result = HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
540         if (result != ERR_OK) {
541             HILOGE("Scheduler SA:%{public}d handle pending load event fail,callPid:%{public}d",
542                 abilityContext->systemAbilityId, loadRequestInfo.callingPid);
543         }
544     }
545     abilityContext->pendingLoadEventList.clear();
546     abilityContext->pendingLoadEventCountMap.clear();
547     return ERR_OK;
548 }
549 
HandlePendingUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)550 int32_t SystemAbilityStateScheduler::HandlePendingUnloadEventLocked(
551     const std::shared_ptr<SystemAbilityContext>& abilityContext)
552 {
553     if (abilityContext->pendingEvent != PendingEvent::UNLOAD_ABILITY_EVENT) {
554         HILOGD("Scheduler SA:%{public}d no pending unload event", abilityContext->systemAbilityId);
555         return ERR_OK;
556     }
557     HILOGI("Scheduler SA:%{public}d handle pending unload event start", abilityContext->systemAbilityId);
558     abilityContext->pendingEvent = PendingEvent::NO_EVENT;
559     return HandleUnloadAbilityEventLocked(abilityContext, abilityContext->pendingUnloadEvent);
560 }
561 
DoLoadSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)562 int32_t SystemAbilityStateScheduler::DoLoadSystemAbilityLocked(
563     const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)
564 {
565     int32_t result = ERR_OK;
566     if (loadRequestInfo.deviceId == LOCAL_DEVICE) {
567         HILOGD("Scheduler SA:%{public}d load ability from local start", abilityContext->systemAbilityId);
568         result = SystemAbilityManager::GetInstance()->DoLoadSystemAbility(abilityContext->systemAbilityId,
569             abilityContext->ownProcessContext->processName, loadRequestInfo.callback, loadRequestInfo.callingPid,
570             loadRequestInfo.loadEvent);
571     } else {
572         HILOGD("Scheduler SA:%{public}d load ability from remote start", abilityContext->systemAbilityId);
573         result = SystemAbilityManager::GetInstance()->DoLoadSystemAbilityFromRpc(loadRequestInfo.deviceId,
574             abilityContext->systemAbilityId, abilityContext->ownProcessContext->processName, loadRequestInfo.callback,
575             loadRequestInfo.loadEvent);
576     }
577     if (result == ERR_OK && abilityContext->state == SystemAbilityState::NOT_LOADED) {
578         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADING);
579     }
580     return result;
581 }
582 
TryUnloadAllSystemAbility(const std::shared_ptr<SystemProcessContext> & processContext)583 int32_t SystemAbilityStateScheduler::TryUnloadAllSystemAbility(
584     const std::shared_ptr<SystemProcessContext>& processContext)
585 {
586     if (processContext == nullptr) {
587         HILOGE("Scheduler:proc context is null");
588         return ERR_INVALID_VALUE;
589     }
590     std::lock_guard<std::mutex> autoLock(processContext->processLock);
591     if (CanUnloadAllSystemAbilityLocked(processContext, true)) {
592         return UnloadAllSystemAbilityLocked(processContext);
593     }
594     return ERR_OK;
595 }
596 
CanUnloadAllSystemAbility(const std::shared_ptr<SystemProcessContext> & processContext)597 bool SystemAbilityStateScheduler::CanUnloadAllSystemAbility(
598     const std::shared_ptr<SystemProcessContext>& processContext)
599 {
600     std::lock_guard<std::mutex> autoLock(processContext->stateCountLock);
601     return CanUnloadAllSystemAbilityLocked(processContext, true);
602 }
603 
CanUnloadAllSystemAbilityLocked(const std::shared_ptr<SystemProcessContext> & processContext,bool isNeedCheckRecycleStrategy)604 bool SystemAbilityStateScheduler::CanUnloadAllSystemAbilityLocked(
605     const std::shared_ptr<SystemProcessContext>& processContext, bool isNeedCheckRecycleStrategy)
606 {
607     uint32_t notLoadAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED];
608     uint32_t unloadableAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE];
609     if (unloadableAbilityCount == 0) {
610         return false;
611     }
612     if (notLoadAbilityCount + unloadableAbilityCount == processContext->saList.size()) {
613         if (isNeedCheckRecycleStrategy) {
614             return CheckSaIsImmediatelyRecycle(processContext);
615         } else {
616             return true;
617         }
618     }
619     HILOGI("Scheduler proc:%{public}s SA num:%{public}zu,notloaded:%{public}d,unloadable:%{public}d",
620         Str16ToStr8(processContext->processName).c_str(), processContext->saList.size(), notLoadAbilityCount,
621         unloadableAbilityCount);
622     return false;
623 }
624 
CheckSaIsImmediatelyRecycle(const std::shared_ptr<SystemProcessContext> & processContext)625 bool SystemAbilityStateScheduler::CheckSaIsImmediatelyRecycle(
626     const std::shared_ptr<SystemProcessContext>& processContext)
627 {
628     for (auto& saId: processContext->saList) {
629         if (SystemAbilityManager::GetInstance()->CheckSaIsImmediatelyRecycle(saId)) {
630             return true;
631         }
632     }
633     HILOGI("CheckSaIsImmediatelyRecycle is false");
634     return false;
635 }
636 
PostTryUnloadAllAbilityTask(const std::shared_ptr<SystemProcessContext> & processContext)637 int32_t SystemAbilityStateScheduler::PostTryUnloadAllAbilityTask(
638     const std::shared_ptr<SystemProcessContext>& processContext)
639 {
640     auto weak = weak_from_this();
641     bool result = processHandler_->PostTask([weak, processContext] () {
642         auto strong = weak.lock();
643         if (!strong) {
644             HILOGW("SystemAbilityStateScheduler is null");
645             return;
646         }
647         int32_t ret = strong->TryUnloadAllSystemAbility(processContext);
648         if (ret != ERR_OK) {
649             HILOGE("Scheduler proc:%{public}s unload all SA fail",
650                 Str16ToStr8(processContext->processName).c_str());
651         }
652     });
653     if (!result) {
654         HILOGW("Scheduler proc:%{public}s post task fail",
655             Str16ToStr8(processContext->processName).c_str());
656         return ERR_INVALID_VALUE;
657     }
658     return ERR_OK;
659 }
660 
PostUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext> & processContext)661 int32_t SystemAbilityStateScheduler::PostUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext>& processContext)
662 {
663     auto weak = weak_from_this();
664     auto timeoutTask = [weak, processContext] () {
665         auto strong = weak.lock();
666         if (!strong) {
667             HILOGW("SystemAbilityStateScheduler is null");
668             return;
669         }
670         std::string name = KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName);
671         if (strong->processHandler_ != nullptr) {
672             HILOGD("TimeoutTask deltask proc:%{public}s", name.c_str());
673             strong->processHandler_->DelTask(name);
674         } else {
675             HILOGE("TimeoutTask processHandler_ is null");
676         }
677         std::lock_guard<std::mutex> autoLock(processContext->processLock);
678         if (processContext->state == SystemProcessState::STOPPING) {
679             HILOGW("Scheduler proc:%{public}s unload SA timeout",
680                 Str16ToStr8(processContext->processName).c_str());
681             int32_t result = strong->KillSystemProcessLocked(processContext);
682             HILOGI("Scheduler proc:%{public}s kill proc timeout ret:%{public}d",
683                 Str16ToStr8(processContext->processName).c_str(), result);
684         }
685     };
686     bool ret = processHandler_->PostTask(timeoutTask, KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName),
687         UNLOAD_TIMEOUT_TIME);
688     if (!ret) {
689         HILOGW("Scheduler proc:%{public}s post timeout task fail",
690             Str16ToStr8(processContext->processName).c_str());
691         return ERR_INVALID_VALUE;
692     }
693     return ERR_OK;
694 }
695 
RemoveUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext> & processContext)696 void SystemAbilityStateScheduler::RemoveUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext>& processContext)
697 {
698     processHandler_->RemoveTask(KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName));
699 }
700 
PostTryKillProcessTask(const std::shared_ptr<SystemProcessContext> & processContext)701 int32_t SystemAbilityStateScheduler::PostTryKillProcessTask(
702     const std::shared_ptr<SystemProcessContext>& processContext)
703 {
704     auto weak = weak_from_this();
705     bool result = processHandler_->PostTask([weak, processContext] () {
706         auto strong = weak.lock();
707         if (!strong) {
708             HILOGW("SystemAbilityStateScheduler is null");
709             return;
710         }
711         int32_t ret = strong->TryKillSystemProcess(processContext);
712         if (ret != ERR_OK) {
713             HILOGE("Scheduler proc:%{public}s kill proc fail",
714                 Str16ToStr8(processContext->processName).c_str());
715         }
716     });
717     if (!result) {
718         HILOGW("Scheduler proc:%{public}s post task fail",
719             Str16ToStr8(processContext->processName).c_str());
720         return ERR_INVALID_VALUE;
721     }
722     return ERR_OK;
723 }
724 
UnloadAllSystemAbilityLocked(const std::shared_ptr<SystemProcessContext> & processContext)725 int32_t SystemAbilityStateScheduler::UnloadAllSystemAbilityLocked(
726     const std::shared_ptr<SystemProcessContext>& processContext)
727 {
728     HILOGI("Scheduler proc:%{public}s unload all SA", Str16ToStr8(processContext->processName).c_str());
729     for (auto& saId : processContext->saList) {
730         std::shared_ptr<SystemAbilityContext> abilityContext;
731         if (!GetSystemAbilityContext(saId, abilityContext)) {
732             continue;
733         }
734         int32_t result = ERR_OK;
735         if (abilityContext->state == SystemAbilityState::UNLOADABLE) {
736             result = DoUnloadSystemAbilityLocked(abilityContext);
737         }
738         if (result != ERR_OK) {
739             HILOGE("Scheduler SA:%{public}d unload fail", saId);
740         }
741     }
742     PostUnloadTimeoutTask(processContext);
743     return stateMachine_->ProcessStateTransitionLocked(processContext, SystemProcessState::STOPPING);
744 }
745 
DoUnloadSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)746 int32_t SystemAbilityStateScheduler::DoUnloadSystemAbilityLocked(
747     const std::shared_ptr<SystemAbilityContext>& abilityContext)
748 {
749     if (abilityContext->unloadRequest == nullptr) {
750         HILOGE("Scheduler SA:%{public}d DoUnloadSaLocked unloadRequest is null",
751             abilityContext->systemAbilityId);
752         return ERR_INVALID_VALUE;
753     }
754     int32_t result = ERR_OK;
755     HILOGI("Scheduler SA:%{public}d unload start", abilityContext->systemAbilityId);
756     result = SystemAbilityManager::GetInstance()->DoUnloadSystemAbility(abilityContext->systemAbilityId,
757         abilityContext->ownProcessContext->processName, abilityContext->unloadRequest->unloadEvent);
758     if (result == ERR_OK) {
759         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::UNLOADING);
760     }
761     return result;
762 }
763 
UnloadAllIdleSystemAbility()764 int32_t SystemAbilityStateScheduler::UnloadAllIdleSystemAbility()
765 {
766     HILOGI("Scheduler:UnloadAllIdleSa");
767     int32_t result = ERR_OK;
768     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
769     for (auto it : processContextMap_) {
770         auto& processContext = it.second;
771         if (processContext == nullptr) {
772             continue;
773         }
774 
775         int32_t ret = ERR_OK;
776         std::lock_guard<std::mutex> autoLock(processContext->processLock);
777         if (CanUnloadAllSystemAbilityLocked(processContext)) {
778             ret = UnloadAllSystemAbilityLocked(processContext);
779         }
780         if (ret != ERR_OK) {
781             result = ret;
782             HILOGI("Scheduler proc:%{public}s unload all SA fail",
783                 Str16ToStr8(processContext->processName).c_str());
784         }
785     }
786     return result;
787 }
788 
TryKillSystemProcess(const std::shared_ptr<SystemProcessContext> & processContext)789 int32_t SystemAbilityStateScheduler::TryKillSystemProcess(
790     const std::shared_ptr<SystemProcessContext>& processContext)
791 {
792     if (processContext == nullptr) {
793         HILOGE("Scheduler:proc context is null");
794         return ERR_INVALID_VALUE;
795     }
796     std::lock_guard<std::mutex> autoLock(processContext->processLock);
797     if (CanKillSystemProcessLocked(processContext)) {
798         return KillSystemProcessLocked(processContext);
799     }
800     return ERR_OK;
801 }
802 
CanKillSystemProcess(const std::shared_ptr<SystemProcessContext> & processContext)803 bool SystemAbilityStateScheduler::CanKillSystemProcess(
804     const std::shared_ptr<SystemProcessContext>& processContext)
805 {
806     std::lock_guard<std::mutex> autoLock(processContext->stateCountLock);
807     return CanKillSystemProcessLocked(processContext);
808 }
809 
CanKillSystemProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)810 bool SystemAbilityStateScheduler::CanKillSystemProcessLocked(
811     const std::shared_ptr<SystemProcessContext>& processContext)
812 {
813     uint32_t notLoadAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED];
814     HILOGI("Scheduler proc:%{public}s,SA num:%{public}zu,notloaded num:%{public}d",
815         Str16ToStr8(processContext->processName).c_str(), processContext->saList.size(), notLoadAbilityCount);
816     if (notLoadAbilityCount == processContext->saList.size()) {
817         return true;
818     }
819     return false;
820 }
821 
KillSystemProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)822 int32_t SystemAbilityStateScheduler::KillSystemProcessLocked(
823     const std::shared_ptr<SystemProcessContext>& processContext)
824 {
825     int64_t begin = GetTickCount();
826     int32_t result = ERR_OK;
827     {
828         SamgrXCollie samgrXCollie("samgr--killProccess_" + Str16ToStr8(processContext->processName));
829         result = ServiceControlWithExtra(Str16ToStr8(processContext->processName).c_str(),
830             ServiceAction::STOP, nullptr, 0);
831     }
832 
833     int64_t duration = GetTickCount() - begin;
834     if (result != 0) {
835         ReportProcessStopFail(Str16ToStr8(processContext->processName), processContext->pid, processContext->uid,
836             "err:" + ToString(result));
837     } else {
838         ReportProcessStopDuration(Str16ToStr8(processContext->processName), processContext->pid,
839             processContext->uid, duration);
840     }
841     KHILOGI("Scheduler proc:%{public}s kill pid:%{public}d,%{public}d_%{public}d_"
842         "%{public}" PRId64 "ms", Str16ToStr8(processContext->processName).c_str(), processContext->pid,
843         processContext->uid, result, duration);
844     return result;
845 }
846 
CanRestartProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)847 bool SystemAbilityStateScheduler::CanRestartProcessLocked(const std::shared_ptr<SystemProcessContext>& processContext)
848 {
849     if (!processContext->enableRestart) {
850         return false;
851     }
852     int64_t curtime = GetTickCount();
853     if (processContext->restartCountsCtrl.size() < RESTART_TIMES_LIMIT) {
854         processContext->restartCountsCtrl.push_back(curtime);
855         return true;
856     } else if (processContext->restartCountsCtrl.size() == RESTART_TIMES_LIMIT) {
857         if (curtime - processContext->restartCountsCtrl.front() < RESTART_TIME_INTERVAL_LIMIT) {
858             processContext->enableRestart = false;
859             return false;
860         }
861         processContext->restartCountsCtrl.push_back(curtime);
862         processContext->restartCountsCtrl.pop_front();
863         return true;
864     } else {
865         HILOGE("Scheduler proc:%{public}s unkown err",
866             Str16ToStr8(processContext->processName).c_str());
867     }
868     return false;
869 }
870 
GetAbnormallyDiedAbilityLocked(std::shared_ptr<SystemProcessContext> & processContext,std::list<std::shared_ptr<SystemAbilityContext>> & abnormallyDiedAbilityList)871 int32_t SystemAbilityStateScheduler::GetAbnormallyDiedAbilityLocked(
872     std::shared_ptr<SystemProcessContext>& processContext,
873     std::list<std::shared_ptr<SystemAbilityContext>>& abnormallyDiedAbilityList)
874 {
875     for (auto& saId : processContext->saList) {
876         std::shared_ptr<SystemAbilityContext> abilityContext;
877         if (!GetSystemAbilityContext(saId, abilityContext)) {
878             continue;
879         }
880         if (abilityContext->state == SystemAbilityState::LOADED
881             || abilityContext->state == SystemAbilityState::LOADING) {
882             SamgrUtil::SendUpdateSaState(abilityContext->systemAbilityId, "crash");
883             HILOGI("Scheduler SA:%{public}d abnormally died", abilityContext->systemAbilityId);
884             if (abilityContext->systemAbilityId == SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
885                 SystemAbilityManager::GetInstance()->RemoveWhiteCommonEvent();
886             }
887             if (!abilityContext->isAutoRestart) {
888                 continue;
889             }
890             if (system::GetBoolParameter("resourceschedule.memmgr.min.memmory.watermark", false)) {
891                 HILOGW("restart fail,watermark=true");
892                 continue;
893             }
894             HILOGI("Scheduler SA:%{public}d is auto restart", abilityContext->systemAbilityId);
895             abnormallyDiedAbilityList.emplace_back(abilityContext);
896         }
897     }
898     return ERR_OK;
899 }
900 
901 
HandleAbnormallyDiedAbilityLocked(std::shared_ptr<SystemProcessContext> & processContext,std::list<std::shared_ptr<SystemAbilityContext>> & abnormallyDiedAbilityList)902 int32_t SystemAbilityStateScheduler::HandleAbnormallyDiedAbilityLocked(
903     std::shared_ptr<SystemProcessContext>& processContext,
904     std::list<std::shared_ptr<SystemAbilityContext>>& abnormallyDiedAbilityList)
905 {
906     if (abnormallyDiedAbilityList.empty()) {
907         return ERR_OK;
908     }
909     if (!CanRestartProcessLocked(processContext)) {
910         HILOGW("Scheduler proc:%{public}s can't restart:More than 4 restarts in 20s",
911             Str16ToStr8(processContext->processName).c_str());
912         return ERR_OK;
913     }
914     OnDemandEvent onDemandEvent = {INTERFACE_CALL, "restart"};
915     sptr<ISystemAbilityLoadCallback> callback(new SystemAbilityLoadCallbackStub());
916     for (auto& abilityContext : abnormallyDiedAbilityList) {
917         // Actively remove SA to prevent restart failure if the death recipient of SA is not processed in time.
918         SystemAbilityManager::GetInstance()->RemoveDiedSystemAbility(abilityContext->systemAbilityId);
919         LoadRequestInfo loadRequestInfo = {LOCAL_DEVICE, callback,
920             abilityContext->systemAbilityId, -1, onDemandEvent};
921         HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
922     }
923     return ERR_OK;
924 }
925 
NotifyProcessStarted(const std::shared_ptr<SystemProcessContext> & processContext)926 void SystemAbilityStateScheduler::NotifyProcessStarted(const std::shared_ptr<SystemProcessContext>& processContext)
927 {
928     std::shared_lock<std::shared_mutex> readLock(listenerSetLock_);
929     for (auto& listener : processListeners_) {
930         if (listener->AsObject() != nullptr) {
931             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
932                 processContext->uid};
933             listener->OnSystemProcessStarted(systemProcessInfo);
934         }
935     }
936 }
937 
NotifyProcessStopped(const std::shared_ptr<SystemProcessContext> & processContext)938 void SystemAbilityStateScheduler::NotifyProcessStopped(const std::shared_ptr<SystemProcessContext>& processContext)
939 {
940     std::shared_lock<std::shared_mutex> readLock(listenerSetLock_);
941     for (auto& listener : processListeners_) {
942         if (listener->AsObject() != nullptr) {
943             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
944                 processContext->uid};
945             listener->OnSystemProcessStopped(systemProcessInfo);
946         }
947     }
948 }
949 
OnProcessStartedLocked(const std::u16string & processName)950 void SystemAbilityStateScheduler::OnProcessStartedLocked(const std::u16string& processName)
951 {
952     HILOGI("Scheduler proc:%{public}s started", Str16ToStr8(processName).c_str());
953     std::shared_ptr<SystemProcessContext> processContext;
954     if (!GetSystemProcessContext(processName, processContext)) {
955         return;
956     }
957     NotifyProcessStarted(processContext);
958 }
959 
OnProcessNotStartedLocked(const std::u16string & processName)960 void SystemAbilityStateScheduler::OnProcessNotStartedLocked(const std::u16string& processName)
961 {
962     HILOGI("Scheduler proc:%{public}s stopped", Str16ToStr8(processName).c_str());
963     std::shared_ptr<SystemProcessContext> processContext;
964     if (!GetSystemProcessContext(processName, processContext)) {
965         return;
966     }
967     NotifyProcessStopped(processContext);
968     RemoveUnloadTimeoutTask(processContext);
969     SystemAbilityManager::GetInstance()->RemoveOnDemandSaInDiedProc(processContext);
970 
971     std::list<std::shared_ptr<SystemAbilityContext>> abnormallyDiedAbilityList;
972     GetAbnormallyDiedAbilityLocked(processContext, abnormallyDiedAbilityList);
973     for (auto& saId : processContext->saList) {
974         std::shared_ptr<SystemAbilityContext> abilityContext;
975         if (!GetSystemAbilityContext(saId, abilityContext)) {
976             continue;
977         }
978         int32_t result = stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::NOT_LOADED);
979         if (result != ERR_OK) {
980             continue;
981         }
982         HandlePendingLoadEventLocked(abilityContext);
983     }
984     HandleAbnormallyDiedAbilityLocked(processContext, abnormallyDiedAbilityList);
985 }
986 
HandleAbilityDiedEvent(int32_t systemAbilityId)987 int32_t SystemAbilityStateScheduler::HandleAbilityDiedEvent(int32_t systemAbilityId)
988 {
989     HILOGD("Scheduler SA:%{public}d handle ability died event", systemAbilityId);
990     return ERR_OK;
991 }
992 
OnAbilityNotLoadedLocked(int32_t systemAbilityId)993 void SystemAbilityStateScheduler::OnAbilityNotLoadedLocked(int32_t systemAbilityId)
994 {
995     HILOGI("Scheduler SA:%{public}d not loaded", systemAbilityId);
996     std::shared_ptr<SystemAbilityContext> abilityContext;
997     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
998         return;
999     }
1000     RemoveDelayUnloadEventLocked(abilityContext->systemAbilityId);
1001     RemovePendingUnloadEventLocked(abilityContext);
1002     if (abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
1003         PostTryKillProcessTask(abilityContext->ownProcessContext);
1004     } else if (abilityContext->ownProcessContext->state == SystemProcessState::STARTED) {
1005         PostTryUnloadAllAbilityTask(abilityContext->ownProcessContext);
1006     }
1007 }
1008 
OnAbilityLoadedLocked(int32_t systemAbilityId)1009 void SystemAbilityStateScheduler::OnAbilityLoadedLocked(int32_t systemAbilityId)
1010 {
1011     HILOGI("Scheduler SA:%{public}d loaded", systemAbilityId);
1012     std::shared_ptr<SystemAbilityContext> abilityContext;
1013     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
1014         return;
1015     }
1016     HandlePendingUnloadEventLocked(abilityContext);
1017 }
1018 
OnAbilityUnloadableLocked(int32_t systemAbilityId)1019 void SystemAbilityStateScheduler::OnAbilityUnloadableLocked(int32_t systemAbilityId)
1020 {
1021     HILOGI("Scheduler SA:%{public}d unloadable", systemAbilityId);
1022     std::shared_ptr<SystemAbilityContext> abilityContext;
1023     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
1024         return;
1025     }
1026     PostTryUnloadAllAbilityTask(abilityContext->ownProcessContext);
1027 }
1028 
GetSystemProcessInfo(int32_t systemAbilityId,SystemProcessInfo & systemProcessInfo)1029 int32_t SystemAbilityStateScheduler::GetSystemProcessInfo(int32_t systemAbilityId,
1030     SystemProcessInfo& systemProcessInfo)
1031 {
1032     HILOGI("Scheduler:get proc info by [SA:%{public}d]", systemAbilityId);
1033     std::shared_ptr<SystemAbilityContext> abilityContext;
1034     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
1035         HILOGI("Scheduler:get SA context by said fail");
1036         return ERR_INVALID_VALUE;
1037     }
1038     std::shared_ptr<SystemProcessContext> processContext = abilityContext->ownProcessContext;
1039     std::lock_guard<std::mutex> autoLock(processContext->processLock);
1040     systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
1041                 processContext->uid};
1042     return ERR_OK;
1043 }
1044 
GetRunningSystemProcess(std::list<SystemProcessInfo> & systemProcessInfos)1045 int32_t SystemAbilityStateScheduler::GetRunningSystemProcess(std::list<SystemProcessInfo>& systemProcessInfos)
1046 {
1047     HILOGI("Scheduler:get running process");
1048     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
1049     for (auto it : processContextMap_) {
1050         auto& processContext = it.second;
1051         if (processContext == nullptr) {
1052             continue;
1053         }
1054         std::lock_guard<std::mutex> autoLock(processContext->processLock);
1055         if (processContext->state == SystemProcessState::STARTED) {
1056             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
1057                 processContext->uid};
1058             systemProcessInfos.emplace_back(systemProcessInfo);
1059         }
1060     }
1061     return ERR_OK;
1062 }
1063 
GetProcessNameByProcessId(int32_t pid,std::u16string & processName)1064 int32_t SystemAbilityStateScheduler::GetProcessNameByProcessId(int32_t pid, std::u16string& processName)
1065 {
1066     HILOGD("[SA Scheduler] get processName by processId");
1067     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
1068     for (auto it : processContextMap_) {
1069         auto& processContext = it.second;
1070         if (processContext == nullptr) {
1071             continue;
1072         }
1073         std::lock_guard<std::mutex> autoLock(processContext->processLock);
1074         if (processContext->pid == pid) {
1075             processName = processContext->processName;
1076             return ERR_OK;
1077         }
1078     }
1079     return ERR_INVALID_VALUE;
1080 }
1081 
GetAllSystemAbilityInfo(std::string & result)1082 void SystemAbilityStateScheduler::GetAllSystemAbilityInfo(std::string& result)
1083 {
1084     std::shared_lock<std::shared_mutex> readLock(abiltyMapLock_);
1085     for (auto it : abilityContextMap_) {
1086         if (it.second == nullptr) {
1087             continue;
1088         }
1089         result += "said:                           ";
1090         result += std::to_string(it.second->systemAbilityId);
1091         result += "\n";
1092         result += "sa_state:                       ";
1093         result += SA_STATE_ENUM_STR[static_cast<int32_t>(it.second->state)];
1094         result += "\n";
1095         result += "sa_pending_event:               ";
1096         result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(it.second->pendingEvent)];
1097         if (it.second->ownProcessContext != nullptr) {
1098             std::lock_guard<std::mutex> autoLock(it.second->ownProcessContext->stateCountLock);
1099             result += '\n';
1100             result += "process_name:                   ";
1101             result += Str16ToStr8(it.second->ownProcessContext->processName);
1102             result += '\n';
1103             result += "pid:                            ";
1104             result += std::to_string(it.second->ownProcessContext->pid);
1105             result += '\n';
1106             result += "uid:                            ";
1107             result += std::to_string(it.second->ownProcessContext->uid);
1108         }
1109         result += "\n---------------------------------------------------\n";
1110     }
1111 }
1112 
GetSystemAbilityInfo(int32_t said,std::string & result)1113 void SystemAbilityStateScheduler::GetSystemAbilityInfo(int32_t said, std::string& result)
1114 {
1115     std::shared_ptr<SystemAbilityContext> abilityContext;
1116     if (!GetSystemAbilityContext(said, abilityContext)) {
1117         result.append("said is not exist");
1118         return;
1119     }
1120     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
1121     result += "said:                           ";
1122     result += std::to_string(said);
1123     result += "\n";
1124     result += "sa_state:                       ";
1125     result += SA_STATE_ENUM_STR[static_cast<int32_t>(abilityContext->state)];
1126     result += "\n";
1127     result += "sa_pending_event:               ";
1128     result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(abilityContext->pendingEvent)];
1129     result += "\n";
1130     result += "process_name:                   ";
1131     result += Str16ToStr8(abilityContext->ownProcessContext->processName);
1132     result += "\n";
1133     result += "process_state:                  ";
1134     result += PROCESS_STATE_ENUM_STR[static_cast<int32_t>(abilityContext->ownProcessContext->state)];
1135     result += "\n";
1136     result += "pid:                            ";
1137     result += std::to_string(abilityContext->ownProcessContext->pid);
1138     result += "\n";
1139 }
1140 
GetProcessInfo(const std::string & processName,std::string & result)1141 void SystemAbilityStateScheduler::GetProcessInfo(const std::string& processName, std::string& result)
1142 {
1143     std::shared_ptr<SystemProcessContext> processContext;
1144     if (!GetSystemProcessContext(Str8ToStr16(processName), processContext)) {
1145         result.append("process is not exist");
1146         return;
1147     }
1148     std::lock_guard<std::mutex> autoLock(processContext->processLock);
1149     result += "process_name:                   ";
1150     result += Str16ToStr8(processContext->processName);
1151     result += "\n";
1152     result += "process_state:                  ";
1153     result += PROCESS_STATE_ENUM_STR[static_cast<int32_t>(processContext->state)];
1154     result += "\n";
1155     result += "pid:                            ";
1156     result += std::to_string(processContext->pid);
1157     result += "\n---------------------------------------------------\n";
1158     for (auto it : processContext->saList) {
1159         std::shared_ptr<SystemAbilityContext> abilityContext;
1160         if (!GetSystemAbilityContext(it, abilityContext)) {
1161             result.append("process said is not exist");
1162             return;
1163         }
1164         result += "said:                           ";
1165         result += std::to_string(abilityContext->systemAbilityId);
1166         result += '\n';
1167         result += "sa_state:                       ";
1168         result += SA_STATE_ENUM_STR[static_cast<int32_t>(abilityContext->state)];
1169         result += '\n';
1170         result += "sa_pending_event:               ";
1171         result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(abilityContext->pendingEvent)];
1172         result += "\n---------------------------------------------------\n";
1173     }
1174 }
1175 
GetAllSystemAbilityInfoByState(const std::string & state,std::string & result)1176 void SystemAbilityStateScheduler::GetAllSystemAbilityInfoByState(const std::string& state, std::string& result)
1177 {
1178     std::shared_lock<std::shared_mutex> readLock(abiltyMapLock_);
1179     for (auto it : abilityContextMap_) {
1180         if (it.second == nullptr || SA_STATE_ENUM_STR[static_cast<int32_t>(it.second->state)] != state) {
1181             continue;
1182         }
1183         result += "said:                           ";
1184         result += std::to_string(it.second->systemAbilityId);
1185         result += '\n';
1186         result += "sa_state:                       ";
1187         result += SA_STATE_ENUM_STR[static_cast<int32_t>(it.second->state)];
1188         result += '\n';
1189         result += "sa_pending_event:               ";
1190         result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(it.second->pendingEvent)];
1191         if (it.second->ownProcessContext != nullptr) {
1192             std::lock_guard<std::mutex> autoLock(it.second->ownProcessContext->stateCountLock);
1193             result += '\n';
1194             result += "process_name:                   ";
1195             result += Str16ToStr8(it.second->ownProcessContext->processName);
1196             result += '\n';
1197             result += "pid:                            ";
1198             result += std::to_string(it.second->ownProcessContext->pid);
1199             result += '\n';
1200             result += "uid:                            ";
1201             result += std::to_string(it.second->ownProcessContext->uid);
1202         }
1203         result += "\n---------------------------------------------------\n";
1204     }
1205 }
1206 
SubscribeSystemProcess(const sptr<ISystemProcessStatusChange> & listener)1207 int32_t SystemAbilityStateScheduler::SubscribeSystemProcess(const sptr<ISystemProcessStatusChange>& listener)
1208 {
1209     std::unique_lock<std::shared_mutex> writeLock(listenerSetLock_);
1210     auto iter = std::find_if(processListeners_.begin(), processListeners_.end(),
1211         [listener](sptr<ISystemProcessStatusChange>& item) {
1212         return item->AsObject() == listener->AsObject();
1213     });
1214     if (iter == processListeners_.end()) {
1215         if (processListenerDeath_ != nullptr) {
1216             bool ret = listener->AsObject()->AddDeathRecipient(processListenerDeath_);
1217             HILOGI("SubscribeSystemProcess AddDeathRecipient %{public}s", ret ? "succeed" : "failed");
1218         }
1219         processListeners_.emplace_back(listener);
1220     } else {
1221         HILOGI("SubscribeSystemProcess listener already exists");
1222     }
1223     return ERR_OK;
1224 }
1225 
UnSubscribeSystemProcess(const sptr<ISystemProcessStatusChange> & listener)1226 int32_t SystemAbilityStateScheduler::UnSubscribeSystemProcess(const sptr<ISystemProcessStatusChange>& listener)
1227 {
1228     std::unique_lock<std::shared_mutex> writeLock(listenerSetLock_);
1229     auto iter = std::find_if(processListeners_.begin(), processListeners_.end(),
1230         [listener](sptr<ISystemProcessStatusChange>& item) {
1231         return item->AsObject() == listener->AsObject();
1232     });
1233     if (iter != processListeners_.end()) {
1234         if (processListenerDeath_ != nullptr) {
1235             listener->AsObject()->RemoveDeathRecipient(processListenerDeath_);
1236         }
1237         processListeners_.erase(iter);
1238         HILOGI("UnSubscribeSystemProcess listener remove success");
1239     } else {
1240         HILOGI("UnSubscribeSystemProcess listener not exists");
1241     }
1242     return ERR_OK;
1243 }
1244 
IsSystemProcessNeverStartedLocked(const std::u16string & processName)1245 bool SystemAbilityStateScheduler::IsSystemProcessNeverStartedLocked(const std::u16string& processName)
1246 {
1247     std::shared_ptr<SystemProcessContext> processContext;
1248     if (!GetSystemProcessContext(processName, processContext)) {
1249         return true;
1250     }
1251     return processContext->pid < 0;
1252 }
1253 
ProcessDelayUnloadEvent(int32_t systemAbilityId)1254 int32_t SystemAbilityStateScheduler::ProcessDelayUnloadEvent(int32_t systemAbilityId)
1255 {
1256     std::shared_ptr<SystemAbilityContext> abilityContext;
1257     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
1258         return GET_SA_CONTEXT_FAIL;
1259     }
1260     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
1261     return ProcessDelayUnloadEventLocked(systemAbilityId);
1262 }
1263 
ProcessDelayUnloadEventLocked(int32_t systemAbilityId)1264 int32_t SystemAbilityStateScheduler::ProcessDelayUnloadEventLocked(int32_t systemAbilityId)
1265 {
1266     std::shared_ptr<SystemAbilityContext> abilityContext;
1267     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
1268         return GET_SA_CONTEXT_FAIL;
1269     }
1270     if (abilityContext->unloadRequest == nullptr) {
1271         HILOGE("Scheduler SA:%{public}d unloadRequest is null", abilityContext->systemAbilityId);
1272         return UNLOAD_REQUEST_NULL;
1273     }
1274     if (abilityContext->state != SystemAbilityState::LOADED) {
1275         HILOGW("Scheduler SA:%{public}d can't proc delay unload event", systemAbilityId);
1276         return ERR_OK;
1277     }
1278     HILOGI("Scheduler SA:%{public}d proc delay unload event", systemAbilityId);
1279     int32_t delayTime = 0;
1280     nlohmann::json idleReason;
1281     idleReason[KEY_EVENT_ID] = abilityContext->unloadRequest->unloadEvent.eventId;
1282     idleReason[KEY_NAME] = abilityContext->unloadRequest->unloadEvent.name;
1283     idleReason[KEY_VALUE] = abilityContext->unloadRequest->unloadEvent.value;
1284     idleReason[KEY_EXTRA_DATA_ID] = abilityContext->unloadRequest->unloadEvent.extraDataId;
1285     bool result = SystemAbilityManager::GetInstance()->IdleSystemAbility(abilityContext->systemAbilityId,
1286         abilityContext->ownProcessContext->processName, idleReason, delayTime);
1287     if (!result) {
1288         HILOGE("Scheduler SA:%{public}d idle fail", systemAbilityId);
1289         return IDLE_SA_FAIL;
1290     }
1291     if (delayTime < 0) {
1292         HILOGI("Scheduler SA:%{public}d reject unload", systemAbilityId);
1293         return ERR_OK;
1294     } else if (delayTime == 0) {
1295         HILOGI("Scheduler SA:%{public}d agree unload", systemAbilityId);
1296         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::UNLOADABLE);
1297     } else {
1298         HILOGI("Scheduler SA:%{public}d choose delay unload", systemAbilityId);
1299         return SendDelayUnloadEventLocked(abilityContext->systemAbilityId, fmin(delayTime, MAX_DELAY_TIME));
1300     }
1301 }
1302 
CheckEnableOnce(const OnDemandEvent & event,const std::list<SaControlInfo> & saControlList)1303 void SystemAbilityStateScheduler::CheckEnableOnce(const OnDemandEvent& event,
1304     const std::list<SaControlInfo>& saControlList)
1305 {
1306     sptr<ISystemAbilityLoadCallback> callback(new SystemAbilityLoadCallbackStub());
1307     for (auto& saControl : saControlList) {
1308         int32_t result = ERR_INVALID_VALUE;
1309         if (saControl.ondemandId == START_ON_DEMAND) {
1310             result = CheckStartEnableOnce(event, saControl, callback);
1311         } else if (saControl.ondemandId == STOP_ON_DEMAND) {
1312             result = CheckStopEnableOnce(event, saControl);
1313         } else {
1314             HILOGE("ondemandId error");
1315         }
1316         if (result != ERR_OK) {
1317             HILOGE("process ondemand event failed, ondemandId:%{public}d, SA:%{public}d",
1318                 saControl.ondemandId, saControl.saId);
1319         }
1320     }
1321 }
1322 
CheckStartEnableOnce(const OnDemandEvent & event,const SaControlInfo & saControl,sptr<ISystemAbilityLoadCallback> callback)1323 int32_t SystemAbilityStateScheduler::CheckStartEnableOnce(const OnDemandEvent& event,
1324     const SaControlInfo& saControl, sptr<ISystemAbilityLoadCallback> callback)
1325 {
1326     int32_t result = ERR_INVALID_VALUE;
1327     if (saControl.enableOnce) {
1328         lock_guard<mutex> autoLock(startEnableOnceLock_);
1329         auto iter = startEnableOnceMap_.find(saControl.saId);
1330         if (iter != startEnableOnceMap_.end() && SamgrUtil::IsSameEvent(event, startEnableOnceMap_[saControl.saId])) {
1331             HILOGI("ondemand canceled for enable-once, ondemandId:%{public}d, SA:%{public}d",
1332                 saControl.ondemandId, saControl.saId);
1333             return result;
1334         }
1335         startEnableOnceMap_[saControl.saId].emplace_back(event);
1336         HILOGI("startEnableOnceMap_ add SA:%{public}d, eventId:%{public}d",
1337             saControl.saId, event.eventId);
1338     }
1339     auto callingPid = IPCSkeleton::GetCallingPid();
1340     LoadRequestInfo loadRequestInfo = {LOCAL_DEVICE, callback, saControl.saId, callingPid, event};
1341     result = HandleLoadAbilityEvent(loadRequestInfo);
1342     if (saControl.enableOnce && result != ERR_OK) {
1343         lock_guard<mutex> autoLock(startEnableOnceLock_);
1344         auto& events = startEnableOnceMap_[saControl.saId];
1345         events.remove(event);
1346         if (events.empty()) {
1347             startEnableOnceMap_.erase(saControl.saId);
1348         }
1349         HILOGI("startEnableOnceMap_remove SA:%{public}d, eventId:%{public}d",
1350             saControl.saId, event.eventId);
1351     }
1352     if (result != ERR_OK) {
1353         ReportSamgrSaLoadFail(saControl.saId, IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(),
1354             "ondemand load err:" + ToString(result));
1355     }
1356     return result;
1357 }
1358 
CheckStopEnableOnce(const OnDemandEvent & event,const SaControlInfo & saControl)1359 int32_t SystemAbilityStateScheduler::CheckStopEnableOnce(const OnDemandEvent& event,
1360     const SaControlInfo& saControl)
1361 {
1362     int32_t result = ERR_INVALID_VALUE;
1363     if (saControl.enableOnce) {
1364         lock_guard<mutex> autoLock(stopEnableOnceLock_);
1365         auto iter = stopEnableOnceMap_.find(saControl.saId);
1366         if (iter != stopEnableOnceMap_.end() && SamgrUtil::IsSameEvent(event, stopEnableOnceMap_[saControl.saId])) {
1367             HILOGI("ondemand canceled for enable-once, ondemandId:%{public}d, SA:%{public}d",
1368                 saControl.ondemandId, saControl.saId);
1369             return result;
1370         }
1371         stopEnableOnceMap_[saControl.saId].emplace_back(event);
1372         HILOGI("stopEnableOnceMap_ add SA:%{public}d, eventId:%{public}d",
1373             saControl.saId, event.eventId);
1374     }
1375     auto callingPid = IPCSkeleton::GetCallingPid();
1376     std::shared_ptr<UnloadRequestInfo> unloadRequestInfo =
1377         std::make_shared<UnloadRequestInfo>(event, saControl.saId, callingPid);
1378     result = HandleUnloadAbilityEvent(unloadRequestInfo);
1379     if (saControl.enableOnce && result != ERR_OK) {
1380         lock_guard<mutex> autoLock(stopEnableOnceLock_);
1381         auto& events = stopEnableOnceMap_[saControl.saId];
1382         events.remove(event);
1383         if (events.empty()) {
1384             stopEnableOnceMap_.erase(saControl.saId);
1385         }
1386         HILOGI("stopEnableOnceMap_ remove SA:%{public}d, eventId:%{public}d",
1387             saControl.saId, event.eventId);
1388     }
1389     if (result != ERR_OK) {
1390         ReportSaUnLoadFail(saControl.saId, IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(),
1391             "Ondemand unload err:" + ToString(result));
1392     }
1393     return result;
1394 }
1395 
ProcessEvent(uint32_t eventId)1396 void SystemAbilityStateScheduler::UnloadEventHandler::ProcessEvent(uint32_t eventId)
1397 {
1398     int32_t systemAbilityId = static_cast<int32_t>(eventId);
1399     if (handler_ != nullptr) {
1400         HILOGD("ProcessEvent deltask SA:%{public}d", systemAbilityId);
1401         handler_->DelTask(std::to_string(eventId));
1402     } else {
1403         HILOGE("ProcessEvent handler_ is null");
1404     }
1405     auto stateScheduler = stateScheduler_.lock();
1406     int32_t result = ERR_OK;
1407     if (stateScheduler != nullptr) {
1408         result = stateScheduler->ProcessDelayUnloadEvent(systemAbilityId);
1409     }
1410     if (result != ERR_OK) {
1411         HILOGE("Scheduler SA:%{public}d proc delay unload event fail", systemAbilityId);
1412     }
1413 }
1414 
SendEvent(uint32_t eventId,int64_t extraDataId,uint64_t delayTime)1415 bool SystemAbilityStateScheduler::UnloadEventHandler::SendEvent(uint32_t eventId,
1416     int64_t extraDataId, uint64_t delayTime)
1417 {
1418     if (handler_ == nullptr) {
1419         HILOGE("SystemAbilityStateScheduler SendEvent handler is null!");
1420         return false;
1421     }
1422     auto weak = weak_from_this();
1423     auto task = [weak, eventId] {
1424         auto strong = weak.lock();
1425         if (!strong) {
1426             HILOGW("SystemAbilityStateScheduler is null");
1427             return;
1428         }
1429         strong->ProcessEvent(eventId);
1430     };
1431     return handler_->PostTask(task, std::to_string(eventId), delayTime);
1432 }
1433 
RemoveEvent(uint32_t eventId)1434 void SystemAbilityStateScheduler::UnloadEventHandler::RemoveEvent(uint32_t eventId)
1435 {
1436     if (handler_ == nullptr) {
1437         HILOGE("SystemAbilityStateScheduler SendEvent handler is null!");
1438         return;
1439     }
1440     handler_->RemoveTask(std::to_string(eventId));
1441 }
1442 
HasInnerEvent(uint32_t eventId)1443 bool SystemAbilityStateScheduler::UnloadEventHandler::HasInnerEvent(uint32_t eventId)
1444 {
1445     if (handler_ == nullptr) {
1446         HILOGE("SystemAbilityStateScheduler SendEvent handler is null!");
1447         return false;
1448     }
1449     return handler_->HasInnerEvent(std::to_string(eventId));
1450 }
1451 
CleanFfrt()1452 void SystemAbilityStateScheduler::UnloadEventHandler::CleanFfrt()
1453 {
1454     if (handler_ != nullptr) {
1455         handler_->CleanFfrt();
1456     }
1457 }
1458 
SetFfrt()1459 void SystemAbilityStateScheduler::UnloadEventHandler::SetFfrt()
1460 {
1461     if (handler_ != nullptr) {
1462         handler_->SetFfrt("UnloadEventHandler");
1463     }
1464 }
1465 
1466 }  // namespace OHOS