• 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 "schedule/system_ability_state_scheduler.h"
24 #include "service_control.h"
25 #include "string_ex.h"
26 #include "system_ability_manager.h"
27 
28 namespace OHOS {
29 namespace {
30 constexpr int64_t RESTART_TIME_INTERVAL_LIMIT = 20 * 1000;
31 constexpr int32_t RESTART_TIMES_LIMIT = 4;
32 constexpr int32_t MAX_SUBSCRIBE_COUNT = 256;
33 constexpr int32_t UNLOAD_TIMEOUT_TIME = 5 * 1000;
34 const std::string LOCAL_DEVICE = "local";
35 constexpr int32_t MAX_DELAY_TIME = 5 * 60 * 1000;
36 constexpr const char* CANCEL_UNLOAD = "cancelUnload";
37 const std::string KEY_EVENT_ID = "eventId";
38 const std::string KEY_NAME = "name";
39 const std::string KEY_VALUE = "value";
40 const std::string KEY_EXTRA_DATA_ID = "extraDataId";
41 const std::string KEY_UNLOAD_TIMEOUT = "unloadTimeout";
42 constexpr const char *SA_STATE_ENUM_STR[] = {
43     "NOT_LOADED", "LOADING", "LOADED", "UNLOADABLE", "UNLOADING" };
44 constexpr const char *PROCESS_STATE_ENUM_STR[] = {
45     "NOT_STARTED", "STARTED", "STOPPING" };
46 constexpr const char *PENDINGEVENT_ENUM_STR[] = {
47     "NO_EVENT", "LOAD_ABILITY_EVENT", "UNLOAD_ABILITY_EVENT" };
48 }
Init(const std::list<SaProfile> & saProfiles)49 void SystemAbilityStateScheduler::Init(const std::list<SaProfile>& saProfiles)
50 {
51     HILOGI("[SA Scheduler] init start");
52     InitStateContext(saProfiles);
53     processListenerDeath_ = sptr<IRemoteObject::DeathRecipient>(new SystemProcessListenerDeathRecipient());
54     unloadEventHandler_ = std::make_shared<UnloadEventHandler>(weak_from_this());
55 
56     auto listener =  std::dynamic_pointer_cast<SystemAbilityStateListener>(shared_from_this());
57     stateMachine_ = std::make_shared<SystemAbilityStateMachine>(listener);
58     stateEventHandler_ = std::make_shared<SystemAbilityEventHandler>(stateMachine_);
59 
60     processHandler_ = std::make_shared<FFRTHandler>("ProcessHandler");
61     HILOGI("[SA Scheduler] init end");
62 }
63 
CleanFfrt()64 void SystemAbilityStateScheduler::CleanFfrt()
65 {
66     if (processHandler_ != nullptr) {
67         processHandler_->CleanFfrt();
68     }
69     if (unloadEventHandler_ != nullptr) {
70         unloadEventHandler_->CleanFfrt();
71     }
72 }
73 
SetFfrt()74 void SystemAbilityStateScheduler::SetFfrt()
75 {
76     if (processHandler_ != nullptr) {
77         processHandler_->SetFfrt("ProcessHandler");
78     }
79     if (unloadEventHandler_ != nullptr) {
80         unloadEventHandler_->SetFfrt();
81     }
82 }
83 
InitStateContext(const std::list<SaProfile> & saProfiles)84 void SystemAbilityStateScheduler::InitStateContext(const std::list<SaProfile>& saProfiles)
85 {
86     for (auto& saProfile : saProfiles) {
87         if (saProfile.process.empty()) {
88             continue;
89         }
90         std::unique_lock<std::shared_mutex> processWriteLock(processMapLock_);
91         if (processContextMap_.count(saProfile.process) == 0) {
92             auto processContext = std::make_shared<SystemProcessContext>();
93             processContext->processName = saProfile.process;
94             processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED] = 0;
95             processContext->abilityStateCountMap[SystemAbilityState::LOADING] = 0;
96             processContext->abilityStateCountMap[SystemAbilityState::LOADED] = 0;
97             processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE] = 0;
98             processContext->abilityStateCountMap[SystemAbilityState::UNLOADING] = 0;
99             processContextMap_[saProfile.process] = processContext;
100         }
101         processContextMap_[saProfile.process]->saList.push_back(saProfile.saId);
102         processContextMap_[saProfile.process]->abilityStateCountMap[SystemAbilityState::NOT_LOADED]++;
103         auto abilityContext = std::make_shared<SystemAbilityContext>();
104         abilityContext->systemAbilityId = saProfile.saId;
105         abilityContext->isAutoRestart = saProfile.autoRestart;
106         int32_t delayUnloadTime = LimitDelayUnloadTime(saProfile.stopOnDemand.delayTime);
107         abilityContext->delayUnloadTime = delayUnloadTime;
108         abilityContext->ownProcessContext = processContextMap_[saProfile.process];
109         std::unique_lock<std::shared_mutex> abiltyWriteLock(abiltyMapLock_);
110         abilityContextMap_[saProfile.saId] = abilityContext;
111     }
112 }
113 
LimitDelayUnloadTime(int32_t delayUnloadTime)114 int32_t SystemAbilityStateScheduler::LimitDelayUnloadTime(int32_t delayUnloadTime)
115 {
116     if (delayUnloadTime < 0) {
117         return 0;
118     }
119     if (delayUnloadTime > MAX_DELAY_TIME) {
120         return MAX_DELAY_TIME;
121     }
122     return delayUnloadTime;
123 }
124 
GetSystemAbilityContext(int32_t systemAbilityId,std::shared_ptr<SystemAbilityContext> & abilityContext)125 bool SystemAbilityStateScheduler::GetSystemAbilityContext(int32_t systemAbilityId,
126     std::shared_ptr<SystemAbilityContext>& abilityContext)
127 {
128     std::shared_lock<std::shared_mutex> readLock(abiltyMapLock_);
129     if (abilityContextMap_.count(systemAbilityId) == 0) {
130         HILOGD("[SA Scheduler][SA:%{public}d] not in SA profiles", systemAbilityId);
131         return false;
132     }
133     abilityContext = abilityContextMap_[systemAbilityId];
134     if (abilityContext == nullptr) {
135         HILOGE("[SA Scheduler][SA:%{public}d] context is nullptr", systemAbilityId);
136         return false;
137     }
138     if (abilityContext->ownProcessContext == nullptr) {
139         HILOGE("[SA Scheduler][SA:%{public}d] not in any process", systemAbilityId);
140         return false;
141     }
142     return true;
143 }
144 
GetSystemProcessContext(const std::u16string & processName,std::shared_ptr<SystemProcessContext> & processContext)145 bool SystemAbilityStateScheduler::GetSystemProcessContext(const std::u16string& processName,
146     std::shared_ptr<SystemProcessContext>& processContext)
147 {
148     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
149     if (processContextMap_.count(processName) == 0) {
150         HILOGE("[SA Scheduler][processName:%{public}s] invalid", Str16ToStr8(processName).c_str());
151         return false;
152     }
153     processContext = processContextMap_[processName];
154     if (processContext == nullptr) {
155         HILOGE("[SA Scheduler][processName:%{public}s] context is nullptr", Str16ToStr8(processName).c_str());
156         return false;
157     }
158     return true;
159 }
160 
IsSystemAbilityUnloading(int32_t systemAbilityId)161 bool SystemAbilityStateScheduler::IsSystemAbilityUnloading(int32_t systemAbilityId)
162 {
163     std::shared_ptr<SystemAbilityContext> abilityContext;
164     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
165         return false;
166     }
167     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
168     if (abilityContext->state ==SystemAbilityState::UNLOADING
169         || abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
170         return true;
171     }
172     return false;
173 }
174 
HandleLoadAbilityEvent(int32_t systemAbilityId,bool & isExist)175 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEvent(int32_t systemAbilityId, bool& isExist)
176 {
177     std::shared_ptr<SystemAbilityContext> abilityContext;
178     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
179         isExist = false;
180         return ERR_INVALID_VALUE;
181     }
182     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
183     if (abilityContext->ownProcessContext->state == SystemProcessState::NOT_STARTED) {
184         isExist = false;
185         return ERR_INVALID_VALUE;
186     }
187     if (abilityContext->ownProcessContext->state == SystemProcessState::STARTED
188         && abilityContext->state ==SystemAbilityState::NOT_LOADED) {
189         HILOGD("[SA Scheduler][SA:%{public}d] handle load event by check start", systemAbilityId);
190         bool result = SystemAbilityManager::GetInstance()->DoLoadOnDemandAbility(systemAbilityId, isExist);
191         if (result) {
192             return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADING);
193         }
194         return ERR_INVALID_VALUE;
195     }
196     isExist = true;
197     return ERR_OK;
198 }
199 
HandleLoadAbilityEvent(const LoadRequestInfo & loadRequestInfo)200 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEvent(const LoadRequestInfo& loadRequestInfo)
201 {
202     std::shared_ptr<SystemAbilityContext> abilityContext;
203     if (!GetSystemAbilityContext(loadRequestInfo.systemAbilityId, abilityContext)) {
204         return ERR_INVALID_VALUE;
205     }
206     HILOGI("[SA Scheduler][SA:%{public}d]load event start, callpid: %{public}d, evtid:%{public}d, "
207         "ProcessState:%{public}d, SAState:%{public}d", loadRequestInfo.systemAbilityId, loadRequestInfo.callingPid,
208         loadRequestInfo.loadEvent.eventId, abilityContext->ownProcessContext->state, abilityContext->state);
209     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
210     return HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
211 }
212 
HandleLoadAbilityEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)213 int32_t SystemAbilityStateScheduler::HandleLoadAbilityEventLocked(
214     const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)
215 {
216     if (abilityContext->state ==SystemAbilityState::UNLOADING
217         || abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
218         return PendLoadEventLocked(abilityContext, loadRequestInfo);
219     }
220     nlohmann::json activeReason;
221     activeReason[KEY_EVENT_ID] = loadRequestInfo.loadEvent.eventId;
222     activeReason[KEY_NAME] = loadRequestInfo.loadEvent.name;
223     activeReason[KEY_VALUE] = loadRequestInfo.loadEvent.value;
224     activeReason[KEY_EXTRA_DATA_ID] = loadRequestInfo.loadEvent.extraDataId;
225     int32_t result = ERR_INVALID_VALUE;
226     switch (abilityContext->state) {
227         case SystemAbilityState::LOADING:
228             result = RemovePendingUnloadEventLocked(abilityContext);
229             break;
230         case SystemAbilityState::LOADED:
231             result = RemoveDelayUnloadEventLocked(abilityContext->systemAbilityId);
232             break;
233         case SystemAbilityState::UNLOADABLE:
234             result = ActiveSystemAbilityLocked(abilityContext, activeReason);
235             break;
236         case SystemAbilityState::NOT_LOADED:
237             result = ERR_OK;
238             break;
239         default:
240             result = ERR_INVALID_VALUE;
241             HILOGI("[SA Scheduler][SA:%{public}d] in state %{public}d, cannot load ability",
242                 loadRequestInfo.systemAbilityId, abilityContext->state);
243             break;
244     }
245     if (result == ERR_OK) {
246         return DoLoadSystemAbilityLocked(abilityContext, loadRequestInfo);
247     }
248     return result;
249 }
250 
HandleUnloadAbilityEvent(const UnloadRequestInfo & unloadRequestInfo)251 int32_t SystemAbilityStateScheduler::HandleUnloadAbilityEvent(const UnloadRequestInfo& unloadRequestInfo)
252 {
253     std::shared_ptr<SystemAbilityContext> abilityContext;
254     if (!GetSystemAbilityContext(unloadRequestInfo.systemAbilityId, abilityContext)) {
255         return ERR_INVALID_VALUE;
256     }
257     HILOGI("[SA Scheduler][SA:%{public}d] handle unload event start callingPid:%{public}d, evtid:%{public}d,"
258         "ProcessState:%{public}d, SAState:%{public}d", unloadRequestInfo.systemAbilityId, unloadRequestInfo.callingPid,
259         unloadRequestInfo.unloadEvent.eventId, abilityContext->ownProcessContext->state, abilityContext->state);
260     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
261     return HandleUnloadAbilityEventLocked(abilityContext, unloadRequestInfo);
262 }
263 
HandleUnloadAbilityEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const UnloadRequestInfo & unloadRequestInfo)264 int32_t SystemAbilityStateScheduler::HandleUnloadAbilityEventLocked(
265     const std::shared_ptr<SystemAbilityContext>& abilityContext, const UnloadRequestInfo& unloadRequestInfo)
266 {
267     abilityContext->unloadRequest = unloadRequestInfo;
268     int32_t result = ERR_INVALID_VALUE;
269     switch (abilityContext->state) {
270         case SystemAbilityState::LOADING:
271             result = PendUnloadEventLocked(abilityContext, unloadRequestInfo);
272             break;
273         case SystemAbilityState::LOADED:
274             if (unloadRequestInfo.unloadEvent.eventId == INTERFACE_CALL) {
275                 result = ProcessDelayUnloadEventLocked(abilityContext->systemAbilityId);
276             } else {
277                 result = SendDelayUnloadEventLocked(abilityContext->systemAbilityId, abilityContext->delayUnloadTime);
278             }
279             break;
280         default:
281             result = ERR_OK;
282             HILOGI("[SA Scheduler][SA:%{public}d] in state %{public}d, not need unload ability, callingPid:%{public}d",
283                 abilityContext->systemAbilityId, abilityContext->state, unloadRequestInfo.callingPid);
284             break;
285     }
286     return result;
287 }
288 
HandleCancelUnloadAbilityEvent(int32_t systemAbilityId)289 int32_t SystemAbilityStateScheduler::HandleCancelUnloadAbilityEvent(int32_t systemAbilityId)
290 {
291     HILOGI("[SA Scheduler][SA:%{public}d] cancel unload start", systemAbilityId);
292     std::shared_ptr<SystemAbilityContext> abilityContext;
293     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
294         return ERR_INVALID_VALUE;
295     }
296     nlohmann::json activeReason;
297     activeReason[KEY_EVENT_ID] = INTERFACE_CALL;
298     activeReason[KEY_NAME] = CANCEL_UNLOAD;
299     activeReason[KEY_VALUE] = "";
300     activeReason[KEY_EXTRA_DATA_ID] = -1;
301     int32_t result = ERR_INVALID_VALUE;
302     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
303     switch (abilityContext->state) {
304         case SystemAbilityState::UNLOADABLE:
305             result = ActiveSystemAbilityLocked(abilityContext, activeReason);
306             break;
307         default:
308             result = ERR_OK;
309             HILOGI("[SA Scheduler][SA:%{public}d] in state %{public}d, not need cancel unload",
310                 systemAbilityId, abilityContext->state);
311             break;
312     }
313     return result;
314 }
315 
ActiveSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const nlohmann::json & activeReason)316 int32_t SystemAbilityStateScheduler::ActiveSystemAbilityLocked(
317     const std::shared_ptr<SystemAbilityContext>& abilityContext,
318     const nlohmann::json& activeReason)
319 {
320     bool result = SystemAbilityManager::GetInstance()->ActiveSystemAbility(abilityContext->systemAbilityId,
321         abilityContext->ownProcessContext->processName, activeReason);
322     if (!result) {
323         HILOGE("[SA Scheduler][SA:%{public}d] active ability failed", abilityContext->systemAbilityId);
324         return ERR_INVALID_VALUE;
325     }
326     return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADED);
327 }
328 
SendAbilityStateEvent(int32_t systemAbilityId,AbilityStateEvent event)329 int32_t SystemAbilityStateScheduler::SendAbilityStateEvent(int32_t systemAbilityId, AbilityStateEvent event)
330 {
331     HILOGD("[SA Scheduler][SA:%{public}d] receive state event", systemAbilityId);
332     std::shared_ptr<SystemAbilityContext> abilityContext;
333     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
334         return ERR_INVALID_VALUE;
335     }
336     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
337     return stateEventHandler_->HandleAbilityEventLocked(abilityContext, event);
338 }
339 
SendProcessStateEvent(const ProcessInfo & processInfo,ProcessStateEvent event)340 int32_t SystemAbilityStateScheduler::SendProcessStateEvent(const ProcessInfo& processInfo, ProcessStateEvent event)
341 {
342     HILOGD("[SA Scheduler][process:%{public}s] receive state event",
343         Str16ToStr8(processInfo.processName).c_str());
344     std::shared_ptr<SystemProcessContext> processContext;
345     if (!GetSystemProcessContext(processInfo.processName, processContext)) {
346         return ERR_INVALID_VALUE;
347     }
348     std::lock_guard<std::mutex> autoLock(processContext->processLock);
349     return stateEventHandler_->HandleProcessEventLocked(processContext, processInfo, event);
350 }
351 
SendDelayUnloadEventLocked(uint32_t systemAbilityId,int32_t delayTime)352 int32_t SystemAbilityStateScheduler::SendDelayUnloadEventLocked(uint32_t systemAbilityId, int32_t delayTime)
353 {
354     if (unloadEventHandler_ == nullptr) {
355         HILOGE("[SA Scheduler] unload handler not initialized!");
356         return ERR_INVALID_VALUE;
357     }
358     if (unloadEventHandler_->HasInnerEvent(systemAbilityId)) {
359         return ERR_OK;
360     }
361     HILOGI("[SA Scheduler][SA:%{public}d] send delay unload event", systemAbilityId);
362     bool ret = unloadEventHandler_->SendEvent(systemAbilityId, 0, delayTime);
363     if (!ret) {
364         HILOGE("[SA Scheduler] send event failed!");
365         return ERR_INVALID_VALUE;
366     }
367     return ERR_OK;
368 }
369 
RemoveDelayUnloadEventLocked(uint32_t systemAbilityId)370 int32_t SystemAbilityStateScheduler::RemoveDelayUnloadEventLocked(uint32_t systemAbilityId)
371 {
372     if (unloadEventHandler_ == nullptr) {
373         HILOGE("[SA Scheduler] unload handler not initialized!");
374         return ERR_INVALID_VALUE;
375     }
376     if (!unloadEventHandler_->HasInnerEvent(systemAbilityId)) {
377         return ERR_OK;
378     }
379     HILOGI("[SA Scheduler][SA:%{public}d] remove delay unload event", systemAbilityId);
380     unloadEventHandler_->RemoveEvent(systemAbilityId);
381     return ERR_OK;
382 }
383 
PendLoadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)384 int32_t SystemAbilityStateScheduler::PendLoadEventLocked(const std::shared_ptr<SystemAbilityContext>& abilityContext,
385     const LoadRequestInfo& loadRequestInfo)
386 {
387     HILOGI("[SA Scheduler][SA:%{public}d] save load event", abilityContext->systemAbilityId);
388     if (loadRequestInfo.callback == nullptr) {
389         HILOGW("[SA Scheduler] callback invalid!");
390         return ERR_INVALID_VALUE;
391     }
392     bool isExist = std::any_of(abilityContext->pendingLoadEventList.begin(),
393         abilityContext->pendingLoadEventList.end(), [&loadRequestInfo](const auto& loadEventItem) {
394             return loadRequestInfo.callback->AsObject() == loadEventItem.callback->AsObject();
395         });
396     if (isExist) {
397         HILOGI("[SA Scheduler][SA:%{public}d] already existed callback object", abilityContext->systemAbilityId);
398         return ERR_OK;
399     }
400     auto& count = abilityContext->pendingLoadEventCountMap[loadRequestInfo.callingPid];
401     if (count >= MAX_SUBSCRIBE_COUNT) {
402         HILOGE("[SA Scheduler][SA:%{public}d] pid:%{public}d overflow max callback count!",
403             abilityContext->systemAbilityId, loadRequestInfo.callingPid);
404         return ERR_PERMISSION_DENIED;
405     }
406     ++count;
407     abilityContext->pendingLoadEventList.emplace_back(loadRequestInfo);
408     abilityContext->pendingEvent = PendingEvent::LOAD_ABILITY_EVENT;
409     return ERR_OK;
410 }
411 
PendUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const UnloadRequestInfo & unloadRequestInfo)412 int32_t SystemAbilityStateScheduler::PendUnloadEventLocked(
413     const std::shared_ptr<SystemAbilityContext>& abilityContext, const UnloadRequestInfo& unloadRequestInfo)
414 {
415     HILOGI("[SA Scheduler][SA:%{public}d] save unload event", abilityContext->systemAbilityId);
416     abilityContext->pendingEvent = PendingEvent::UNLOAD_ABILITY_EVENT;
417     abilityContext->pendingUnloadEvent = unloadRequestInfo;
418     return ERR_OK;
419 }
420 
RemovePendingUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)421 int32_t SystemAbilityStateScheduler::RemovePendingUnloadEventLocked(
422     const std::shared_ptr<SystemAbilityContext>& abilityContext)
423 {
424     if (abilityContext->pendingEvent == PendingEvent::UNLOAD_ABILITY_EVENT) {
425         HILOGI("[SA Scheduler][SA:%{public}d] remove pending unload event", abilityContext->systemAbilityId);
426         abilityContext->pendingEvent = PendingEvent::NO_EVENT;
427     }
428     return ERR_OK;
429 }
430 
HandlePendingLoadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)431 int32_t SystemAbilityStateScheduler::HandlePendingLoadEventLocked(
432     const std::shared_ptr<SystemAbilityContext>& abilityContext)
433 {
434     if (abilityContext->pendingEvent != PendingEvent::LOAD_ABILITY_EVENT) {
435         HILOGD("[SA Scheduler][SA:%{public}d] no pending load event", abilityContext->systemAbilityId);
436         return ERR_OK;
437     }
438     HILOGI("[SA Scheduler][SA:%{public}d] handle pending load event start", abilityContext->systemAbilityId);
439     abilityContext->pendingEvent = PendingEvent::NO_EVENT;
440     for (auto& loadRequestInfo : abilityContext->pendingLoadEventList) {
441         int32_t result = HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
442         if (result != ERR_OK) {
443             HILOGE("[SA Scheduler][SA:%{public}d] handle pending load event failed, callingPid: %{public}d",
444                 abilityContext->systemAbilityId, loadRequestInfo.callingPid);
445         }
446     }
447     abilityContext->pendingLoadEventList.clear();
448     abilityContext->pendingLoadEventCountMap.clear();
449     return ERR_OK;
450 }
451 
HandlePendingUnloadEventLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)452 int32_t SystemAbilityStateScheduler::HandlePendingUnloadEventLocked(
453     const std::shared_ptr<SystemAbilityContext>& abilityContext)
454 {
455     if (abilityContext->pendingEvent != PendingEvent::UNLOAD_ABILITY_EVENT) {
456         HILOGD("[SA Scheduler][SA:%{public}d] no pending unload event", abilityContext->systemAbilityId);
457         return ERR_OK;
458     }
459     HILOGI("[SA Scheduler][SA:%{public}d] handle pending unload event start", abilityContext->systemAbilityId);
460     abilityContext->pendingEvent = PendingEvent::NO_EVENT;
461     return HandleUnloadAbilityEventLocked(abilityContext, abilityContext->pendingUnloadEvent);
462 }
463 
DoLoadSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext,const LoadRequestInfo & loadRequestInfo)464 int32_t SystemAbilityStateScheduler::DoLoadSystemAbilityLocked(
465     const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)
466 {
467     int32_t result = ERR_OK;
468     if (loadRequestInfo.deviceId == LOCAL_DEVICE) {
469         HILOGD("[SA Scheduler][SA:%{public}d] load ability from local start", abilityContext->systemAbilityId);
470         result = SystemAbilityManager::GetInstance()->DoLoadSystemAbility(abilityContext->systemAbilityId,
471             abilityContext->ownProcessContext->processName, loadRequestInfo.callback, loadRequestInfo.callingPid,
472             loadRequestInfo.loadEvent);
473     } else {
474         HILOGD("[SA Scheduler][SA:%{public}d] load ability from remote start", abilityContext->systemAbilityId);
475         result = SystemAbilityManager::GetInstance()->DoLoadSystemAbilityFromRpc(loadRequestInfo.deviceId,
476             abilityContext->systemAbilityId, abilityContext->ownProcessContext->processName, loadRequestInfo.callback,
477             loadRequestInfo.loadEvent);
478     }
479     if (result == ERR_OK && abilityContext->state == SystemAbilityState::NOT_LOADED) {
480         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADING);
481     }
482     return result;
483 }
484 
TryUnloadAllSystemAbility(const std::shared_ptr<SystemProcessContext> & processContext)485 int32_t SystemAbilityStateScheduler::TryUnloadAllSystemAbility(
486     const std::shared_ptr<SystemProcessContext>& processContext)
487 {
488     if (processContext == nullptr) {
489         HILOGE("[SA Scheduler] process context is nullptr");
490         return ERR_INVALID_VALUE;
491     }
492     std::lock_guard<std::mutex> autoLock(processContext->processLock);
493     if (CanUnloadAllSystemAbilityLocked(processContext, true)) {
494         return UnloadAllSystemAbilityLocked(processContext);
495     }
496     return ERR_OK;
497 }
498 
CanUnloadAllSystemAbility(const std::shared_ptr<SystemProcessContext> & processContext)499 bool SystemAbilityStateScheduler::CanUnloadAllSystemAbility(
500     const std::shared_ptr<SystemProcessContext>& processContext)
501 {
502     std::shared_lock<std::shared_mutex> sharedLock(processContext->stateCountLock);
503 	return CanUnloadAllSystemAbilityLocked(processContext, true);
504 }
505 
CanUnloadAllSystemAbilityLocked(const std::shared_ptr<SystemProcessContext> & processContext,bool isNeedCheckRecycleStrategy)506 bool SystemAbilityStateScheduler::CanUnloadAllSystemAbilityLocked(
507     const std::shared_ptr<SystemProcessContext>& processContext, bool isNeedCheckRecycleStrategy)
508 {
509     uint32_t notLoadAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED];
510     uint32_t unloadableAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE];
511     if (unloadableAbilityCount == 0) {
512         return false;
513     }
514     if (notLoadAbilityCount + unloadableAbilityCount == processContext->saList.size()) {
515         if (isNeedCheckRecycleStrategy) {
516             return CheckSaIsImmediatelyRecycle(processContext);
517         } else {
518             return true;
519         }
520     }
521     HILOGI("[SA Scheduler][process:%{public}s] SA num: %{public}zu, notloaded: %{public}d, unloadable: %{public}d",
522         Str16ToStr8(processContext->processName).c_str(), processContext->saList.size(), notLoadAbilityCount,
523         unloadableAbilityCount);
524     return false;
525 }
526 
CheckSaIsImmediatelyRecycle(const std::shared_ptr<SystemProcessContext> & processContext)527 bool SystemAbilityStateScheduler::CheckSaIsImmediatelyRecycle(
528     const std::shared_ptr<SystemProcessContext>& processContext)
529 {
530     for (auto& saId: processContext->saList) {
531         if (SystemAbilityManager::GetInstance()->CheckSaIsImmediatelyRecycle(saId)) {
532             return true;
533         }
534     }
535     HILOGI("CheckSaIsImmediatelyRecycle is false");
536     return false;
537 }
538 
PostTryUnloadAllAbilityTask(const std::shared_ptr<SystemProcessContext> & processContext)539 int32_t SystemAbilityStateScheduler::PostTryUnloadAllAbilityTask(
540     const std::shared_ptr<SystemProcessContext>& processContext)
541 {
542     bool result = processHandler_->PostTask([this, processContext] () {
543         int32_t ret = TryUnloadAllSystemAbility(processContext);
544         if (ret != ERR_OK) {
545             HILOGE("[SA Scheduler][process:%{public}s] unload all SA failed",
546                 Str16ToStr8(processContext->processName).c_str());
547         }
548     });
549     if (!result) {
550         HILOGW("[SA Scheduler][process:%{public}s] post task failed",
551             Str16ToStr8(processContext->processName).c_str());
552         return ERR_INVALID_VALUE;
553     }
554     return ERR_OK;
555 }
556 
PostUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext> & processContext)557 int32_t SystemAbilityStateScheduler::PostUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext>& processContext)
558 {
559     auto timeoutTask = [this, processContext] () {
560         std::string name = KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName);
561         if (processHandler_ != nullptr) {
562             HILOGD("TimeoutTask deltask proc:%{public}s", name.c_str());
563             processHandler_->DelTask(name);
564         } else {
565             HILOGE("TimeoutTask processHandler_ is null");
566         }
567         std::lock_guard<std::mutex> autoLock(processContext->processLock);
568         if (processContext->state == SystemProcessState::STOPPING) {
569             HILOGW("[SA Scheduler][process:%{public}s] unload SA timeout",
570                 Str16ToStr8(processContext->processName).c_str());
571             int32_t result = KillSystemProcessLocked(processContext);
572             HILOGI("[SA Scheduler][process:%{public}s] kill timeout process ret: %{public}d",
573                 Str16ToStr8(processContext->processName).c_str(), result);
574         }
575     };
576     bool ret = processHandler_->PostTask(timeoutTask, KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName),
577         UNLOAD_TIMEOUT_TIME);
578     if (!ret) {
579         HILOGW("[SA Scheduler][process:%{public}s] post timeout task failed",
580             Str16ToStr8(processContext->processName).c_str());
581         return ERR_INVALID_VALUE;
582     }
583     return ERR_OK;
584 }
585 
RemoveUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext> & processContext)586 void SystemAbilityStateScheduler::RemoveUnloadTimeoutTask(const std::shared_ptr<SystemProcessContext>& processContext)
587 {
588     processHandler_->RemoveTask(KEY_UNLOAD_TIMEOUT + Str16ToStr8(processContext->processName));
589 }
590 
PostTryKillProcessTask(const std::shared_ptr<SystemProcessContext> & processContext)591 int32_t SystemAbilityStateScheduler::PostTryKillProcessTask(
592     const std::shared_ptr<SystemProcessContext>& processContext)
593 {
594     bool result = processHandler_->PostTask([this, processContext] () {
595         int32_t ret = TryKillSystemProcess(processContext);
596         if (ret != ERR_OK) {
597             HILOGE("[SA Scheduler][process:%{public}s] kill process failed",
598                 Str16ToStr8(processContext->processName).c_str());
599         }
600     });
601     if (!result) {
602         HILOGW("[SA Scheduler][process:%{public}s] post task failed",
603             Str16ToStr8(processContext->processName).c_str());
604         return ERR_INVALID_VALUE;
605     }
606     return ERR_OK;
607 }
608 
UnloadAllSystemAbilityLocked(const std::shared_ptr<SystemProcessContext> & processContext)609 int32_t SystemAbilityStateScheduler::UnloadAllSystemAbilityLocked(
610     const std::shared_ptr<SystemProcessContext>& processContext)
611 {
612     HILOGI("[SA Scheduler][process:%{public}s] unload all SA", Str16ToStr8(processContext->processName).c_str());
613     for (auto& saId : processContext->saList) {
614         std::shared_ptr<SystemAbilityContext> abilityContext;
615         if (!GetSystemAbilityContext(saId, abilityContext)) {
616             continue;
617         }
618         int32_t result = ERR_OK;
619         if (abilityContext->state == SystemAbilityState::UNLOADABLE) {
620             result = DoUnloadSystemAbilityLocked(abilityContext);
621         }
622         if (result != ERR_OK) {
623             HILOGE("[SA Scheduler][SA:%{public}d] unload failed", saId);
624         }
625     }
626     PostUnloadTimeoutTask(processContext);
627     return stateMachine_->ProcessStateTransitionLocked(processContext, SystemProcessState::STOPPING);
628 }
629 
DoUnloadSystemAbilityLocked(const std::shared_ptr<SystemAbilityContext> & abilityContext)630 int32_t SystemAbilityStateScheduler::DoUnloadSystemAbilityLocked(
631     const std::shared_ptr<SystemAbilityContext>& abilityContext)
632 {
633     int32_t result = ERR_OK;
634     HILOGI("[SA Scheduler][SA:%{public}d] unload ability start", abilityContext->systemAbilityId);
635     result = SystemAbilityManager::GetInstance()->DoUnloadSystemAbility(abilityContext->systemAbilityId,
636         abilityContext->ownProcessContext->processName, abilityContext->unloadRequest.unloadEvent);
637     if (result == ERR_OK) {
638         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::UNLOADING);
639     }
640     return result;
641 }
642 
UnloadAllIdleSystemAbility()643 int32_t SystemAbilityStateScheduler::UnloadAllIdleSystemAbility()
644 {
645     HILOGI("[SA Scheduler] UnloadAllIdleSystemAbility");
646     int32_t result = ERR_OK;
647     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
648     for (auto it : processContextMap_) {
649         auto& processContext = it.second;
650         if (processContext == nullptr) {
651             continue;
652         }
653 
654         int32_t ret = ERR_OK;
655         std::lock_guard<std::mutex> autoLock(processContext->processLock);
656         if (CanUnloadAllSystemAbilityLocked(processContext)) {
657             ret = UnloadAllSystemAbilityLocked(processContext);
658         }
659         if (ret != ERR_OK) {
660             result = ret;
661             HILOGI("[SA Scheduler][process:%{public}s] unload all SA fail",
662                 Str16ToStr8(processContext->processName).c_str());
663         }
664     }
665     return result;
666 }
667 
TryKillSystemProcess(const std::shared_ptr<SystemProcessContext> & processContext)668 int32_t SystemAbilityStateScheduler::TryKillSystemProcess(
669     const std::shared_ptr<SystemProcessContext>& processContext)
670 {
671     if (processContext == nullptr) {
672         HILOGE("[SA Scheduler] process context is nullptr");
673         return ERR_INVALID_VALUE;
674     }
675     std::lock_guard<std::mutex> autoLock(processContext->processLock);
676     if (CanKillSystemProcessLocked(processContext)) {
677         return KillSystemProcessLocked(processContext);
678     }
679     return ERR_OK;
680 }
681 
CanKillSystemProcess(const std::shared_ptr<SystemProcessContext> & processContext)682 bool SystemAbilityStateScheduler::CanKillSystemProcess(
683     const std::shared_ptr<SystemProcessContext>& processContext)
684 {
685     std::shared_lock<std::shared_mutex> sharedLock(processContext->stateCountLock);
686 	return CanKillSystemProcessLocked(processContext);
687 }
688 
CanKillSystemProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)689 bool SystemAbilityStateScheduler::CanKillSystemProcessLocked(
690     const std::shared_ptr<SystemProcessContext>& processContext)
691 {
692     uint32_t notLoadAbilityCount = processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED];
693     HILOGI("[SA Scheduler][process:%{public}s] SA num: %{public}zu, not loaded num: %{public}d",
694         Str16ToStr8(processContext->processName).c_str(), processContext->saList.size(), notLoadAbilityCount);
695     if (notLoadAbilityCount == processContext->saList.size()) {
696         return true;
697     }
698     return false;
699 }
700 
KillSystemProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)701 int32_t SystemAbilityStateScheduler::KillSystemProcessLocked(
702     const std::shared_ptr<SystemProcessContext>& processContext)
703 {
704     int64_t begin = GetTickCount();
705     int32_t result = ERR_OK;
706     result = ServiceControlWithExtra(Str16ToStr8(processContext->processName).c_str(), ServiceAction::STOP, nullptr, 0);
707     HILOGI("[SA Scheduler][process:%{public}s] kill process, pid: %{public}d, uid: %{public}d, result: %{public}d "
708         "spend %{public}" PRId64 " ms", Str16ToStr8(processContext->processName).c_str(), processContext->pid,
709         processContext->uid, result, GetTickCount() - begin);
710     return result;
711 }
712 
CanRestartProcessLocked(const std::shared_ptr<SystemProcessContext> & processContext)713 bool SystemAbilityStateScheduler::CanRestartProcessLocked(const std::shared_ptr<SystemProcessContext>& processContext)
714 {
715     if (!processContext->enableRestart) {
716         return false;
717     }
718     int64_t curtime = GetTickCount();
719     if (processContext->restartCountsCtrl.size() < RESTART_TIMES_LIMIT) {
720         processContext->restartCountsCtrl.push_back(curtime);
721         return true;
722     } else if (processContext->restartCountsCtrl.size() == RESTART_TIMES_LIMIT) {
723         if (curtime - processContext->restartCountsCtrl.front() < RESTART_TIME_INTERVAL_LIMIT) {
724             processContext->enableRestart = false;
725             return false;
726         }
727         processContext->restartCountsCtrl.push_back(curtime);
728         processContext->restartCountsCtrl.pop_front();
729         return true;
730     } else {
731         HILOGE("[SA Scheduler][process:%{public}s] unkown error",
732             Str16ToStr8(processContext->processName).c_str());
733     }
734     return false;
735 }
736 
GetAbnormallyDiedAbilityLocked(std::shared_ptr<SystemProcessContext> & processContext,std::list<std::shared_ptr<SystemAbilityContext>> & abnormallyDiedAbilityList)737 int32_t SystemAbilityStateScheduler::GetAbnormallyDiedAbilityLocked(
738     std::shared_ptr<SystemProcessContext>& processContext,
739     std::list<std::shared_ptr<SystemAbilityContext>>& abnormallyDiedAbilityList)
740 {
741     for (auto& saId : processContext->saList) {
742         std::shared_ptr<SystemAbilityContext> abilityContext;
743         if (!GetSystemAbilityContext(saId, abilityContext)) {
744             continue;
745         }
746         if (abilityContext->state == SystemAbilityState::LOADED
747             || abilityContext->state == SystemAbilityState::LOADING) {
748             HILOGI("[SA Scheduler][SA:%{public}d] abnormally died", abilityContext->systemAbilityId);
749             if (abilityContext->isAutoRestart) {
750                 HILOGI("[SA Scheduler][SA:%{public}d] is auto restart", abilityContext->systemAbilityId);
751                 abnormallyDiedAbilityList.emplace_back(abilityContext);
752             }
753         }
754     }
755     return ERR_OK;
756 }
757 
758 
HandleAbnormallyDiedAbilityLocked(std::shared_ptr<SystemProcessContext> & processContext,std::list<std::shared_ptr<SystemAbilityContext>> & abnormallyDiedAbilityList)759 int32_t SystemAbilityStateScheduler::HandleAbnormallyDiedAbilityLocked(
760     std::shared_ptr<SystemProcessContext>& processContext,
761     std::list<std::shared_ptr<SystemAbilityContext>>& abnormallyDiedAbilityList)
762 {
763     if (abnormallyDiedAbilityList.empty()) {
764         return ERR_OK;
765     }
766     if (!CanRestartProcessLocked(processContext)) {
767         HILOGW("[SA Scheduler][process:%{public}s] can't restart: More than 4 restarts in 20 seconds",
768             Str16ToStr8(processContext->processName).c_str());
769         return ERR_OK;
770     }
771     OnDemandEvent onDemandEvent = {INTERFACE_CALL, "restart"};
772     sptr<ISystemAbilityLoadCallback> callback(new SystemAbilityLoadCallbackStub());
773     for (auto& abilityContext : abnormallyDiedAbilityList) {
774         // Actively remove SA to prevent restart failure if the death recipient of SA is not processed in time.
775         SystemAbilityManager::GetInstance()->RemoveDiedSystemAbility(abilityContext->systemAbilityId);
776         LoadRequestInfo loadRequestInfo = {abilityContext->systemAbilityId,
777             LOCAL_DEVICE, callback, -1, onDemandEvent};
778         HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);
779     }
780     return ERR_OK;
781 }
782 
NotifyProcessStarted(const std::shared_ptr<SystemProcessContext> & processContext)783 void SystemAbilityStateScheduler::NotifyProcessStarted(const std::shared_ptr<SystemProcessContext>& processContext)
784 {
785     std::shared_lock<std::shared_mutex> readLock(listenerSetLock_);
786     for (auto& listener : processListeners_) {
787         if (listener->AsObject() != nullptr) {
788             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
789                 processContext->uid};
790             listener->OnSystemProcessStarted(systemProcessInfo);
791         }
792     }
793 }
794 
NotifyProcessStopped(const std::shared_ptr<SystemProcessContext> & processContext)795 void SystemAbilityStateScheduler::NotifyProcessStopped(const std::shared_ptr<SystemProcessContext>& processContext)
796 {
797     std::shared_lock<std::shared_mutex> readLock(listenerSetLock_);
798     for (auto& listener : processListeners_) {
799         if (listener->AsObject() != nullptr) {
800             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
801                 processContext->uid};
802             listener->OnSystemProcessStopped(systemProcessInfo);
803         }
804     }
805 }
806 
OnProcessStartedLocked(const std::u16string & processName)807 void SystemAbilityStateScheduler::OnProcessStartedLocked(const std::u16string& processName)
808 {
809     HILOGI("[SA Scheduler][process:%{public}s] started", Str16ToStr8(processName).c_str());
810     std::shared_ptr<SystemProcessContext> processContext;
811     if (!GetSystemProcessContext(processName, processContext)) {
812         return;
813     }
814     NotifyProcessStarted(processContext);
815 }
816 
OnProcessNotStartedLocked(const std::u16string & processName)817 void SystemAbilityStateScheduler::OnProcessNotStartedLocked(const std::u16string& processName)
818 {
819     HILOGI("[SA Scheduler][process:%{public}s] stopped", Str16ToStr8(processName).c_str());
820     std::shared_ptr<SystemProcessContext> processContext;
821     if (!GetSystemProcessContext(processName, processContext)) {
822         return;
823     }
824     NotifyProcessStopped(processContext);
825     RemoveUnloadTimeoutTask(processContext);
826 
827     std::list<std::shared_ptr<SystemAbilityContext>> abnormallyDiedAbilityList;
828     GetAbnormallyDiedAbilityLocked(processContext, abnormallyDiedAbilityList);
829     for (auto& saId : processContext->saList) {
830         std::shared_ptr<SystemAbilityContext> abilityContext;
831         if (!GetSystemAbilityContext(saId, abilityContext)) {
832             continue;
833         }
834         int32_t result = stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::NOT_LOADED);
835         if (result != ERR_OK) {
836             continue;
837         }
838         HandlePendingLoadEventLocked(abilityContext);
839     }
840     HandleAbnormallyDiedAbilityLocked(processContext, abnormallyDiedAbilityList);
841 }
842 
HandleAbilityDiedEvent(int32_t systemAbilityId)843 int32_t SystemAbilityStateScheduler::HandleAbilityDiedEvent(int32_t systemAbilityId)
844 {
845     HILOGD("[SA Scheduler][SA:%{public}d] handle ability died event", systemAbilityId);
846     return ERR_OK;
847 }
848 
OnAbilityNotLoadedLocked(int32_t systemAbilityId)849 void SystemAbilityStateScheduler::OnAbilityNotLoadedLocked(int32_t systemAbilityId)
850 {
851     HILOGI("[SA Scheduler][SA:%{public}d] not loaded", systemAbilityId);
852     std::shared_ptr<SystemAbilityContext> abilityContext;
853     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
854         return;
855     }
856     RemoveDelayUnloadEventLocked(abilityContext->systemAbilityId);
857     RemovePendingUnloadEventLocked(abilityContext);
858     if (abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {
859         PostTryKillProcessTask(abilityContext->ownProcessContext);
860     } else if (abilityContext->ownProcessContext->state == SystemProcessState::STARTED) {
861         PostTryUnloadAllAbilityTask(abilityContext->ownProcessContext);
862     }
863 }
864 
OnAbilityLoadedLocked(int32_t systemAbilityId)865 void SystemAbilityStateScheduler::OnAbilityLoadedLocked(int32_t systemAbilityId)
866 {
867     HILOGI("[SA Scheduler][SA:%{public}d] loaded", systemAbilityId);
868     std::shared_ptr<SystemAbilityContext> abilityContext;
869     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
870         return;
871     }
872     HandlePendingUnloadEventLocked(abilityContext);
873 }
874 
OnAbilityUnloadableLocked(int32_t systemAbilityId)875 void SystemAbilityStateScheduler::OnAbilityUnloadableLocked(int32_t systemAbilityId)
876 {
877     HILOGI("[SA Scheduler][SA:%{public}d] unloadable", systemAbilityId);
878     std::shared_ptr<SystemAbilityContext> abilityContext;
879     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
880         return;
881     }
882     PostTryUnloadAllAbilityTask(abilityContext->ownProcessContext);
883 }
884 
GetSystemProcessInfo(int32_t systemAbilityId,SystemProcessInfo & systemProcessInfo)885 int32_t SystemAbilityStateScheduler::GetSystemProcessInfo(int32_t systemAbilityId,
886     SystemProcessInfo& systemProcessInfo)
887 {
888     HILOGI("[SA Scheduler] get process info by [SA:%{public}d]", systemAbilityId);
889     std::shared_ptr<SystemAbilityContext> abilityContext;
890     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
891         HILOGI("[SA Scheduler] get ability context by said failed");
892         return ERR_INVALID_VALUE;
893     }
894     std::shared_ptr<SystemProcessContext> processContext = abilityContext->ownProcessContext;
895     std::lock_guard<std::mutex> autoLock(processContext->processLock);
896     systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
897                 processContext->uid};
898     return ERR_OK;
899 }
900 
GetRunningSystemProcess(std::list<SystemProcessInfo> & systemProcessInfos)901 int32_t SystemAbilityStateScheduler::GetRunningSystemProcess(std::list<SystemProcessInfo>& systemProcessInfos)
902 {
903     HILOGI("[SA Scheduler] get running process");
904     std::shared_lock<std::shared_mutex> readLock(processMapLock_);
905     for (auto it : processContextMap_) {
906         auto& processContext = it.second;
907         if (processContext == nullptr) {
908             continue;
909         }
910         std::lock_guard<std::mutex> autoLock(processContext->processLock);
911         if (processContext->state == SystemProcessState::STARTED) {
912             SystemProcessInfo systemProcessInfo = {Str16ToStr8(processContext->processName), processContext->pid,
913                 processContext->uid};
914             systemProcessInfos.emplace_back(systemProcessInfo);
915         }
916     }
917     return ERR_OK;
918 }
919 
GetAllSystemAbilityInfo(std::string & result)920 void SystemAbilityStateScheduler::GetAllSystemAbilityInfo(std::string& result)
921 {
922     std::shared_lock<std::shared_mutex> readLock(abiltyMapLock_);
923     for (auto it : abilityContextMap_) {
924         if (it.second == nullptr) {
925             continue;
926         }
927         result += "said:                           ";
928         result += std::to_string(it.second->systemAbilityId);
929         result += "\n";
930         result += "sa_state:                       ";
931         result += SA_STATE_ENUM_STR[static_cast<int32_t>(it.second->state)];
932         result += "\n";
933         result += "sa_pending_event:               ";
934         result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(it.second->pendingEvent)];
935         result += "\n---------------------------------------------------\n";
936     }
937 }
938 
GetSystemAbilityInfo(int32_t said,std::string & result)939 void SystemAbilityStateScheduler::GetSystemAbilityInfo(int32_t said, std::string& result)
940 {
941     std::shared_ptr<SystemAbilityContext> abilityContext;
942     if (!GetSystemAbilityContext(said, abilityContext)) {
943         result.append("said is not exist");
944         return;
945     }
946     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
947     result += "said:                           ";
948     result += std::to_string(said);
949     result += "\n";
950     result += "sa_state:                       ";
951     result += SA_STATE_ENUM_STR[static_cast<int32_t>(abilityContext->state)];
952     result += "\n";
953     result += "sa_pending_event:               ";
954     result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(abilityContext->pendingEvent)];
955     result += "\n";
956     result += "process_name:                   ";
957     result += Str16ToStr8(abilityContext->ownProcessContext->processName);
958     result += "\n";
959     result += "process_state:                  ";
960     result += PROCESS_STATE_ENUM_STR[static_cast<int32_t>(abilityContext->ownProcessContext->state)];
961     result += "\n";
962     result += "pid:                            ";
963     result += std::to_string(abilityContext->ownProcessContext->pid);
964     result += "\n";
965 }
966 
GetProcessInfo(const std::string & processName,std::string & result)967 void SystemAbilityStateScheduler::GetProcessInfo(const std::string& processName, std::string& result)
968 {
969     std::shared_ptr<SystemProcessContext> processContext;
970     if (!GetSystemProcessContext(Str8ToStr16(processName), processContext)) {
971         result.append("process is not exist");
972         return;
973     }
974     std::lock_guard<std::mutex> autoLock(processContext->processLock);
975     result += "process_name:                   ";
976     result += Str16ToStr8(processContext->processName);
977     result += "\n";
978     result += "process_state:                  ";
979     result += PROCESS_STATE_ENUM_STR[static_cast<int32_t>(processContext->state)];
980     result += "\n";
981     result += "pid:                            ";
982     result += std::to_string(processContext->pid);
983     result += "\n---------------------------------------------------\n";
984     for (auto it : processContext->saList) {
985         std::shared_ptr<SystemAbilityContext> abilityContext;
986         if (!GetSystemAbilityContext(it, abilityContext)) {
987             result.append("process said is not exist");
988             return;
989         }
990         result += "said:                           ";
991         result += std::to_string(abilityContext->systemAbilityId);
992         result += '\n';
993         result += "sa_state:                       ";
994         result += SA_STATE_ENUM_STR[static_cast<int32_t>(abilityContext->state)];
995         result += '\n';
996         result += "sa_pending_event:               ";
997         result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(abilityContext->pendingEvent)];
998         result += "\n---------------------------------------------------\n";
999     }
1000 }
1001 
GetAllSystemAbilityInfoByState(const std::string & state,std::string & result)1002 void SystemAbilityStateScheduler::GetAllSystemAbilityInfoByState(const std::string& state, std::string& result)
1003 {
1004     std::shared_lock<std::shared_mutex> readLock(abiltyMapLock_);
1005     for (auto it : abilityContextMap_) {
1006         if (it.second == nullptr || SA_STATE_ENUM_STR[static_cast<int32_t>(it.second->state)] != state) {
1007             continue;
1008         }
1009         result += "said:                           ";
1010         result += std::to_string(it.second->systemAbilityId);
1011         result += '\n';
1012         result += "sa_state:                       ";
1013         result += SA_STATE_ENUM_STR[static_cast<int32_t>(it.second->state)];
1014         result += '\n';
1015         result += "sa_pending_event:               ";
1016         result += PENDINGEVENT_ENUM_STR[static_cast<int32_t>(it.second->pendingEvent)];
1017         result += "\n---------------------------------------------------\n";
1018     }
1019 }
1020 
SubscribeSystemProcess(const sptr<ISystemProcessStatusChange> & listener)1021 int32_t SystemAbilityStateScheduler::SubscribeSystemProcess(const sptr<ISystemProcessStatusChange>& listener)
1022 {
1023     std::unique_lock<std::shared_mutex> writeLock(listenerSetLock_);
1024     auto iter = std::find_if(processListeners_.begin(), processListeners_.end(),
1025         [listener](sptr<ISystemProcessStatusChange>& item) {
1026         return item->AsObject() == listener->AsObject();
1027     });
1028     if (iter == processListeners_.end()) {
1029         if (processListenerDeath_ != nullptr) {
1030             bool ret = listener->AsObject()->AddDeathRecipient(processListenerDeath_);
1031             HILOGI("SubscribeSystemProcess AddDeathRecipient %{public}s", ret ? "succeed" : "failed");
1032         }
1033         processListeners_.emplace_back(listener);
1034     } else {
1035         HILOGI("SubscribeSystemProcess listener already exists");
1036     }
1037     return ERR_OK;
1038 }
1039 
UnSubscribeSystemProcess(const sptr<ISystemProcessStatusChange> & listener)1040 int32_t SystemAbilityStateScheduler::UnSubscribeSystemProcess(const sptr<ISystemProcessStatusChange>& listener)
1041 {
1042     std::unique_lock<std::shared_mutex> writeLock(listenerSetLock_);
1043     auto iter = std::find_if(processListeners_.begin(), processListeners_.end(),
1044         [listener](sptr<ISystemProcessStatusChange>& item) {
1045         return item->AsObject() == listener->AsObject();
1046     });
1047     if (iter != processListeners_.end()) {
1048         if (processListenerDeath_ != nullptr) {
1049             listener->AsObject()->RemoveDeathRecipient(processListenerDeath_);
1050         }
1051         processListeners_.erase(iter);
1052         HILOGI("UnSubscribeSystemProcess listener remove success");
1053     } else {
1054         HILOGI("UnSubscribeSystemProcess listener not exists");
1055     }
1056     return ERR_OK;
1057 }
1058 
IsSystemProcessNeverStartedLocked(const std::u16string & processName)1059 bool SystemAbilityStateScheduler::IsSystemProcessNeverStartedLocked(const std::u16string& processName)
1060 {
1061     std::shared_ptr<SystemProcessContext> processContext;
1062     if (!GetSystemProcessContext(processName, processContext)) {
1063         return true;
1064     }
1065     return processContext->pid < 0;
1066 }
1067 
ProcessDelayUnloadEvent(int32_t systemAbilityId)1068 int32_t SystemAbilityStateScheduler::ProcessDelayUnloadEvent(int32_t systemAbilityId)
1069 {
1070     std::shared_ptr<SystemAbilityContext> abilityContext;
1071     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
1072         return ERR_INVALID_VALUE;
1073     }
1074     std::lock_guard<std::mutex> autoLock(abilityContext->ownProcessContext->processLock);
1075 	return ProcessDelayUnloadEventLocked(systemAbilityId);
1076 }
1077 
ProcessDelayUnloadEventLocked(int32_t systemAbilityId)1078 int32_t SystemAbilityStateScheduler::ProcessDelayUnloadEventLocked(int32_t systemAbilityId)
1079 {
1080     std::shared_ptr<SystemAbilityContext> abilityContext;
1081     if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) {
1082         return ERR_INVALID_VALUE;
1083     }
1084     if (abilityContext->state != SystemAbilityState::LOADED) {
1085         HILOGW("[SA Scheduler][SA:%{public}d] cannot process delay unload event", systemAbilityId);
1086         return ERR_OK;
1087     }
1088     HILOGI("[SA Scheduler][SA:%{public}d] process delay unload event", systemAbilityId);
1089     int32_t delayTime = 0;
1090     nlohmann::json idleReason;
1091     idleReason[KEY_EVENT_ID] = abilityContext->unloadRequest.unloadEvent.eventId;
1092     idleReason[KEY_NAME] = abilityContext->unloadRequest.unloadEvent.name;
1093     idleReason[KEY_VALUE] = abilityContext->unloadRequest.unloadEvent.value;
1094     idleReason[KEY_EXTRA_DATA_ID] = abilityContext->unloadRequest.unloadEvent.extraDataId;
1095     bool result = SystemAbilityManager::GetInstance()->IdleSystemAbility(abilityContext->systemAbilityId,
1096         abilityContext->ownProcessContext->processName, idleReason, delayTime);
1097     if (!result) {
1098         HILOGE("[SA Scheduler][SA:%{public}d] idle system ability failed", systemAbilityId);
1099         return ERR_INVALID_VALUE;
1100     }
1101     if (delayTime < 0) {
1102         HILOGI("[SA Scheduler][SA:%{public}d] reject unload", systemAbilityId);
1103         return ERR_OK;
1104     } else if (delayTime == 0) {
1105         HILOGI("[SA Scheduler][SA:%{public}d] agree unload", systemAbilityId);
1106         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::UNLOADABLE);
1107     } else {
1108         HILOGI("[SA Scheduler][SA:%{public}d] choose delay unload", systemAbilityId);
1109         return SendDelayUnloadEventLocked(abilityContext->systemAbilityId, fmin(delayTime, MAX_DELAY_TIME));
1110     }
1111 }
1112 
ProcessEvent(uint32_t eventId)1113 void SystemAbilityStateScheduler::UnloadEventHandler::ProcessEvent(uint32_t eventId)
1114 {
1115     int32_t systemAbilityId = static_cast<int32_t>(eventId);
1116     if (handler_ != nullptr) {
1117         HILOGD("ProcessEvent deltask SA:%{public}d", systemAbilityId);
1118         handler_->DelTask(std::to_string(eventId));
1119     } else {
1120         HILOGE("ProcessEvent handler_ is null");
1121     }
1122     auto stateScheduler = stateScheduler_.lock();
1123     int32_t result = ERR_OK;
1124     if (stateScheduler != nullptr) {
1125         result = stateScheduler->ProcessDelayUnloadEvent(systemAbilityId);
1126     }
1127     if (result != ERR_OK) {
1128         HILOGE("[SA Scheduler][SA:%{public}d] process delay unload event failed", systemAbilityId);
1129     }
1130 }
1131 
SendEvent(uint32_t eventId,int64_t extraDataId,uint64_t delayTime)1132 bool SystemAbilityStateScheduler::UnloadEventHandler::SendEvent(uint32_t eventId, int64_t extraDataId, uint64_t delayTime)
1133 {
1134     if (handler_ == nullptr) {
1135         HILOGE("SystemAbilityStateScheduler SendEvent handler is null!");
1136         return false;
1137     }
1138     auto task = std::bind(&SystemAbilityStateScheduler::UnloadEventHandler::ProcessEvent, this, eventId);
1139     return handler_->PostTask(task, std::to_string(eventId), delayTime);
1140 }
1141 
RemoveEvent(uint32_t eventId)1142 void SystemAbilityStateScheduler::UnloadEventHandler::RemoveEvent(uint32_t eventId)
1143 {
1144     if (handler_ == nullptr) {
1145         HILOGE("SystemAbilityStateScheduler SendEvent handler is null!");
1146         return;
1147     }
1148     handler_->RemoveTask(std::to_string(eventId));
1149 }
1150 
HasInnerEvent(uint32_t eventId)1151 bool SystemAbilityStateScheduler::UnloadEventHandler::HasInnerEvent(uint32_t eventId)
1152 {
1153     if (handler_ == nullptr) {
1154         HILOGE("SystemAbilityStateScheduler SendEvent handler is null!");
1155         return false;
1156     }
1157     return handler_->HasInnerEvent(std::to_string(eventId));
1158 }
1159 
CleanFfrt()1160 void SystemAbilityStateScheduler::UnloadEventHandler::CleanFfrt()
1161 {
1162     if (handler_ != nullptr) {
1163         handler_->CleanFfrt();
1164     }
1165 }
1166 
SetFfrt()1167 void SystemAbilityStateScheduler::UnloadEventHandler::SetFfrt()
1168 {
1169     if (handler_ != nullptr) {
1170         handler_->SetFfrt("UnloadEventHandler");
1171     }
1172 }
1173 
1174 }  // namespace OHOS