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 <iostream>
21 #include <sys/types.h>
22
23 #include "datetime_ex.h"
24 #include "errors.h"
25 #include "hitrace_meter.h"
26 #include "ipc_skeleton.h"
27 #include "iservice_registry.h"
28 #include "safwk_log.h"
29 #include "string_ex.h"
30
31 namespace OHOS {
32 using std::u16string;
33 using std::string;
34 using std::vector;
35
36 namespace {
37 const string TAG = "LocalAbilityManager";
38
39 constexpr int32_t RETRY_TIMES_FOR_ONDEMAND = 10;
40 constexpr int32_t RETRY_TIMES_FOR_SAMGR = 50;
41 constexpr int32_t DEFAULT_SAID = -1;
42 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_SAMGR_ONE_TIME(200);
43 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_ONDEMAND_ONE_TIME(100);
44
45 const u16string BOOT_START_PHASE = u"BootStartPhase";
46 const u16string CORE_START_PHASE = u"CoreStartPhase";
47 constexpr int32_t MAX_SA_STARTUP_TIME = 100;
48 constexpr int32_t SUFFIX_LENGTH = 4; // .xml length
49
50 const string PROFILES_DIR = "/system/profile/";
51 const string DEFAULT_DIR = "/system/usr/";
52 const string PREFIX = PROFILES_DIR;
53 const string SUFFIX = "_trust.xml";
54
55 const string ONDEMAND_POOL = "SaOndemand";
56 const string INIT_POOL = "SaInit";
57
58 enum {
59 BOOT_START = 1,
60 CORE_START = 2,
61 OTHER_START = 3,
62 };
63 }
64
65 IMPLEMENT_SINGLE_INSTANCE(LocalAbilityManager);
66
LocalAbilityManager()67 LocalAbilityManager::LocalAbilityManager()
68 {
69 profileParser_ = std::make_shared<ParseUtil>();
70 initPool_ = std::make_unique<ThreadPool>(INIT_POOL);
71 ondemandPool_ = std::make_unique<ThreadPool>(ONDEMAND_POOL);
72 ondemandPool_->Start(std::thread::hardware_concurrency());
73 ondemandPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
74 }
75
~LocalAbilityManager()76 LocalAbilityManager::~LocalAbilityManager()
77 {
78 ondemandPool_->Stop();
79 }
80
DoStartSAProcess(const std::string & profilePath,int32_t saId)81 void LocalAbilityManager::DoStartSAProcess(const std::string& profilePath, int32_t saId)
82 {
83 HILOGI(TAG, "DoStartSAProcess saId : %d", saId);
84 string realProfilePath = "";
85 if (!CheckAndGetProfilePath(profilePath, realProfilePath)) {
86 HILOGE(TAG, "DoStartSAProcess invalid path");
87 return;
88 }
89 {
90 std::string traceTag = GetTraceTag(realProfilePath);
91 HITRACE_METER_NAME(HITRACE_TAG_SAMGR, traceTag);
92 bool ret = InitSystemAbilityProfiles(realProfilePath, saId);
93 if (!ret) {
94 HILOGE(TAG, "InitSystemAbilityProfiles no right profile, will exit");
95 return;
96 }
97 ret = CheckSystemAbilityManagerReady();
98 if (!ret) {
99 HILOGE(TAG, "CheckSystemAbilityManagerReady failed! will exit");
100 return;
101 }
102 ret = InitializeSaProfiles(saId);
103 if (!ret) {
104 HILOGE(TAG, "InitializeSaProfiles failed! will exit");
105 return;
106 }
107 ret = Run(saId);
108 if (!ret) {
109 HILOGE(TAG, "Run failed! will exit");
110 return;
111 }
112 }
113
114 IPCSkeleton::JoinWorkThread();
115 ClearResource();
116 HILOGE(TAG, "JoinWorkThread stop, will exit");
117 }
118
GetTraceTag(const std::string & profilePath)119 std::string LocalAbilityManager::GetTraceTag(const std::string& profilePath)
120 {
121 std::vector<std::string> libPathVec;
122 string traceTag = "default_proc";
123 SplitStr(profilePath, "/", libPathVec);
124 if ((libPathVec.size() > 0)) {
125 traceTag = libPathVec[libPathVec.size() - 1];
126 auto size = traceTag.length();
127 if (size > SUFFIX_LENGTH) {
128 return traceTag.substr(0, size - SUFFIX_LENGTH);
129 }
130 }
131 return traceTag;
132 }
133
CheckAndGetProfilePath(const std::string & profilePath,std::string & realProfilePath)134 bool LocalAbilityManager::CheckAndGetProfilePath(const std::string& profilePath, std::string& realProfilePath)
135 {
136 if (profilePath.length() > PATH_MAX) {
137 HILOGE(TAG, "profilePath length too long!");
138 return false;
139 }
140 char realPath[PATH_MAX] = {'\0'};
141 if (realpath(profilePath.c_str(), realPath) == nullptr) {
142 HILOGE(TAG, "xmlDocName path does not exist!");
143 return false;
144 }
145 // realProfilePath must begin with "/system/profile/" or begin with "/system/usr/"
146 realProfilePath = realPath;
147 if (realProfilePath.find(PROFILES_DIR) != 0 && realProfilePath.find(DEFAULT_DIR) != 0) {
148 HILOGE(TAG, "xmlDoc dir is not matched");
149 return false;
150 }
151 return true;
152 }
153
CheckSystemAbilityManagerReady()154 bool LocalAbilityManager::CheckSystemAbilityManagerReady()
155 {
156 int32_t timeout = RETRY_TIMES_FOR_SAMGR;
157 constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_SAMGR_ONE_TIME).count();
158 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
159 while (samgrProxy == nullptr) {
160 HILOGI(TAG, "waiting for samgr...");
161 if (timeout > 0) {
162 usleep(duration);
163 samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
164 } else {
165 HILOGE(TAG, "wait for samgr time out (10s)");
166 return false;
167 }
168 timeout--;
169 }
170 return true;
171 }
172
InitSystemAbilityProfiles(const std::string & profilePath,int32_t saId)173 bool LocalAbilityManager::InitSystemAbilityProfiles(const std::string& profilePath, int32_t saId)
174 {
175 HILOGD(TAG, "[PerformanceTest] SAFWK parse system ability profiles!");
176 int64_t begin = GetTickCount();
177 bool ret = profileParser_->ParseSaProfiles(profilePath);
178 if (!ret) {
179 HILOGW(TAG, "ParseSaProfiles failed!");
180 return false;
181 }
182
183 procName_ = profileParser_->GetProcessName();
184 auto saInfos = profileParser_->GetAllSaProfiles();
185 std::string process = Str16ToStr8(procName_);
186 HILOGI(TAG, "[PerformanceTest] SAFWK parse process:%{public}s system ability profiles finished, spend:%{public}"
187 PRId64 " ms", process.c_str(), (GetTickCount() - begin));
188 std::string path = PREFIX + process + SUFFIX;
189 bool isExist = profileParser_->CheckPathExist(path);
190 if (isExist) {
191 CheckTrustSa(path, process, saInfos);
192 }
193 begin = GetTickCount();
194 if (saId != DEFAULT_SAID) {
195 HILOGD(TAG, "[PerformanceTest] SAFWK LoadSaLib systemAbilityId:%{public}d", saId);
196 bool result = profileParser_->LoadSaLib(saId);
197 HILOGI(TAG, "[PerformanceTest] SAFWK LoadSaLib systemAbilityId:%{public}d finished, spend:%{public}"
198 PRId64 " ms", saId, (GetTickCount() - begin));
199 return result;
200 } else {
201 HILOGD(TAG, "[PerformanceTest] SAFWK load all libraries");
202 profileParser_->OpenSo();
203 HILOGI(TAG, "[PerformanceTest] SAFWK load all libraries finished, spend:%{public}" PRId64 " ms",
204 (GetTickCount() - begin));
205 return true;
206 }
207 }
208
CheckTrustSa(const std::string & path,const std::string & process,const std::list<SaProfile> & saInfos)209 void LocalAbilityManager::CheckTrustSa(const std::string& path, const std::string& process,
210 const std::list<SaProfile>& saInfos)
211 {
212 HILOGD(TAG, "CheckTrustSa start");
213 std::map<std::u16string, std::set<int32_t>> trustMaps;
214 bool ret = profileParser_->ParseTrustConfig(path, trustMaps);
215 if (ret && !trustMaps.empty()) {
216 // 1.get allowed sa set in the process
217 const auto& saSets = trustMaps[Str8ToStr16(process)];
218 // 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
219 for (const auto& saInfo : saInfos) {
220 if (saSets.find(saInfo.saId) == saSets.end()) {
221 HILOGW(TAG, "sa : %{public}d not allow to load in %{public}s", saInfo.saId, process.c_str());
222 profileParser_->RemoveSaProfile(saInfo.saId);
223 }
224 }
225 }
226 }
227
ClearResource()228 void LocalAbilityManager::ClearResource()
229 {
230 profileParser_->ClearResource();
231 }
232
AddAbility(SystemAbility * ability)233 bool LocalAbilityManager::AddAbility(SystemAbility* ability)
234 {
235 if (ability == nullptr) {
236 HILOGW(TAG, "try to add null ability!");
237 return false;
238 }
239
240 int32_t saId = ability->GetSystemAbilitId();
241 SaProfile saProfile;
242 bool ret = profileParser_->GetProfile(saId, saProfile);
243 if (!ret) {
244 return false;
245 }
246 std::unique_lock<std::shared_mutex> writeLock(abilityMapLock_);
247 auto iter = abilityMap_.find(saId);
248 if (iter != abilityMap_.end()) {
249 HILOGW(TAG, "try to add existed ability:%{public}d!", saId);
250 return false;
251 }
252 HILOGI(TAG, "set profile attributes for SA:%{public}d", saId);
253 ability->SetLibPath(saProfile.libPath);
254 ability->SetRunOnCreate(saProfile.runOnCreate);
255 ability->SetDependSa(saProfile.dependSa);
256 ability->SetDependTimeout(saProfile.dependTimeout);
257 ability->SetDistributed(saProfile.distributed);
258 ability->SetDumpLevel(saProfile.dumpLevel);
259 ability->SetCapability(saProfile.capability);
260 ability->SetPermission(saProfile.permission);
261 abilityMap_.emplace(saId, ability);
262 return true;
263 }
264
RemoveAbility(int32_t systemAbilityId)265 bool LocalAbilityManager::RemoveAbility(int32_t systemAbilityId)
266 {
267 if (systemAbilityId <= 0) {
268 HILOGW(TAG, "invalid systemAbilityId");
269 return false;
270 }
271 std::unique_lock<std::shared_mutex> writeLock(abilityMapLock_);
272 (void)abilityMap_.erase(systemAbilityId);
273 return true;
274 }
275
AddSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)276 bool LocalAbilityManager::AddSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
277 {
278 if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
279 HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!",
280 systemAbilityId, listenerSaId);
281 return false;
282 }
283 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
284 if (samgrProxy == nullptr) {
285 HILOGE(TAG, "failed to get samgrProxy");
286 return false;
287 }
288
289 {
290 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
291 std::lock_guard<std::mutex> autoLock(listenerLock_);
292 auto& listenerSaIdList = listenerMap_[systemAbilityId];
293 auto iter = std::find_if(listenerSaIdList.begin(), listenerSaIdList.end(), [listenerSaId](int32_t SaId) {
294 return SaId == listenerSaId;
295 });
296 if (iter == listenerSaIdList.end()) {
297 listenerSaIdList.emplace_back(listenerSaId);
298 }
299 HILOGI(TAG, "AddSystemAbilityListener SA:%{public}d, size:%{public}zu", systemAbilityId,
300 listenerSaIdList.size());
301 if (listenerSaIdList.size() > 1) {
302 sptr<IRemoteObject> object = samgrProxy->CheckSystemAbility(systemAbilityId);
303 if (object != nullptr) {
304 NotifyAbilityListener(systemAbilityId, listenerSaId, "",
305 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
306 }
307 return true;
308 }
309 }
310
311 int32_t ret = samgrProxy->SubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
312 if (ret) {
313 HILOGE(TAG, "failed to subscribe sa:%{public}d, process name:%{public}s", systemAbilityId,
314 Str16ToStr8(procName_).c_str());
315 return false;
316 }
317 return true;
318 }
319
RemoveSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)320 bool LocalAbilityManager::RemoveSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
321 {
322 if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
323 HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!",
324 systemAbilityId, listenerSaId);
325 return false;
326 }
327
328 {
329 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
330 std::lock_guard<std::mutex> autoLock(listenerLock_);
331 if (listenerMap_.count(systemAbilityId) == 0) {
332 return true;
333 }
334 auto& listenerSaIdList = listenerMap_[systemAbilityId];
335 auto iter = std::find_if(listenerSaIdList.begin(), listenerSaIdList.end(), [listenerSaId](int32_t SaId) {
336 return SaId == listenerSaId;
337 });
338 if (iter != listenerSaIdList.end()) {
339 listenerSaIdList.erase(iter);
340 }
341 HILOGI(TAG, "RemoveSystemAbilityListener SA:%{public}d, size:%{public}zu", systemAbilityId,
342 listenerSaIdList.size());
343 if (!listenerSaIdList.empty()) {
344 return true;
345 }
346 listenerMap_.erase(systemAbilityId);
347 }
348
349 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
350 if (samgrProxy == nullptr) {
351 HILOGE(TAG, "failed to get samgrProxy");
352 return false;
353 }
354 int32_t ret = samgrProxy->UnSubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
355 if (ret) {
356 HILOGE(TAG, "failed to unsubscribe SA:%{public}d, process name:%{public}s",
357 systemAbilityId, Str16ToStr8(procName_).c_str());
358 return false;
359 }
360 return true;
361 }
362
NotifyAbilityListener(int32_t systemAbilityId,int32_t listenerSaId,const std::string & deviceId,int32_t code)363 void LocalAbilityManager::NotifyAbilityListener(int32_t systemAbilityId, int32_t listenerSaId,
364 const std::string& deviceId, int32_t code)
365 {
366 HILOGI(TAG, "SA:%{public}d, listenerSA:%{public}d, code:%{public}d", systemAbilityId, listenerSaId, code);
367 auto ability = GetAbility(listenerSaId);
368 if (ability == nullptr) {
369 HILOGE(TAG, "failed to get listener SA:%{public}d", listenerSaId);
370 return;
371 }
372
373 switch (code) {
374 case ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY: {
375 HILOGD(TAG, "OnAddSystemAbility, SA:%{public}d", listenerSaId);
376 ability->OnAddSystemAbility(systemAbilityId, deviceId);
377 break;
378 }
379 case ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY: {
380 HILOGD(TAG, "OnRemoveSystemAbility, SA:%{public}d", listenerSaId);
381 ability->OnRemoveSystemAbility(systemAbilityId, deviceId);
382 break;
383 }
384 default:
385 break;
386 }
387 }
388
FindAndNotifyAbilityListeners(int32_t systemAbilityId,const std::string & deviceId,int32_t code)389 void LocalAbilityManager::FindAndNotifyAbilityListeners(int32_t systemAbilityId,
390 const std::string& deviceId, int32_t code)
391 {
392 HILOGD(TAG, "SA:%{public}d, code:%{public}d", systemAbilityId, code);
393 int64_t begin = GetTickCount();
394 std::list<int32_t> listenerSaIdList;
395 {
396 std::lock_guard<std::mutex> autoLock(listenerLock_);
397 auto iter = listenerMap_.find(systemAbilityId);
398 if (iter != listenerMap_.end()) {
399 listenerSaIdList = iter->second;
400 } else {
401 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
402 }
403 }
404 for (auto listenerSaId : listenerSaIdList) {
405 NotifyAbilityListener(systemAbilityId, listenerSaId, deviceId, code);
406 }
407 HILOGI(TAG, "SA:%{public}d, code:%{public}d spend:%{public}" PRId64 " ms", systemAbilityId, code,
408 GetTickCount() - begin);
409 }
410
OnStartAbility(int32_t systemAbilityId)411 bool LocalAbilityManager::OnStartAbility(int32_t systemAbilityId)
412 {
413 HILOGD(TAG, "try to start SA:%{public}d", systemAbilityId);
414 auto ability = GetAbility(systemAbilityId);
415 if (ability == nullptr) {
416 return false;
417 }
418 ability->Start();
419 return true;
420 }
421
GetAbility(int32_t systemAbilityId)422 SystemAbility* LocalAbilityManager::GetAbility(int32_t systemAbilityId)
423 {
424 std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
425 auto it = abilityMap_.find(systemAbilityId);
426 if (it == abilityMap_.end()) {
427 HILOGW(TAG, "SA:%{public}d not register", systemAbilityId);
428 return nullptr;
429 }
430
431 return it->second;
432 }
433
GetRunningStatus(int32_t systemAbilityId)434 bool LocalAbilityManager::GetRunningStatus(int32_t systemAbilityId)
435 {
436 auto ability = GetAbility(systemAbilityId);
437 if (ability == nullptr) {
438 return false;
439 }
440
441 return ability->GetRunningStatus();
442 }
443
StartOndemandSystemAbility(int32_t systemAbilityId)444 void LocalAbilityManager::StartOndemandSystemAbility(int32_t systemAbilityId)
445 {
446 HILOGD(TAG, "[PerformanceTest] SAFWK ondemand LoadSaLib systemAbilityId:%{public}d library", systemAbilityId);
447 int64_t begin = GetTickCount();
448 bool isExist = profileParser_->LoadSaLib(systemAbilityId);
449 HILOGI(TAG, "[PerformanceTest] SAFWK ondemand LoadSaLib systemAbilityId:%{public}d, spend:%{public}" PRId64 " ms",
450 systemAbilityId, (GetTickCount() - begin));
451 if (isExist) {
452 int32_t timeout = RETRY_TIMES_FOR_ONDEMAND;
453 constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_ONDEMAND_ONE_TIME).count();
454 {
455 std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
456 auto it = abilityMap_.find(systemAbilityId);
457 while (it == abilityMap_.end()) {
458 HILOGI(TAG, "waiting for SA:%{public}d...", systemAbilityId);
459 if (timeout > 0) {
460 usleep(duration);
461 it = abilityMap_.find(systemAbilityId);
462 } else {
463 HILOGE(TAG, "waiting for SA:%{public}d time out (1s)", systemAbilityId);
464 return;
465 }
466 timeout--;
467 }
468 }
469
470 if (!OnStartAbility(systemAbilityId)) {
471 HILOGE(TAG, "failed to start ability:%{public}d", systemAbilityId);
472 }
473 } else {
474 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
475 }
476 }
477
StartAbility(int32_t systemAbilityId)478 bool LocalAbilityManager::StartAbility(int32_t systemAbilityId)
479 {
480 HILOGI(TAG, "[PerformanceTest] SAFWK received start systemAbilityId:%{public}d request", systemAbilityId);
481 auto task = std::bind(&LocalAbilityManager::StartOndemandSystemAbility, this, systemAbilityId);
482 ondemandPool_->AddTask(task);
483 return true;
484 }
485
InitializeSaProfiles(int32_t saId)486 bool LocalAbilityManager::InitializeSaProfiles(int32_t saId)
487 {
488 return (saId == DEFAULT_SAID) ? InitializeRunOnCreateSaProfiles() : InitializeOnDemandSaProfile(saId);
489 }
490
InitializeRunOnCreateSaProfiles()491 bool LocalAbilityManager::InitializeRunOnCreateSaProfiles()
492 {
493 HILOGD(TAG, "initializing run-on-create sa profiles...");
494 auto& saProfileList = profileParser_->GetAllSaProfiles();
495 if (saProfileList.empty()) {
496 HILOGW(TAG, "sa profile is empty");
497 return false;
498 }
499
500 for (const auto& saProfile : saProfileList) {
501 if (!InitializeSaProfilesInnerLocked(saProfile)) {
502 HILOGW(TAG, "SA:%{public}d init fail", saProfile.saId);
503 continue;
504 }
505 }
506 return true;
507 }
508
InitializeOnDemandSaProfile(int32_t saId)509 bool LocalAbilityManager::InitializeOnDemandSaProfile(int32_t saId)
510 {
511 HILOGD(TAG, "initializing ondemand sa profile...");
512 SaProfile saProfile;
513 bool ret = profileParser_->GetProfile(saId, saProfile);
514 if (ret) {
515 return InitializeSaProfilesInnerLocked(saProfile);
516 }
517 return false;
518 }
519
InitializeSaProfilesInnerLocked(const SaProfile & saProfile)520 bool LocalAbilityManager::InitializeSaProfilesInnerLocked(const SaProfile& saProfile)
521 {
522 std::unique_lock<std::shared_mutex> writeLock(abilityMapLock_);
523 auto iterProfile = abilityMap_.find(saProfile.saId);
524 if (iterProfile == abilityMap_.end()) {
525 HILOGW(TAG, "SA:%{public}d not found", saProfile.saId);
526 return false;
527 }
528 auto systemAbility = iterProfile->second;
529 if (systemAbility == nullptr) {
530 HILOGW(TAG, "SA:%{public}d is null", saProfile.saId);
531 return false;
532 }
533 uint32_t phase = OTHER_START;
534 if (saProfile.bootPhase == BOOT_START_PHASE) {
535 phase = BOOT_START;
536 } else if (saProfile.bootPhase == CORE_START_PHASE) {
537 phase = CORE_START;
538 }
539 auto& saList = abilityPhaseMap_[phase];
540 saList.emplace_back(systemAbility);
541 return true;
542 }
543
CheckDependencyStatus(const vector<u16string> & dependSa)544 vector<u16string> LocalAbilityManager::CheckDependencyStatus(const vector<u16string>& dependSa)
545 {
546 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
547 if (samgrProxy == nullptr) {
548 HILOGW(TAG, "failed to get samgrProxy");
549 return dependSa;
550 }
551 vector<u16string> checkSaStatusResult;
552 for (const auto& saName : dependSa) {
553 int32_t systemAbilityId = 0;
554 StrToInt(Str16ToStr8(saName), systemAbilityId);
555 if (CheckInputSysAbilityId(systemAbilityId)) {
556 sptr<IRemoteObject> saObject = samgrProxy->CheckSystemAbility(systemAbilityId);
557 if (saObject == nullptr) {
558 checkSaStatusResult.emplace_back(saName);
559 }
560 } else {
561 HILOGW(TAG, "dependency's id:%{public}s is invalid", Str16ToStr8(saName).c_str());
562 }
563 }
564
565 return checkSaStatusResult;
566 }
567
StartSystemAbilityTask(SystemAbility * ability)568 void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
569 {
570 if (ability != nullptr) {
571 HILOGD(TAG, "StartSystemAbility is called for %{public}d", ability->GetSystemAbilitId());
572 if (ability->GetDependSa().empty()) {
573 ability->Start();
574 } else {
575 int64_t start = GetTickCount();
576 int64_t dependTimeout = ability->GetDependTimeout();
577 while (!CheckDependencyStatus(ability->GetDependSa()).empty()) {
578 int64_t end = GetTickCount();
579 int64_t duration = ((end >= start) ? (end - start) : (INT64_MAX - end + start));
580 if (duration < dependTimeout) {
581 usleep(CHECK_DEPENDENT_SA_PERIOD);
582 } else {
583 break;
584 }
585 }
586 vector<u16string> unpreparedDeps = CheckDependencyStatus(ability->GetDependSa());
587 if (unpreparedDeps.empty()) {
588 ability->Start();
589 } else {
590 for (const auto& unpreparedDep : unpreparedDeps) {
591 HILOGI(TAG, "%{public}d's dependency:%{public}s not started in %{public}d ms",
592 ability->GetSystemAbilitId(), Str16ToStr8(unpreparedDep).c_str(), ability->GetDependTimeout());
593 }
594 }
595 }
596 }
597
598 std::lock_guard<std::mutex> lock(startPhaseLock_);
599 if (startTaskNum_ > 0) {
600 --startTaskNum_;
601 }
602 startPhaseCV_.notify_one();
603 }
604
RegisterOnDemandSystemAbility(int32_t saId)605 void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId)
606 {
607 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
608 if (samgrProxy == nullptr) {
609 HILOGI(TAG, "failed to get samgrProxy");
610 return;
611 }
612
613 auto& saProfileList = profileParser_->GetAllSaProfiles();
614 for (const auto& saProfile : saProfileList) {
615 if (NeedRegisterOnDemand(saProfile, saId)) {
616 HILOGD(TAG, "register ondemand ability:%{public}d to samgr", saProfile.saId);
617 int32_t ret = samgrProxy->AddOnDemandSystemAbilityInfo(saProfile.saId, procName_);
618 if (ret != ERR_OK) {
619 HILOGI(TAG, "failed to add ability info for on-demand SA:%{public}d", saProfile.saId);
620 }
621 }
622 }
623 }
624
625 // on default load, not-run-on-create SA will register to OnDemandSystemAbility
626 // on demand load, other SA will register to OnDemandSystemAbility, although some are runOnCreate
NeedRegisterOnDemand(const SaProfile & saProfile,int32_t saId)627 bool LocalAbilityManager::NeedRegisterOnDemand(const SaProfile& saProfile, int32_t saId)
628 {
629 return (saId == DEFAULT_SAID && !saProfile.runOnCreate) ||
630 (saId != DEFAULT_SAID && saProfile.saId != saId);
631 }
632
StartPhaseTasks(const std::list<SystemAbility * > & systemAbilityList)633 void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
634 {
635 if (systemAbilityList.empty()) {
636 return;
637 }
638
639 for (auto systemAbility : systemAbilityList) {
640 if (systemAbility != nullptr) {
641 HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
642 std::lock_guard<std::mutex> autoLock(startPhaseLock_);
643 ++startTaskNum_;
644 auto task = std::bind(&LocalAbilityManager::StartSystemAbilityTask, this, systemAbility);
645 initPool_->AddTask(task);
646 }
647 }
648
649 int64_t begin = GetTickCount();
650 HILOGD(TAG, "start waiting for all tasks!");
651 std::unique_lock<std::mutex> lck(startPhaseLock_);
652 if (!startPhaseCV_.wait_for(lck, std::chrono::seconds(MAX_SA_STARTUP_TIME),
653 [this] () { return startTaskNum_ == 0; })) {
654 HILOGW(TAG, "start timeout!");
655 }
656 startTaskNum_ = 0;
657 int64_t end = GetTickCount();
658 HILOGI(TAG, "start tasks finished and spend %{public}" PRId64 " ms", (end - begin));
659 }
660
FindAndStartPhaseTasks()661 void LocalAbilityManager::FindAndStartPhaseTasks()
662 {
663 std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
664 for (uint32_t startType = BOOT_START; startType <= OTHER_START; ++startType) {
665 auto iter = abilityPhaseMap_.find(startType);
666 if (iter != abilityPhaseMap_.end()) {
667 StartPhaseTasks(iter->second);
668 }
669 }
670 }
671
Run(int32_t saId)672 bool LocalAbilityManager::Run(int32_t saId)
673 {
674 HILOGD(TAG, "local ability manager is running...");
675 bool addResult = AddLocalAbilityManager();
676 if (!addResult) {
677 HILOGE(TAG, "failed to add local abilitymanager");
678 return false;
679 }
680 HILOGD(TAG, "success to add process name:%{public}s", Str16ToStr8(procName_).c_str());
681 uint32_t concurrentThreads = std::thread::hardware_concurrency();
682 HILOGI(TAG, "concurrentThreads is %{public}d", concurrentThreads);
683 initPool_->Start(concurrentThreads);
684 initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
685
686 FindAndStartPhaseTasks();
687 RegisterOnDemandSystemAbility(saId);
688 initPool_->Stop();
689 return true;
690 }
691
AddLocalAbilityManager()692 bool LocalAbilityManager::AddLocalAbilityManager()
693 {
694 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
695 if (samgrProxy == nullptr) {
696 HILOGE(TAG, "failed to get samgrProxy");
697 return false;
698 }
699
700 if (localAbilityManager_ == nullptr) {
701 localAbilityManager_ = this;
702 }
703 int32_t ret = samgrProxy->AddSystemProcess(procName_, localAbilityManager_);
704 return ret == ERR_OK;
705 }
706
GetSystemAbilityStatusChange()707 sptr<ISystemAbilityStatusChange> LocalAbilityManager::GetSystemAbilityStatusChange()
708 {
709 std::lock_guard<std::mutex> autoLock(listenerLock_);
710 if (statusChangeListener_ == nullptr) {
711 statusChangeListener_ = new SystemAbilityListener();
712 }
713 return statusChangeListener_;
714 }
715
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)716 void LocalAbilityManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
717 const std::string& deviceId)
718 {
719 HILOGD(TAG, "SA:%{public}d added", systemAbilityId);
720 if (!CheckInputSysAbilityId(systemAbilityId)) {
721 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
722 return;
723 }
724
725 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
726 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
727 }
728
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)729 void LocalAbilityManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
730 const std::string& deviceId)
731 {
732 HILOGD(TAG, "SA:%{public}d removed", systemAbilityId);
733 if (!CheckInputSysAbilityId(systemAbilityId)) {
734 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
735 return;
736 }
737
738 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
739 ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY);
740 }
741 }
742