1 /*
2 * Copyright (c) 2021 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 "local_ability_manager.h"
17
18 #include <chrono>
19 #include <cinttypes>
20 #include <dlfcn.h>
21 #include <iostream>
22 #include <sys/types.h>
23 #include <thread>
24
25 #include "datetime_ex.h"
26 #include "errors.h"
27 #include "hitrace_meter.h"
28 #include "ipc_skeleton.h"
29 #include "iservice_registry.h"
30 #include "safwk_log.h"
31 #include "file_ex.h"
32 #include "string_ex.h"
33 #include "hisysevent_adapter.h"
34 #include "system_ability_ondemand_reason.h"
35 #include "local_ability_manager_dumper.h"
36 #include "timer.h"
37 #include "hisysevent_adapter.h"
38 #include "system_ability_definition.h"
39 #include "samgr_xcollie.h"
40 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
41 #include <sys/syscall.h>
42 #include <sys/resource.h>
43 #endif
44
45 namespace OHOS {
46 using std::u16string;
47 using std::string;
48 using std::vector;
49
50 namespace {
51 constexpr int32_t RETRY_TIMES_FOR_ONDEMAND = 10;
52 constexpr int32_t RETRY_TIMES_FOR_SAMGR = 50;
53 constexpr int32_t DEFAULT_SAID = -1;
54 constexpr int32_t UNUSED_RESIDENT_TIMER_INTERVAL = 1000 * 60 * 10;
55 constexpr int32_t UNUSED_ONDEMAND_TIMER_INTERVAL = 1000 * 60 * 1;
56 constexpr int32_t ONDEMAND_SA_UNUSED_TIMEOUT_LOWLIMIT = UNUSED_ONDEMAND_TIMER_INTERVAL;
57 constexpr int32_t ONDEMAND_SA_UNUSED_TIMEOUT_UPLIMIT = 1000 * 60 * 120;
58 constexpr int32_t RESIDENT_SA_UNUSED_TIMEOUT = 1000 * 60 * 10;
59 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_SAMGR_ONE_TIME(200);
60 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_ONDEMAND_ONE_TIME(100);
61 constexpr int32_t TIME_S_TO_MS = 1000;
62 constexpr int32_t MAX_DEPEND_TIMEOUT = 65;
63 constexpr int32_t MAX_CHECK_TIMEOUT = 10;
64
65 constexpr int32_t MAX_SA_STARTUP_TIME = 100;
66 constexpr int32_t SUFFIX_LENGTH = 5; // .json length
67 constexpr uint32_t FFRT_DUMP_INFO_ALL = 0;
68 constexpr int FFRT_BUFFER_SIZE = 512 * 1024;
69
70 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
71 constexpr int OPEN_SO_PRIO = -20;
72 constexpr int NORMAL_PRIO = 0;
73 #endif
74
75 constexpr const char* PROFILES_DIR = "/system/profile/";
76 constexpr const char* DEFAULT_DIR = "/system/usr/";
77 constexpr const char* PREFIX = PROFILES_DIR;
78 constexpr const char* SUFFIX = "_trust.json";
79
80 constexpr const char* ONDEMAND_WORKER = "SaOndemand";
81 constexpr const char* INIT_POOL = "SaInit";
82
83 constexpr const char* EVENT_ID = "eventId";
84 constexpr const char* NAME = "name";
85 constexpr const char* VALUE = "value";
86 constexpr const char* EXTRA_DATA_ID = "extraDataId";
87
88 enum {
89 BOOT_START = 1,
90 CORE_START = 2,
91 OTHER_START = 3,
92 };
93 }
94
95 IMPLEMENT_SINGLE_INSTANCE(LocalAbilityManager);
96
97 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
SetThreadPrio(int priority)98 static void SetThreadPrio(int priority)
99 {
100 int tid = syscall(SYS_gettid);
101 LOGI("set tid:%{public}d priority:%{public}d.", tid, priority);
102 if (setpriority(PRIO_PROCESS, tid, priority) != 0) {
103 LOGE("set tid:%{public}d priority:%{public}d failed.", tid, priority);
104 }
105 }
106 #endif
107
LocalAbilityManager()108 LocalAbilityManager::LocalAbilityManager()
109 {
110 profileParser_ = std::make_shared<ParseUtil>();
111 initPool_ = std::make_unique<ThreadPool>(INIT_POOL);
112 }
113
~LocalAbilityManager()114 LocalAbilityManager::~LocalAbilityManager()
115 {
116 if (idleTimer_ != nullptr) {
117 idleTimer_->Shutdown();
118 }
119 }
120
DoStartSAProcess(const std::string & profilePath,int32_t saId)121 void LocalAbilityManager::DoStartSAProcess(const std::string& profilePath, int32_t saId)
122 {
123 startBegin_ = GetTickCount();
124 HILOGD(TAG, "SA:%{public}d", saId);
125 string realProfilePath = "";
126 if (!CheckAndGetProfilePath(profilePath, realProfilePath)) {
127 ReportSaMainExit("DoStartSAProcess invalid path");
128 HILOGE(TAG, "DoStartSAProcess invalid path");
129 return;
130 }
131 {
132 std::string traceTag = GetTraceTag(realProfilePath);
133 HITRACE_METER_NAME(HITRACE_TAG_SAMGR, traceTag);
134 bool ret = InitSystemAbilityProfiles(realProfilePath, saId);
135 if (!ret) {
136 ReportSaMainExit("InitSaProfiles no right profile");
137 HILOGE(TAG, "InitSystemAbilityProfiles no right profile, will exit");
138 return;
139 }
140 {
141 SamgrXCollie samgrXCollie("safwk--CheckSamgrReady", MAX_CHECK_TIMEOUT);
142 ret = CheckSystemAbilityManagerReady();
143 }
144 if (!ret) {
145 ReportSaMainExit("CheckSamgrReady failed");
146 HILOGE(TAG, "CheckSystemAbilityManagerReady failed! will exit");
147 return;
148 }
149 ret = Run(saId);
150 if (!ret) {
151 ReportSaMainExit("SA Run failed");
152 HILOGE(TAG, "Run failed! will exit");
153 return;
154 }
155 }
156
157 StartTimedQuery();
158 IPCSkeleton::JoinWorkThread();
159 HILOGE(TAG, "JoinWorkThread stop, will exit");
160 }
161
GetTraceTag(const std::string & profilePath)162 std::string LocalAbilityManager::GetTraceTag(const std::string& profilePath)
163 {
164 std::vector<std::string> libPathVec;
165 string traceTag = "default_proc";
166 SplitStr(profilePath, "/", libPathVec);
167 if ((libPathVec.size() > 0)) {
168 traceTag = libPathVec[libPathVec.size() - 1];
169 auto size = traceTag.length();
170 if (size > SUFFIX_LENGTH) {
171 return traceTag.substr(0, size - SUFFIX_LENGTH);
172 }
173 }
174 return traceTag;
175 }
176
CheckAndGetProfilePath(const std::string & profilePath,std::string & realProfilePath)177 bool LocalAbilityManager::CheckAndGetProfilePath(const std::string& profilePath, std::string& realProfilePath)
178 {
179 if (profilePath.length() > PATH_MAX) {
180 HILOGE(TAG, "profilePath length too long!");
181 return false;
182 }
183 char realPath[PATH_MAX] = {'\0'};
184 if (realpath(profilePath.c_str(), realPath) == nullptr) {
185 HILOGE(TAG, "file path does not exist!");
186 return false;
187 }
188 // realProfilePath must begin with "/system/profile/" or begin with "/system/usr/"
189 realProfilePath = realPath;
190 if (realProfilePath.find(PROFILES_DIR) != 0 && realProfilePath.find(DEFAULT_DIR) != 0) {
191 HILOGE(TAG, "file path is not matched");
192 return false;
193 }
194 return true;
195 }
196
CheckSystemAbilityManagerReady()197 bool LocalAbilityManager::CheckSystemAbilityManagerReady()
198 {
199 int32_t timeout = RETRY_TIMES_FOR_SAMGR;
200 constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_SAMGR_ONE_TIME).count();
201 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
202 while (samgrProxy == nullptr) {
203 HILOGI(TAG, "%{public}s waiting for samgr...", Str16ToStr8(procName_).c_str());
204 if (timeout > 0) {
205 usleep(duration);
206 samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
207 } else {
208 HILOGE(TAG, "wait for samgr time out (10s)");
209 return false;
210 }
211 timeout--;
212 }
213 return true;
214 }
215
InitSystemAbilityProfiles(const std::string & profilePath,int32_t saId)216 bool LocalAbilityManager::InitSystemAbilityProfiles(const std::string& profilePath, int32_t saId)
217 {
218 LOGD("InitProfiles parse sa profiles!");
219 int64_t begin = GetTickCount();
220 bool ret = profileParser_->ParseSaProfiles(profilePath);
221 if (!ret) {
222 HILOGW(TAG, "ParseSaProfiles failed!");
223 return false;
224 }
225
226 procName_ = profileParser_->GetProcessName();
227 auto saInfos = profileParser_->GetAllSaProfiles();
228 std::string process = Str16ToStr8(procName_);
229 LOGI("InitProfiles proc:%{public}s end,spend:%{public}" PRId64 "ms", process.c_str(), (GetTickCount() - begin));
230 std::string path = PREFIX + process + SUFFIX;
231 bool isExist = profileParser_->CheckPathExist(path);
232 if (isExist) {
233 CheckTrustSa(path, process, saInfos);
234 }
235 return InitializeSaProfiles(saId);
236 }
237
InitializeSaProfiles(int32_t saId)238 bool LocalAbilityManager::InitializeSaProfiles(int32_t saId)
239 {
240 if (saId != DEFAULT_SAID) {
241 return InitializeOnDemandSaProfile(saId);
242 } else {
243 return InitializeRunOnCreateSaProfiles(BOOT_START);
244 }
245 }
246
CheckTrustSa(const std::string & path,const std::string & process,const std::list<SaProfile> & saInfos)247 void LocalAbilityManager::CheckTrustSa(const std::string& path, const std::string& process,
248 const std::list<SaProfile>& saInfos)
249 {
250 HILOGD(TAG, "CheckTrustSa start");
251 std::map<std::u16string, std::set<int32_t>> trustMaps;
252 bool ret = profileParser_->ParseTrustConfig(path, trustMaps);
253 if (ret && !trustMaps.empty()) {
254 // 1.get allowed sa set in the process
255 const auto& saSets = trustMaps[Str8ToStr16(process)];
256 // 2.check to-load sa in the allowed sa set, and if to-load sa not in the allowed, will remove and not load it
257 for (const auto& saInfo : saInfos) {
258 if (saSets.find(saInfo.saId) == saSets.end()) {
259 HILOGW(TAG, "SA:%{public}d not allow to load in %{public}s", saInfo.saId, process.c_str());
260 profileParser_->RemoveSaProfile(saInfo.saId);
261 }
262 }
263 }
264 }
265
ClearResource()266 void LocalAbilityManager::ClearResource()
267 {
268 profileParser_->ClearResource();
269 }
270
AddAbility(SystemAbility * ability)271 bool LocalAbilityManager::AddAbility(SystemAbility* ability)
272 {
273 if (ability == nullptr) {
274 HILOGW(TAG, "try to add null ability!");
275 return false;
276 }
277
278 int32_t saId = ability->GetSystemAbilitId();
279 SaProfile saProfile;
280 bool ret = profileParser_->GetProfile(saId, saProfile);
281 if (!ret) {
282 return false;
283 }
284 std::unique_lock<std::shared_mutex> writeLock(localAbilityMapLock_);
285 auto iter = localAbilityMap_.find(saId);
286 if (iter != localAbilityMap_.end()) {
287 HILOGW(TAG, "try to add existed SA:%{public}d!", saId);
288 return false;
289 }
290 HILOGI(TAG, "set profile attr for SA:%{public}d", saId);
291 ability->SetLibPath(saProfile.libPath);
292 ability->SetRunOnCreate(saProfile.runOnCreate);
293 ability->SetDependSa(saProfile.dependSa);
294 ability->SetDependTimeout(saProfile.dependTimeout);
295 ability->SetDistributed(saProfile.distributed);
296 ability->SetDumpLevel(saProfile.dumpLevel);
297 ability->SetCapability(saProfile.capability);
298 ability->SetPermission(saProfile.permission);
299 localAbilityMap_.emplace(saId, ability);
300 return true;
301 }
302
RemoveAbility(int32_t systemAbilityId)303 bool LocalAbilityManager::RemoveAbility(int32_t systemAbilityId)
304 {
305 if (systemAbilityId <= 0) {
306 HILOGW(TAG, "invalid systemAbilityId");
307 return false;
308 }
309 std::unique_lock<std::shared_mutex> writeLock(localAbilityMapLock_);
310 (void)localAbilityMap_.erase(systemAbilityId);
311 return true;
312 }
313
AddSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)314 bool LocalAbilityManager::AddSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
315 {
316 if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
317 HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!", systemAbilityId, listenerSaId);
318 return false;
319 }
320 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
321 if (samgrProxy == nullptr) {
322 HILOGE(TAG, "failed to get samgrProxy");
323 return false;
324 }
325 bool isNeedNotify = false;
326 size_t listenerListSize = 0;
327 {
328 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
329 std::lock_guard<std::mutex> autoLock(listenerLock_);
330 auto& listenerList = localListenerMap_[systemAbilityId];
331 auto iter = std::find_if(listenerList.begin(), listenerList.end(),
332 [listenerSaId](const std::pair<int32_t, ListenerState>& listener) {
333 return listener.first == listenerSaId;
334 });
335 if (listenerList.size() > 0) {
336 sptr<IRemoteObject> object = samgrProxy->CheckSystemAbility(systemAbilityId);
337 if (object != nullptr) {
338 isNeedNotify = true;
339 }
340 }
341 if (iter == listenerList.end()) {
342 listenerList.push_back({listenerSaId,
343 (isNeedNotify) ? ListenerState::NOTIFIED : ListenerState::INIT});
344 }
345 listenerListSize = listenerList.size();
346 LOGI("AddSaListener SA:%{public}d,listenerSA:%{public}d,size:%{public}zu", systemAbilityId, listenerSaId,
347 listenerList.size());
348 }
349 if (listenerListSize > 1) {
350 if (isNeedNotify) {
351 NotifyAbilityListener(systemAbilityId, listenerSaId, "",
352 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
353 }
354 return true;
355 }
356 int32_t ret = samgrProxy->SubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
357 if (ret) {
358 HILOGE(TAG, "failed to subscribe SA:%{public}d, process name:%{public}s", systemAbilityId,
359 Str16ToStr8(procName_).c_str());
360 return false;
361 }
362 return true;
363 }
364
RemoveSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)365 bool LocalAbilityManager::RemoveSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
366 {
367 if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
368 HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!",
369 systemAbilityId, listenerSaId);
370 return false;
371 }
372 {
373 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
374 std::lock_guard<std::mutex> autoLock(listenerLock_);
375 if (localListenerMap_.count(systemAbilityId) == 0) {
376 return true;
377 }
378 auto& listenerList = localListenerMap_[systemAbilityId];
379 auto iter = std::find_if(listenerList.begin(), listenerList.end(),
380 [listenerSaId](const std::pair<int32_t, ListenerState>& listener) {
381 return listener.first == listenerSaId;
382 });
383 if (iter != listenerList.end()) {
384 listenerList.erase(iter);
385 }
386 HILOGI(TAG, "SA:%{public}d, size:%{public}zu", systemAbilityId,
387 listenerList.size());
388 if (!listenerList.empty()) {
389 return true;
390 }
391 localListenerMap_.erase(systemAbilityId);
392 }
393
394 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
395 if (samgrProxy == nullptr) {
396 HILOGE(TAG, "failed to get samgrProxy");
397 return false;
398 }
399 int32_t ret = samgrProxy->UnSubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
400 if (ret) {
401 HILOGE(TAG, "failed to unsubscribe SA:%{public}d, process name:%{public}s",
402 systemAbilityId, Str16ToStr8(procName_).c_str());
403 return false;
404 }
405 return true;
406 }
407
NotifyAbilityListener(int32_t systemAbilityId,int32_t listenerSaId,const std::string & deviceId,int32_t code)408 void LocalAbilityManager::NotifyAbilityListener(int32_t systemAbilityId, int32_t listenerSaId,
409 const std::string& deviceId, int32_t code)
410 {
411 LOGI("NotifyListener SA:%{public}d,listenerSA:%{public}d,code:%{public}d", systemAbilityId, listenerSaId, code);
412 auto ability = GetAbility(listenerSaId);
413 if (ability == nullptr) {
414 HILOGE(TAG, "failed to get listener SA:%{public}d", listenerSaId);
415 return;
416 }
417
418 switch (code) {
419 case ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY: {
420 HILOGD(TAG, "OnAddSystemAbility, SA:%{public}d", listenerSaId);
421 ability->OnAddSystemAbility(systemAbilityId, deviceId);
422 break;
423 }
424 case ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY: {
425 HILOGD(TAG, "OnRemoveSystemAbility, SA:%{public}d", listenerSaId);
426 ability->OnRemoveSystemAbility(systemAbilityId, deviceId);
427 break;
428 }
429 default:
430 break;
431 }
432 }
433
FindAndNotifyAbilityListeners(int32_t systemAbilityId,const std::string & deviceId,int32_t code)434 void LocalAbilityManager::FindAndNotifyAbilityListeners(int32_t systemAbilityId,
435 const std::string& deviceId, int32_t code)
436 {
437 HILOGD(TAG, "SA:%{public}d, code:%{public}d", systemAbilityId, code);
438 int64_t begin = GetTickCount();
439 std::vector<int32_t> listenerSaIdVec;
440 {
441 std::lock_guard<std::mutex> autoLock(listenerLock_);
442 auto iter = localListenerMap_.find(systemAbilityId);
443 if (iter == localListenerMap_.end()) {
444 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
445 return;
446 }
447 if (code == ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY) {
448 for (auto& listener : iter->second) {
449 if (listener.second == ListenerState::INIT) {
450 listenerSaIdVec.push_back(listener.first);
451 listener.second = ListenerState::NOTIFIED;
452 } else {
453 HILOGW(TAG, "listener SA:%{public}d has been notified add", listener.first);
454 }
455 }
456 } else if (code == ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY) {
457 for (auto& listener : iter->second) {
458 listenerSaIdVec.push_back(listener.first);
459 if (listener.second == ListenerState::NOTIFIED) {
460 listener.second = ListenerState::INIT;
461 }
462 }
463 }
464 }
465 for (auto listenerSaId : listenerSaIdVec) {
466 NotifyAbilityListener(systemAbilityId, listenerSaId, deviceId, code);
467 }
468 LOGI("FindNotifyListeners SA:%{public}d,size:%{public}zu,code:%{public}d,spend:%{public}" PRId64 "ms",
469 systemAbilityId, listenerSaIdVec.size(), code, GetTickCount() - begin);
470 }
471
OnStartAbility(int32_t systemAbilityId)472 bool LocalAbilityManager::OnStartAbility(int32_t systemAbilityId)
473 {
474 HILOGD(TAG, "try to start SA:%{public}d", systemAbilityId);
475 auto ability = GetAbility(systemAbilityId);
476 if (ability == nullptr) {
477 return false;
478 }
479 ability->Start();
480 return true;
481 }
482
OnStopAbility(int32_t systemAbilityId)483 bool LocalAbilityManager::OnStopAbility(int32_t systemAbilityId)
484 {
485 HILOGD(TAG, "try to stop SA:%{public}d", systemAbilityId);
486 auto ability = GetAbility(systemAbilityId);
487 if (ability == nullptr) {
488 return false;
489 }
490 ability->Stop();
491 return true;
492 }
493
GetAbility(int32_t systemAbilityId)494 SystemAbility* LocalAbilityManager::GetAbility(int32_t systemAbilityId)
495 {
496 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
497 auto it = localAbilityMap_.find(systemAbilityId);
498 if (it == localAbilityMap_.end()) {
499 HILOGW(TAG, "SA:%{public}d not register", systemAbilityId);
500 return nullptr;
501 }
502
503 return it->second;
504 }
505
GetRunningStatus(int32_t systemAbilityId)506 bool LocalAbilityManager::GetRunningStatus(int32_t systemAbilityId)
507 {
508 auto ability = GetAbility(systemAbilityId);
509 if (ability == nullptr) {
510 return false;
511 }
512
513 return ability->GetRunningStatus();
514 }
515
StartOndemandSystemAbility(int32_t systemAbilityId)516 void LocalAbilityManager::StartOndemandSystemAbility(int32_t systemAbilityId)
517 {
518 pthread_setname_np(pthread_self(), ONDEMAND_WORKER);
519 LOGD("StartOndemandSa LoadSaLib SA:%{public}d library", systemAbilityId);
520 int64_t begin = GetTickCount();
521 bool isExist = profileParser_->LoadSaLib(systemAbilityId);
522 LOGI("StartOndemandSa LoadSaLib SA:%{public}d,spend:%{public}" PRId64 "ms",
523 systemAbilityId, (GetTickCount() - begin));
524 if (isExist) {
525 int32_t timeout = RETRY_TIMES_FOR_ONDEMAND;
526 constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_ONDEMAND_ONE_TIME).count();
527 {
528 auto it = localAbilityMap_.begin();
529 {
530 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
531 it = localAbilityMap_.find(systemAbilityId);
532 }
533 while (it == localAbilityMap_.end()) {
534 HILOGI(TAG, "waiting for SA:%{public}d...", systemAbilityId);
535 if (timeout > 0) {
536 usleep(duration);
537 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
538 it = localAbilityMap_.find(systemAbilityId);
539 } else {
540 HILOGE(TAG, "waiting for SA:%{public}d time out (1s)", systemAbilityId);
541 return;
542 }
543 timeout--;
544 }
545 }
546
547 if (!OnStartAbility(systemAbilityId)) {
548 HILOGE(TAG, "failed to start SA:%{public}d", systemAbilityId);
549 }
550 } else {
551 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
552 }
553 }
554
StartAbility(int32_t systemAbilityId,const std::string & eventStr)555 bool LocalAbilityManager::StartAbility(int32_t systemAbilityId, const std::string& eventStr)
556 {
557 LOGI("StartSa recv start SA:%{public}d req", systemAbilityId);
558 nlohmann::json startReason = ParseUtil::StringToJsonObj(eventStr);
559 SetStartReason(systemAbilityId, startReason);
560 auto task = [this, systemAbilityId] {this->StartOndemandSystemAbility(systemAbilityId);};
561 std::thread thread(task);
562 thread.detach();
563 return true;
564 }
565
StopOndemandSystemAbility(int32_t systemAbilityId)566 void LocalAbilityManager::StopOndemandSystemAbility(int32_t systemAbilityId)
567 {
568 pthread_setname_np(pthread_self(), ONDEMAND_WORKER);
569 if (!OnStopAbility(systemAbilityId)) {
570 HILOGE(TAG, "failed to stop SA:%{public}d", systemAbilityId);
571 }
572 }
573
StopAbility(int32_t systemAbilityId,const std::string & eventStr)574 bool LocalAbilityManager::StopAbility(int32_t systemAbilityId, const std::string& eventStr)
575 {
576 LOGI("StopSa recv stop SA:%{public}d req", systemAbilityId);
577 nlohmann::json stopReason = ParseUtil::StringToJsonObj(eventStr);
578 SetStopReason(systemAbilityId, stopReason);
579 auto task = [this, systemAbilityId] {this->StopOndemandSystemAbility(systemAbilityId);};
580 std::thread thread(task);
581 thread.detach();
582 return true;
583 }
584
ActiveAbility(int32_t systemAbilityId,const nlohmann::json & activeReason)585 bool LocalAbilityManager::ActiveAbility(int32_t systemAbilityId,
586 const nlohmann::json& activeReason)
587 {
588 LOGD("ActiveSa:%{public}d", systemAbilityId);
589 auto ability = GetAbility(systemAbilityId);
590 if (ability == nullptr) {
591 return false;
592 }
593 SystemAbilityOnDemandReason onDemandActiveReason = JsonToOnDemandReason(activeReason);
594 ability->Active(onDemandActiveReason);
595 return true;
596 }
597
IdleAbility(int32_t systemAbilityId,const nlohmann::json & idleReason,int32_t & delayTime)598 bool LocalAbilityManager::IdleAbility(int32_t systemAbilityId,
599 const nlohmann::json& idleReason, int32_t& delayTime)
600 {
601 HILOGD(TAG, "idle SA:%{public}d", systemAbilityId);
602 auto ability = GetAbility(systemAbilityId);
603 if (ability == nullptr) {
604 return false;
605 }
606 SystemAbilityOnDemandReason onDemandIdleReason = JsonToOnDemandReason(idleReason);
607 ability->Idle(onDemandIdleReason, delayTime);
608 return true;
609 }
610
JsonToOnDemandReason(const nlohmann::json & reasonJson)611 SystemAbilityOnDemandReason LocalAbilityManager::JsonToOnDemandReason(const nlohmann::json& reasonJson)
612 {
613 SystemAbilityOnDemandReason onDemandStartReason;
614 if (reasonJson.contains(EVENT_ID) && reasonJson[EVENT_ID].is_number()) {
615 onDemandStartReason.SetId(reasonJson[EVENT_ID]);
616 }
617 if (reasonJson.contains(NAME) && reasonJson[NAME].is_string()) {
618 onDemandStartReason.SetName(reasonJson[NAME]);
619 }
620 if (reasonJson.contains(VALUE) && reasonJson[VALUE].is_string()) {
621 onDemandStartReason.SetValue(reasonJson[VALUE]);
622 }
623 if (reasonJson.contains(EXTRA_DATA_ID) && reasonJson[EXTRA_DATA_ID].is_number()) {
624 onDemandStartReason.SetExtraDataId(reasonJson[EXTRA_DATA_ID]);
625 }
626 return onDemandStartReason;
627 }
628
InitializeOnDemandSaProfile(int32_t saId)629 bool LocalAbilityManager::InitializeOnDemandSaProfile(int32_t saId)
630 {
631 int64_t begin = GetTickCount();
632 LOGD("InitOnDemandSa LoadSaLib SA:%{public}d", saId);
633 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
634 SetThreadPrio(OPEN_SO_PRIO);
635 #endif
636 bool result = profileParser_->LoadSaLib(saId);
637 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
638 SetThreadPrio(NORMAL_PRIO);
639 #endif
640 LOGI("InitOnDemandSa LoadSaLib SA:%{public}d finished,spend:%{public}"
641 PRId64 "ms", saId, (GetTickCount() - begin));
642 if (!result) {
643 LOGW("InitOnDemandSa LoadSaLib fail,SA:{public}%d", saId);
644 return false;
645 }
646 SaProfile saProfile;
647 bool ret = profileParser_->GetProfile(saId, saProfile);
648 if (ret) {
649 return InitializeSaProfilesInnerLocked(saProfile);
650 }
651 return false;
652 }
653
InitializeSaProfilesInnerLocked(const SaProfile & saProfile)654 bool LocalAbilityManager::InitializeSaProfilesInnerLocked(const SaProfile& saProfile)
655 {
656 std::unique_lock<std::shared_mutex> readLock(localAbilityMapLock_);
657 auto iterProfile = localAbilityMap_.find(saProfile.saId);
658 if (iterProfile == localAbilityMap_.end()) {
659 HILOGW(TAG, "SA:%{public}d not found", saProfile.saId);
660 return false;
661 }
662 auto systemAbility = iterProfile->second;
663 if (systemAbility == nullptr) {
664 HILOGW(TAG, "SA:%{public}d is null", saProfile.saId);
665 return false;
666 }
667 if (saProfile.bootPhase > OTHER_START) {
668 HILOGW(TAG, "invalid boot phase: %{public}d", saProfile.bootPhase);
669 return false;
670 }
671 auto& saList = abilityPhaseMap_[saProfile.bootPhase];
672 saList.emplace_back(systemAbility);
673 return true;
674 }
675
CheckDependencyStatus(const vector<int32_t> & dependSa)676 vector<int32_t> LocalAbilityManager::CheckDependencyStatus(const vector<int32_t>& dependSa)
677 {
678 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
679 if (samgrProxy == nullptr) {
680 HILOGW(TAG, "failed to get samgrProxy");
681 return dependSa;
682 }
683
684 vector<int32_t> checkSaStatusResult;
685 for (const auto& saId : dependSa) {
686 if (CheckInputSysAbilityId(saId)) {
687 sptr<IRemoteObject> saObject = samgrProxy->CheckSystemAbility(saId);
688 if (saObject == nullptr) {
689 checkSaStatusResult.emplace_back(saId);
690 }
691 } else {
692 HILOGW(TAG, "dependency's SA:%{public}d is invalid", saId);
693 }
694 }
695 return checkSaStatusResult;
696 }
697
StartDependSaTask(SystemAbility * ability)698 void LocalAbilityManager::StartDependSaTask(SystemAbility* ability)
699 {
700 if (ability == nullptr) {
701 HILOGE(TAG, "ability is null");
702 return;
703 }
704 int64_t start = GetTickCount();
705 int64_t dependTimeout = ability->GetDependTimeout();
706 size_t lastSize = CheckDependencyStatus(ability->GetDependSa()).size();
707 HILOGI(TAG, "SA:%{public}d's depend timeout:%{public}" PRId64 " ms,depend size:%{public}zu",
708 ability->GetSystemAbilitId(), dependTimeout, lastSize);
709 {
710 SamgrXCollie samgrXCollie("DependSaTimeout_" + ToString(ability->GetSystemAbilitId()), MAX_DEPEND_TIMEOUT);
711 while (lastSize > 0) {
712 int64_t end = GetTickCount();
713 int64_t duration = ((end >= start) ? (end - start) : (INT64_MAX - end + start));
714 if (duration < dependTimeout) {
715 usleep(CHECK_DEPENDENT_SA_PERIOD);
716 } else {
717 break;
718 }
719 vector<int32_t> temp = CheckDependencyStatus(ability->GetDependSa());
720 size_t curSize = temp.size();
721 if (curSize != lastSize) {
722 HILOGI(TAG, "SA:%{public}d's depend left:%{public}zu", ability->GetSystemAbilitId(), curSize);
723 }
724 lastSize = curSize;
725 }
726 }
727 vector<int32_t> unpreparedDeps = CheckDependencyStatus(ability->GetDependSa());
728 if (unpreparedDeps.empty()) {
729 HILOGI(TAG, "SA:%{public}d's depend all start", ability->GetSystemAbilitId());
730 ability->Start();
731 } else {
732 for (const auto& unpreparedDep : unpreparedDeps) {
733 HILOGI(TAG, "%{public}d's dependency:%{public}d not started in %{public}d ms",
734 ability->GetSystemAbilitId(), unpreparedDep, ability->GetDependTimeout());
735 }
736 }
737 }
738
StartSystemAbilityTask(SystemAbility * ability)739 void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
740 {
741 if (ability != nullptr) {
742 HILOGD(TAG, "StartSystemAbility is called for SA:%{public}d", ability->GetSystemAbilitId());
743 if (ability->GetDependSa().empty()) {
744 ability->Start();
745 } else {
746 StartDependSaTask(ability);
747 }
748 KHILOGI(TAG, "%{public}s SA:%{public}d init finished, %{public}" PRId64 " ms",
749 Str16ToStr8(procName_).c_str(), ability->GetSystemAbilitId(), (GetTickCount() - startBegin_));
750 }
751
752 std::lock_guard<std::mutex> lock(startPhaseLock_);
753 if (startTaskNum_ > 0) {
754 --startTaskNum_;
755 }
756 startPhaseCV_.notify_one();
757 }
758
RegisterOnDemandSystemAbility(int32_t saId)759 void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId)
760 {
761 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
762 if (samgrProxy == nullptr) {
763 HILOGI(TAG, "failed to get samgrProxy");
764 return;
765 }
766
767 auto& saProfileList = profileParser_->GetAllSaProfiles();
768 for (const auto& saProfile : saProfileList) {
769 if (NeedRegisterOnDemand(saProfile, saId)) {
770 HILOGD(TAG, "register ondemand SA:%{public}d to samgr", saProfile.saId);
771 int32_t ret = samgrProxy->AddOnDemandSystemAbilityInfo(saProfile.saId, procName_);
772 if (ret != ERR_OK) {
773 HILOGI(TAG, "failed to add ability info for on-demand SA:%{public}d", saProfile.saId);
774 }
775 }
776 }
777 }
778
779 // on default load, not-run-on-create SA will register to OnDemandSystemAbility
780 // on demand load, other SA will register to OnDemandSystemAbility, although some are runOnCreate
NeedRegisterOnDemand(const SaProfile & saProfile,int32_t saId)781 bool LocalAbilityManager::NeedRegisterOnDemand(const SaProfile& saProfile, int32_t saId)
782 {
783 return (saId == DEFAULT_SAID && !saProfile.runOnCreate) ||
784 (saId != DEFAULT_SAID && saProfile.saId != saId);
785 }
786
StartPhaseTasks(const std::list<SystemAbility * > & systemAbilityList)787 void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
788 {
789 if (systemAbilityList.empty()) {
790 return;
791 }
792
793 for (auto systemAbility : systemAbilityList) {
794 if (systemAbility != nullptr) {
795 HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
796 std::lock_guard<std::mutex> autoLock(startPhaseLock_);
797 ++startTaskNum_;
798 auto task = [this, systemAbility] {this->StartSystemAbilityTask(systemAbility);};
799 initPool_->AddTask(task);
800 }
801 }
802 }
803
WaitForTasks()804 void LocalAbilityManager::WaitForTasks()
805 {
806 int64_t begin = GetTickCount();
807 HILOGD(TAG, "start waiting for all tasks!");
808 std::unique_lock<std::mutex> lck(startPhaseLock_);
809 if (!startPhaseCV_.wait_for(lck, std::chrono::seconds(MAX_SA_STARTUP_TIME),
810 [this] () { return startTaskNum_ == 0; })) {
811 HILOGW(TAG, "start timeout!");
812 }
813 startTaskNum_ = 0;
814 int64_t end = GetTickCount();
815 LOGI("start tasks proc:%{public}s end,spend %{public}" PRId64 "ms",
816 Str16ToStr8(procName_).c_str(), (end - begin));
817 }
818
FindAndStartPhaseTasks(int32_t saId)819 void LocalAbilityManager::FindAndStartPhaseTasks(int32_t saId)
820 {
821 if (saId == DEFAULT_SAID) {
822 for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
823 auto iter = abilityPhaseMap_.find(bootPhase);
824 if (iter != abilityPhaseMap_.end()) {
825 StartPhaseTasks(iter->second);
826 InitializeRunOnCreateSaProfiles(bootPhase + 1);
827 WaitForTasks();
828 } else {
829 InitializeRunOnCreateSaProfiles(bootPhase + 1);
830 }
831 }
832 } else {
833 for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
834 auto iter = abilityPhaseMap_.find(bootPhase);
835 if (iter != abilityPhaseMap_.end()) {
836 StartPhaseTasks(iter->second);
837 WaitForTasks();
838 }
839 }
840 }
841 }
842
InitializeRunOnCreateSaProfiles(uint32_t bootPhase)843 bool LocalAbilityManager::InitializeRunOnCreateSaProfiles(uint32_t bootPhase)
844 {
845 if (bootPhase > OTHER_START) {
846 return false;
847 }
848 int64_t begin = GetTickCount();
849 LOGD("ROC_InitProfiles load phase %{public}d libraries", bootPhase);
850 profileParser_->OpenSo(bootPhase);
851 LOGI("ROC_InitProfiles proc:%{public}s phase:%{public}d end, spend:%{public}" PRId64 "ms",
852 Str16ToStr8(procName_).c_str(), bootPhase, (GetTickCount() - begin));
853 auto& saProfileList = profileParser_->GetAllSaProfiles();
854 if (saProfileList.empty()) {
855 HILOGW(TAG, "sa profile is empty");
856 return false;
857 }
858 for (const auto& saProfile : saProfileList) {
859 if (saProfile.bootPhase != bootPhase) {
860 continue;
861 }
862 if (!InitializeSaProfilesInnerLocked(saProfile)) {
863 HILOGW(TAG, "SA:%{public}d init fail", saProfile.saId);
864 continue;
865 }
866 }
867 return true;
868 }
869
Run(int32_t saId)870 bool LocalAbilityManager::Run(int32_t saId)
871 {
872 HILOGD(TAG, "local ability manager is running...");
873 bool addResult = AddLocalAbilityManager();
874 if (!addResult) {
875 HILOGE(TAG, "failed to add local abilitymanager");
876 return false;
877 }
878 LOGD("Run succ to add proc name:%{public}s", Str16ToStr8(procName_).c_str());
879 uint32_t concurrentThreads = std::thread::hardware_concurrency();
880 LOGI("Run curThread is %{public}d,proc:%{public}s,SA:%{public}d",
881 concurrentThreads, Str16ToStr8(procName_).c_str(), saId);
882 initPool_->Start(concurrentThreads);
883 initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
884
885 RegisterOnDemandSystemAbility(saId);
886 FindAndStartPhaseTasks(saId);
887 initPool_->Stop();
888 return true;
889 }
890
AddLocalAbilityManager()891 bool LocalAbilityManager::AddLocalAbilityManager()
892 {
893 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
894 if (samgrProxy == nullptr) {
895 HILOGE(TAG, "failed to get samgrProxy");
896 return false;
897 }
898
899 if (localAbilityManager_ == nullptr) {
900 localAbilityManager_ = this;
901 }
902 int32_t ret = samgrProxy->AddSystemProcess(procName_, localAbilityManager_);
903 return ret == ERR_OK;
904 }
905
SetStartReason(int32_t saId,const nlohmann::json & event)906 void LocalAbilityManager::SetStartReason(int32_t saId, const nlohmann::json& event)
907 {
908 std::lock_guard<std::mutex> autoLock(ReasonLock_);
909 saIdToStartReason_[saId] = event;
910 }
911
SetStopReason(int32_t saId,const nlohmann::json & event)912 void LocalAbilityManager::SetStopReason(int32_t saId, const nlohmann::json& event)
913 {
914 std::lock_guard<std::mutex> autoLock(ReasonLock_);
915 saIdToStopReason_[saId] = event;
916 }
917
GetStartReason(int32_t saId)918 nlohmann::json LocalAbilityManager::GetStartReason(int32_t saId)
919 {
920 std::lock_guard<std::mutex> autoLock(ReasonLock_);
921 return saIdToStartReason_[saId];
922 }
923
GetStopReason(int32_t saId)924 nlohmann::json LocalAbilityManager::GetStopReason(int32_t saId)
925 {
926 std::lock_guard<std::mutex> autoLock(ReasonLock_);
927 return saIdToStopReason_[saId];
928 }
929
GetSystemAbilityStatusChange()930 sptr<ISystemAbilityStatusChange> LocalAbilityManager::GetSystemAbilityStatusChange()
931 {
932 std::lock_guard<std::mutex> autoLock(listenerLock_);
933 if (statusChangeListener_ == nullptr) {
934 statusChangeListener_ = new SystemAbilityListener();
935 }
936 return statusChangeListener_;
937 }
938
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)939 void LocalAbilityManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
940 const std::string& deviceId)
941 {
942 HILOGD(TAG, "SA:%{public}d added", systemAbilityId);
943 if (!CheckInputSysAbilityId(systemAbilityId)) {
944 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
945 return;
946 }
947
948 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
949 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
950 }
951
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)952 void LocalAbilityManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
953 const std::string& deviceId)
954 {
955 HILOGD(TAG, "SA:%{public}d removed", systemAbilityId);
956 if (!CheckInputSysAbilityId(systemAbilityId)) {
957 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
958 return;
959 }
960
961 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
962 ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY);
963 }
964
SendStrategyToSA(int32_t type,int32_t systemAbilityId,int32_t level,std::string & action)965 bool LocalAbilityManager::SendStrategyToSA(int32_t type, int32_t systemAbilityId, int32_t level, std::string& action)
966 {
967 HILOGD(TAG, "SendStrategyTo SA:%{public}d", systemAbilityId);
968 auto ability = GetAbility(systemAbilityId);
969 if (ability == nullptr) {
970 HILOGW(TAG, "failed to get SA:%{public}d", systemAbilityId);
971 return false;
972 }
973 ability->OnDeviceLevelChanged(type, level, action);
974 return true;
975 }
976
IpcStatCmdProc(int32_t fd,int32_t cmd)977 bool LocalAbilityManager::IpcStatCmdProc(int32_t fd, int32_t cmd)
978 {
979 bool ret = false;
980 std::string result;
981
982 HILOGI(TAG, "IpcStatCmdProc:fd=%{public}d cmd=%{public}d request", fd, cmd);
983 if (cmd < IPC_STAT_CMD_START || cmd >= IPC_STAT_CMD_MAX) {
984 HILOGW(TAG, "para invalid, fd=%{public}d cmd=%{public}d", fd, cmd);
985 return false;
986 }
987
988 switch (cmd) {
989 case IPC_STAT_CMD_START: {
990 ret = LocalAbilityManagerDumper::StartIpcStatistics(result);
991 break;
992 }
993 case IPC_STAT_CMD_STOP: {
994 ret = LocalAbilityManagerDumper::StopIpcStatistics(result);
995 break;
996 }
997 case IPC_STAT_CMD_GET: {
998 ret = LocalAbilityManagerDumper::GetIpcStatistics(result);
999 break;
1000 }
1001 default:
1002 return false;
1003 }
1004
1005 if (!SaveStringToFd(fd, result)) {
1006 HILOGW(TAG, "save to fd failed");
1007 return false;
1008 }
1009 return ret;
1010 }
1011
1012 typedef void (*PGetSdkName)(uint32_t cmd, char *buf, uint32_t len);
1013
FfrtDumperProc(std::string & ffrtDumperInfo)1014 bool LocalAbilityManager::FfrtDumperProc(std::string& ffrtDumperInfo)
1015 {
1016 HILOGI(TAG, "FfrtDumperPorc request");
1017 PGetSdkName pFFrtDumpInfo = (PGetSdkName)dlsym(RTLD_DEFAULT, "ffrt_dump");
1018 char* pszErr = dlerror();
1019 if (pszErr != NULL) {
1020 HILOGE(TAG, "dlsym err info: %{public}s", pszErr);
1021 }
1022 if (pFFrtDumpInfo == NULL) {
1023 HILOGE(TAG, "dlsym failed");
1024 ffrtDumperInfo.append("process " + std::to_string(getpid()) + " did not load ffrt\n");
1025 return false;
1026 }
1027 char* buffer = new char[FFRT_BUFFER_SIZE + 1]();
1028 buffer[FFRT_BUFFER_SIZE] = 0;
1029 (*pFFrtDumpInfo)(FFRT_DUMP_INFO_ALL, buffer, FFRT_BUFFER_SIZE);
1030 if (strlen(buffer) == 0) {
1031 HILOGE(TAG, "get samgr FfrtDumperInfo failed");
1032 delete[] buffer;
1033 return false;
1034 }
1035 ffrtDumperInfo += buffer;
1036 delete[] buffer;
1037 return true;
1038 }
1039
SystemAbilityExtProc(const std::string & extension,int32_t said,SystemAbilityExtensionPara * callback,bool isAsync)1040 int32_t LocalAbilityManager::SystemAbilityExtProc(const std::string& extension, int32_t said,
1041 SystemAbilityExtensionPara* callback, bool isAsync)
1042 {
1043 (void)isAsync;
1044 if (callback == nullptr) {
1045 return INVALID_DATA;
1046 }
1047
1048 HILOGD(TAG, "SystemAbilityExtProc Extension %{public}s SA:%{public}d", extension.c_str(), said);
1049 auto ability = GetAbility(said);
1050 if (ability == nullptr) {
1051 return INVALID_DATA;
1052 }
1053 return ability->OnExtension(extension, *callback->data_, *callback->reply_);
1054 }
1055
IsResident()1056 bool LocalAbilityManager::IsResident()
1057 {
1058 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
1059 for (const auto& it : localAbilityMap_) {
1060 if ((it.second != nullptr) && (it.second->IsRunOnCreate())) {
1061 return true;
1062 }
1063 }
1064 return false;
1065 }
1066
NoNeedCheckUnused(int32_t saId)1067 bool LocalAbilityManager::NoNeedCheckUnused(int32_t saId)
1068 {
1069 std::set<int32_t> saIdWhiteList = {};
1070 return saIdWhiteList.find(saId) != saIdWhiteList.end();
1071 }
1072
IsConfigUnused()1073 bool LocalAbilityManager::IsConfigUnused()
1074 {
1075 std::shared_lock<std::shared_mutex> readLock(unusedCfgMapLock_);
1076 HILOGI(TAG, "unusedCfgMap_ size:%{public}zu", unusedCfgMap_.size());
1077 return !unusedCfgMap_.empty();
1078 }
1079
LimitUnusedTimeout(int32_t saId,int32_t timeout)1080 void LocalAbilityManager::LimitUnusedTimeout(int32_t saId, int32_t timeout)
1081 {
1082 int64_t millisecTimeout = static_cast<int64_t>(timeout * TIME_S_TO_MS);
1083 if (millisecTimeout < ONDEMAND_SA_UNUSED_TIMEOUT_LOWLIMIT) {
1084 unusedCfgMap_[saId] = ONDEMAND_SA_UNUSED_TIMEOUT_LOWLIMIT;
1085 } else if (millisecTimeout > ONDEMAND_SA_UNUSED_TIMEOUT_UPLIMIT) {
1086 unusedCfgMap_[saId] = ONDEMAND_SA_UNUSED_TIMEOUT_UPLIMIT;
1087 } else {
1088 unusedCfgMap_[saId] = millisecTimeout;
1089 }
1090 }
1091
InitUnusedCfg()1092 void LocalAbilityManager::InitUnusedCfg()
1093 {
1094 auto saProfileList = profileParser_->GetAllSaProfiles();
1095 std::shared_lock<std::shared_mutex> writeLock(unusedCfgMapLock_);
1096 for (const auto& saProfile : saProfileList) {
1097 if (!saProfile.runOnCreate && saProfile.stopOnDemand.unusedTimeout != -1) {
1098 LimitUnusedTimeout(saProfile.saId, saProfile.stopOnDemand.unusedTimeout);
1099 }
1100 }
1101 }
1102
GetSaLastRequestTime(const sptr<ISystemAbilityManager> & samgr,int32_t saId,uint64_t & lastRequestTime)1103 bool LocalAbilityManager::GetSaLastRequestTime(const sptr<ISystemAbilityManager>& samgr,
1104 int32_t saId, uint64_t& lastRequestTime)
1105 {
1106 sptr<IRemoteObject> object = samgr->CheckSystemAbility(saId);
1107 if (object == nullptr) {
1108 HILOGD(TAG, "SA:%{public}d is not register", saId);
1109 return false;
1110 }
1111 sptr<IPCObjectStub> saStub = reinterpret_cast<IPCObjectStub*>(object.GetRefPtr());
1112 if (saStub == nullptr) {
1113 HILOGE(TAG, "SA:%{public}d stub is nullptr", saId);
1114 return false;
1115 }
1116 lastRequestTime = saStub->GetLastRequestTime();
1117 HILOGI(TAG, "SA:%{public}d last request time %{public}" PRIu64, saId, lastRequestTime);
1118
1119 return true;
1120 }
1121
IdentifyUnusedResident()1122 void LocalAbilityManager::IdentifyUnusedResident()
1123 {
1124 auto cur = std::chrono::steady_clock::now();
1125 uint64_t currTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
1126 cur.time_since_epoch()).count());
1127
1128 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1129 if (samgr == nullptr) {
1130 HILOGE(TAG, "failed to get samgrProxy");
1131 return;
1132 }
1133
1134 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
1135 for (const auto& it : localAbilityMap_) {
1136 int32_t saId = it.first;
1137 uint64_t lastRequestTime = 0;
1138 bool ret = GetSaLastRequestTime(samgr, saId, lastRequestTime);
1139 if ((ret != true) || (currTime <= lastRequestTime)) {
1140 continue;
1141 }
1142 uint64_t idleTime = currTime - lastRequestTime;
1143 uint64_t threshold = static_cast<uint64_t>(RESIDENT_SA_UNUSED_TIMEOUT);
1144 HILOGD(TAG, "resident SA:%{public}d, idleTime:%{public}" PRIu64 ", longtime-unused threshold:%{public}" PRIu64,
1145 saId, idleTime, threshold);
1146 if (idleTime > threshold) {
1147 ReportSAIdle(saId, "long time unused:" + ToString(idleTime));
1148 HILOGI(TAG, "resident SA:%{public}d, longtime:%{public}" PRIu64 "unused", saId, idleTime);
1149 }
1150 }
1151 }
1152
IdentifyUnusedOndemand()1153 void LocalAbilityManager::IdentifyUnusedOndemand()
1154 {
1155 auto cur = std::chrono::steady_clock::now();
1156 uint64_t currTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
1157 cur.time_since_epoch()).count());
1158
1159 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1160 if (samgr == nullptr) {
1161 HILOGE(TAG, "failed to get samgrProxy");
1162 return;
1163 }
1164
1165 std::shared_lock<std::shared_mutex> readLock(unusedCfgMapLock_);
1166 for (const auto& it : unusedCfgMap_) {
1167 int32_t saId = it.first;
1168 uint64_t lastRequestTime;
1169 bool ret = GetSaLastRequestTime(samgr, saId, lastRequestTime);
1170 if ((ret != true) || (currTime <= lastRequestTime)) {
1171 continue;
1172 }
1173 uint64_t threshold = it.second;
1174 uint64_t idleTime = currTime - lastRequestTime;
1175 HILOGD(TAG, "ondemand SA:%{public}d, idleTime:%{public}" PRIu64 ", longtime-unused threshold:%{public}" PRIu64,
1176 saId, idleTime, threshold);
1177 if (idleTime > threshold) {
1178 samgr->UnloadSystemAbility(saId);
1179 HILOGI(TAG, "ondemand SA:%{public}d, longtime:%{public}" PRIu64 "unused", saId, idleTime);
1180 }
1181 }
1182 }
1183
StartTimedQuery()1184 void LocalAbilityManager::StartTimedQuery()
1185 {
1186 int32_t timerInterval = 0;
1187 std::function<void()> timerCallback;
1188
1189 {
1190 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
1191 for (const auto& it : localAbilityMap_) {
1192 if (NoNeedCheckUnused(it.first)) {
1193 HILOGI(TAG, "SA:%{public}d no need check unused", it.first);
1194 return;
1195 }
1196 }
1197 }
1198
1199 if (IsResident()) {
1200 timerInterval = UNUSED_RESIDENT_TIMER_INTERVAL;
1201 timerCallback = std::bind(&LocalAbilityManager::IdentifyUnusedResident, this);
1202 } else {
1203 InitUnusedCfg();
1204 if (IsConfigUnused()) {
1205 timerInterval = UNUSED_ONDEMAND_TIMER_INTERVAL;
1206 timerCallback = std::bind(&LocalAbilityManager::IdentifyUnusedOndemand, this);
1207 }
1208 }
1209
1210 if ((timerInterval != 0) && (timerCallback)) {
1211 idleTimer_ = std::make_unique<Utils::Timer>("OS_IdleSaReport", -1);
1212 idleTimer_->Setup();
1213 auto timerId = idleTimer_->Register(timerCallback, timerInterval);
1214 HILOGI(TAG, "StartIdleTimer timerId:%{public}u, interval:%{public}d", timerId, timerInterval);
1215 }
1216 }
1217 }
1218