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