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