• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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