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