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