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