• 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 <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 "samgr_xcollie.h"
37 
38 namespace OHOS {
39 using std::u16string;
40 using std::string;
41 using std::vector;
42 
43 namespace {
44 constexpr int32_t RETRY_TIMES_FOR_ONDEMAND = 10;
45 constexpr int32_t RETRY_TIMES_FOR_SAMGR = 50;
46 constexpr int32_t DEFAULT_SAID = -1;
47 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_SAMGR_ONE_TIME(200);
48 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_ONDEMAND_ONE_TIME(100);
49 constexpr int32_t MAX_DEPEND_TIMEOUT = 65;
50 constexpr int32_t MAX_CHECK_TIMEOUT = 10;
51 
52 constexpr int32_t MAX_SA_STARTUP_TIME = 100;
53 constexpr int32_t SUFFIX_LENGTH = 5; // .json length
54 constexpr uint32_t FFRT_DUMP_INFO_ALL = 0;
55 constexpr int FFRT_BUFFER_SIZE = 512 * 1024;
56 
57 constexpr const char* PROFILES_DIR = "/system/profile/";
58 constexpr const char* DEFAULT_DIR = "/system/usr/";
59 constexpr const char* PREFIX = PROFILES_DIR;
60 constexpr const char* SUFFIX = "_trust.json";
61 
62 constexpr const char* ONDEMAND_WORKER = "SaOndemand";
63 constexpr const char* INIT_POOL = "SaInit";
64 
65 constexpr const char* EVENT_ID = "eventId";
66 constexpr const char* NAME = "name";
67 constexpr const char* VALUE = "value";
68 constexpr const char* EXTRA_DATA_ID = "extraDataId";
69 
70 enum {
71     BOOT_START = 1,
72     CORE_START = 2,
73     OTHER_START = 3,
74 };
75 }
76 
77 IMPLEMENT_SINGLE_INSTANCE(LocalAbilityManager);
78 
LocalAbilityManager()79 LocalAbilityManager::LocalAbilityManager()
80 {
81     profileParser_ = std::make_shared<ParseUtil>();
82     initPool_ = std::make_unique<ThreadPool>(INIT_POOL);
83 }
84 
DoStartSAProcess(const std::string & profilePath,int32_t saId)85 void LocalAbilityManager::DoStartSAProcess(const std::string& profilePath, int32_t saId)
86 {
87     startBegin_ = GetTickCount();
88     HILOGD(TAG, "SA:%{public}d", saId);
89     string realProfilePath = "";
90     if (!CheckAndGetProfilePath(profilePath, realProfilePath)) {
91         ReportSaMainExit("DoStartSAProcess invalid path");
92         HILOGE(TAG, "DoStartSAProcess invalid path");
93         return;
94     }
95     {
96         std::string traceTag = GetTraceTag(realProfilePath);
97         HITRACE_METER_NAME(HITRACE_TAG_SAMGR, traceTag);
98         bool ret = InitSystemAbilityProfiles(realProfilePath, saId);
99         if (!ret) {
100             ReportSaMainExit("InitSaProfiles no right profile");
101             HILOGE(TAG, "InitSystemAbilityProfiles no right profile, will exit");
102             return;
103         }
104         {
105             SamgrXCollie samgrXCollie("safwk--CheckSamgrReady", MAX_CHECK_TIMEOUT);
106             ret = CheckSystemAbilityManagerReady();
107         }
108         if (!ret) {
109             ReportSaMainExit("CheckSamgrReady failed");
110             HILOGE(TAG, "CheckSystemAbilityManagerReady failed! will exit");
111             return;
112         }
113         ret = Run(saId);
114         if (!ret) {
115             ReportSaMainExit("SA Run failed");
116             HILOGE(TAG, "Run failed! will exit");
117             return;
118         }
119     }
120 
121     IPCSkeleton::JoinWorkThread();
122     HILOGE(TAG, "JoinWorkThread stop, will exit");
123 }
124 
GetTraceTag(const std::string & profilePath)125 std::string LocalAbilityManager::GetTraceTag(const std::string& profilePath)
126 {
127     std::vector<std::string> libPathVec;
128     string traceTag = "default_proc";
129     SplitStr(profilePath, "/", libPathVec);
130     if ((libPathVec.size() > 0)) {
131         traceTag = libPathVec[libPathVec.size() - 1];
132         auto size = traceTag.length();
133         if (size > SUFFIX_LENGTH) {
134             return traceTag.substr(0, size - SUFFIX_LENGTH);
135         }
136     }
137     return traceTag;
138 }
139 
CheckAndGetProfilePath(const std::string & profilePath,std::string & realProfilePath)140 bool LocalAbilityManager::CheckAndGetProfilePath(const std::string& profilePath, std::string& realProfilePath)
141 {
142     if (profilePath.length() > PATH_MAX) {
143         HILOGE(TAG, "profilePath length too long!");
144         return false;
145     }
146     char realPath[PATH_MAX] = {'\0'};
147     if (realpath(profilePath.c_str(), realPath) == nullptr) {
148         HILOGE(TAG, "file path does not exist!");
149         return false;
150     }
151     // realProfilePath must begin with "/system/profile/" or begin with "/system/usr/"
152     realProfilePath = realPath;
153     if (realProfilePath.find(PROFILES_DIR) != 0 && realProfilePath.find(DEFAULT_DIR) != 0) {
154         HILOGE(TAG, "file path is not matched");
155         return false;
156     }
157     return true;
158 }
159 
CheckSystemAbilityManagerReady()160 bool LocalAbilityManager::CheckSystemAbilityManagerReady()
161 {
162     int32_t timeout = RETRY_TIMES_FOR_SAMGR;
163     constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_SAMGR_ONE_TIME).count();
164     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
165     while (samgrProxy == nullptr) {
166         HILOGI(TAG, "%{public}s waiting for samgr...", Str16ToStr8(procName_).c_str());
167         if (timeout > 0) {
168             usleep(duration);
169             samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
170         } else {
171             HILOGE(TAG, "wait for samgr time out (10s)");
172             return false;
173         }
174         timeout--;
175     }
176     return true;
177 }
178 
InitSystemAbilityProfiles(const std::string & profilePath,int32_t saId)179 bool LocalAbilityManager::InitSystemAbilityProfiles(const std::string& profilePath, int32_t saId)
180 {
181     LOGD("InitProfiles parse sa profiles!");
182     int64_t begin = GetTickCount();
183     bool ret = profileParser_->ParseSaProfiles(profilePath);
184     if (!ret) {
185         HILOGW(TAG, "ParseSaProfiles failed!");
186         return false;
187     }
188 
189     procName_ = profileParser_->GetProcessName();
190     auto saInfos = profileParser_->GetAllSaProfiles();
191     std::string process = Str16ToStr8(procName_);
192     LOGI("InitProfiles proc:%{public}s end,spend:%{public}" PRId64 "ms", process.c_str(), (GetTickCount() - begin));
193     std::string path = PREFIX + process + SUFFIX;
194     bool isExist = profileParser_->CheckPathExist(path);
195     if (isExist) {
196         CheckTrustSa(path, process, saInfos);
197     }
198     return InitializeSaProfiles(saId);
199 }
200 
InitializeSaProfiles(int32_t saId)201 bool LocalAbilityManager::InitializeSaProfiles(int32_t saId)
202 {
203     if (saId != DEFAULT_SAID) {
204         return InitializeOnDemandSaProfile(saId);
205     } else {
206         return InitializeRunOnCreateSaProfiles(BOOT_START);
207     }
208 }
209 
CheckTrustSa(const std::string & path,const std::string & process,const std::list<SaProfile> & saInfos)210 void LocalAbilityManager::CheckTrustSa(const std::string& path, const std::string& process,
211     const std::list<SaProfile>& saInfos)
212 {
213     HILOGD(TAG, "CheckTrustSa start");
214     std::map<std::u16string, std::set<int32_t>> trustMaps;
215     bool ret = profileParser_->ParseTrustConfig(path, trustMaps);
216     if (ret && !trustMaps.empty()) {
217         // 1.get allowed sa set in the process
218         const auto& saSets = trustMaps[Str8ToStr16(process)];
219         // 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
220         for (const auto& saInfo : saInfos) {
221             if (saSets.find(saInfo.saId) == saSets.end()) {
222                 HILOGW(TAG, "SA:%{public}d not allow to load in %{public}s", saInfo.saId, process.c_str());
223                 profileParser_->RemoveSaProfile(saInfo.saId);
224             }
225         }
226     }
227 }
228 
ClearResource()229 void LocalAbilityManager::ClearResource()
230 {
231     profileParser_->ClearResource();
232 }
233 
AddAbility(SystemAbility * ability)234 bool LocalAbilityManager::AddAbility(SystemAbility* ability)
235 {
236     if (ability == nullptr) {
237         HILOGW(TAG, "try to add null ability!");
238         return false;
239     }
240 
241     int32_t saId = ability->GetSystemAbilitId();
242     SaProfile saProfile;
243     bool ret = profileParser_->GetProfile(saId, saProfile);
244     if (!ret) {
245         return false;
246     }
247     std::unique_lock<std::shared_mutex> writeLock(abilityMapLock_);
248     auto iter = abilityMap_.find(saId);
249     if (iter != abilityMap_.end()) {
250         HILOGW(TAG, "try to add existed SA:%{public}d!", saId);
251         return false;
252     }
253     HILOGI(TAG, "set profile attr for SA:%{public}d", saId);
254     ability->SetLibPath(saProfile.libPath);
255     ability->SetRunOnCreate(saProfile.runOnCreate);
256     ability->SetDependSa(saProfile.dependSa);
257     ability->SetDependTimeout(saProfile.dependTimeout);
258     ability->SetDistributed(saProfile.distributed);
259     ability->SetDumpLevel(saProfile.dumpLevel);
260     ability->SetCapability(saProfile.capability);
261     ability->SetPermission(saProfile.permission);
262     abilityMap_.emplace(saId, ability);
263     return true;
264 }
265 
RemoveAbility(int32_t systemAbilityId)266 bool LocalAbilityManager::RemoveAbility(int32_t systemAbilityId)
267 {
268     if (systemAbilityId <= 0) {
269         HILOGW(TAG, "invalid systemAbilityId");
270         return false;
271     }
272     std::unique_lock<std::shared_mutex> writeLock(abilityMapLock_);
273     (void)abilityMap_.erase(systemAbilityId);
274     return true;
275 }
276 
AddSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)277 bool LocalAbilityManager::AddSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
278 {
279     if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
280         HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!",
281             systemAbilityId, listenerSaId);
282         return false;
283     }
284     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
285     if (samgrProxy == nullptr) {
286         HILOGE(TAG, "failed to get samgrProxy");
287         return false;
288     }
289 
290     std::pair<int32_t, int32_t> key = std::make_pair(systemAbilityId, listenerSaId);
291     {
292         std::lock_guard<std::mutex> autoLock(listenerLock_);
293         auto iter = listenerMap_.find(key);
294         if (iter != listenerMap_.end()) {
295             HILOGW(TAG, "SA:%{public}d, listenerSA:%{public}d already add", systemAbilityId, listenerSaId);
296             return true;
297         }
298 
299         sptr<ISystemAbilityStatusChange> listener = new SystemAbilityListener(listenerSaId);
300         listenerMap_[key] = listener;
301         LOGI("AddSaListener SA:%{public}d,listenerSA:%{public}d", systemAbilityId, listenerSaId);
302     }
303 
304     int32_t ret = samgrProxy->SubscribeSystemAbility(systemAbilityId, listenerMap_[key]);
305     if (ret) {
306         HILOGE(TAG, "failed to subscribe SA:%{public}d, process name:%{public}s", systemAbilityId,
307             Str16ToStr8(procName_).c_str());
308         return false;
309     }
310     return true;
311 }
312 
RemoveSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)313 bool LocalAbilityManager::RemoveSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
314 {
315     if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
316         HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!",
317             systemAbilityId, listenerSaId);
318         return false;
319     }
320 
321     std::pair<int32_t, int32_t> key = std::make_pair(systemAbilityId, listenerSaId);
322     sptr<ISystemAbilityStatusChange> listener = nullptr;
323     {
324         std::lock_guard<std::mutex> autoLock(listenerLock_);
325         auto iter = listenerMap_.find(key);
326         if (iter != listenerMap_.end()) {
327             listener = listenerMap_[key];
328             listenerMap_.erase(iter);
329             LOGI("RmSaListener SA:%{public}d,listenerSA:%{public}d", systemAbilityId, listenerSaId);
330         }
331     }
332 
333     if (listener == nullptr) {
334         HILOGW(TAG, "SA:%{public}d,listenerSA:%{public}d,listener is null!", systemAbilityId, listenerSaId);
335         return true;
336     }
337 
338     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
339     if (samgrProxy == nullptr) {
340         HILOGE(TAG, "failed to get samgrProxy");
341         return false;
342     }
343     int32_t ret = samgrProxy->UnSubscribeSystemAbility(systemAbilityId, listener);
344     if (ret) {
345         HILOGE(TAG, "failed to unsubscribe SA:%{public}d, process name:%{public}s",
346             systemAbilityId, Str16ToStr8(procName_).c_str());
347         return false;
348     }
349     return true;
350 }
351 
NotifyAbilityListener(int32_t systemAbilityId,int32_t listenerSaId,const std::string & deviceId,int32_t code)352 void LocalAbilityManager::NotifyAbilityListener(int32_t systemAbilityId, int32_t listenerSaId,
353     const std::string& deviceId, int32_t code)
354 {
355     LOGI("NotifyListener SA:%{public}d,listenerSA:%{public}d,code:%{public}d", systemAbilityId, listenerSaId, code);
356     auto ability = GetAbility(listenerSaId);
357     if (ability == nullptr) {
358         HILOGE(TAG, "failed to get listener SA:%{public}d", listenerSaId);
359         return;
360     }
361 
362     switch (code) {
363         case ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY: {
364             HILOGD(TAG, "OnAddSystemAbility, SA:%{public}d", listenerSaId);
365             ability->OnAddSystemAbility(systemAbilityId, deviceId);
366             break;
367         }
368         case ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY: {
369             HILOGD(TAG, "OnRemoveSystemAbility, SA:%{public}d", listenerSaId);
370             ability->OnRemoveSystemAbility(systemAbilityId, deviceId);
371             break;
372         }
373         default:
374             break;
375     }
376 }
377 
OnStartAbility(int32_t systemAbilityId)378 bool LocalAbilityManager::OnStartAbility(int32_t systemAbilityId)
379 {
380     HILOGD(TAG, "try to start SA:%{public}d", systemAbilityId);
381     auto ability = GetAbility(systemAbilityId);
382     if (ability == nullptr) {
383         return false;
384     }
385     ability->Start();
386     return true;
387 }
388 
OnStopAbility(int32_t systemAbilityId)389 bool LocalAbilityManager::OnStopAbility(int32_t systemAbilityId)
390 {
391     HILOGD(TAG, "try to stop SA:%{public}d", systemAbilityId);
392     auto ability = GetAbility(systemAbilityId);
393     if (ability == nullptr) {
394         return false;
395     }
396     ability->Stop();
397     return true;
398 }
399 
GetAbility(int32_t systemAbilityId)400 SystemAbility* LocalAbilityManager::GetAbility(int32_t systemAbilityId)
401 {
402     std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
403     auto it = abilityMap_.find(systemAbilityId);
404     if (it == abilityMap_.end()) {
405         HILOGW(TAG, "SA:%{public}d not register", systemAbilityId);
406         return nullptr;
407     }
408 
409     return it->second;
410 }
411 
GetRunningStatus(int32_t systemAbilityId)412 bool LocalAbilityManager::GetRunningStatus(int32_t systemAbilityId)
413 {
414     auto ability = GetAbility(systemAbilityId);
415     if (ability == nullptr) {
416         return false;
417     }
418 
419     return ability->GetRunningStatus();
420 }
421 
StartOndemandSystemAbility(int32_t systemAbilityId)422 void LocalAbilityManager::StartOndemandSystemAbility(int32_t systemAbilityId)
423 {
424     pthread_setname_np(pthread_self(), ONDEMAND_WORKER);
425     LOGD("StartOndemandSa LoadSaLib SA:%{public}d library", systemAbilityId);
426     int64_t begin = GetTickCount();
427     bool isExist = profileParser_->LoadSaLib(systemAbilityId);
428     LOGI("StartOndemandSa LoadSaLib SA:%{public}d,spend:%{public}" PRId64 "ms",
429         systemAbilityId, (GetTickCount() - begin));
430     if (isExist) {
431         int32_t timeout = RETRY_TIMES_FOR_ONDEMAND;
432         constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_ONDEMAND_ONE_TIME).count();
433         {
434             std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
435             auto it = abilityMap_.find(systemAbilityId);
436             while (it == abilityMap_.end()) {
437                 HILOGI(TAG, "waiting for SA:%{public}d...", systemAbilityId);
438                 if (timeout > 0) {
439                     usleep(duration);
440                     it = abilityMap_.find(systemAbilityId);
441                 } else {
442                     HILOGE(TAG, "waiting for SA:%{public}d time out (1s)", systemAbilityId);
443                     return;
444                 }
445                 timeout--;
446             }
447         }
448 
449         if (!OnStartAbility(systemAbilityId)) {
450             HILOGE(TAG, "failed to start SA:%{public}d", systemAbilityId);
451         }
452     } else {
453         HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
454     }
455 }
456 
StartAbility(int32_t systemAbilityId,const std::string & eventStr)457 bool LocalAbilityManager::StartAbility(int32_t systemAbilityId, const std::string& eventStr)
458 {
459     LOGI("StartSa recv start SA:%{public}d req", systemAbilityId);
460     nlohmann::json startReason = ParseUtil::StringToJsonObj(eventStr);
461     SetStartReason(systemAbilityId, startReason);
462     auto task = [this, systemAbilityId] {this->StartOndemandSystemAbility(systemAbilityId);};
463     std::thread thread(task);
464     thread.detach();
465     return true;
466 }
467 
StopOndemandSystemAbility(int32_t systemAbilityId)468 void LocalAbilityManager::StopOndemandSystemAbility(int32_t systemAbilityId)
469 {
470     pthread_setname_np(pthread_self(), ONDEMAND_WORKER);
471     if (!OnStopAbility(systemAbilityId)) {
472         HILOGE(TAG, "failed to stop SA:%{public}d", systemAbilityId);
473     }
474 }
475 
StopAbility(int32_t systemAbilityId,const std::string & eventStr)476 bool LocalAbilityManager::StopAbility(int32_t systemAbilityId, const std::string& eventStr)
477 {
478     LOGI("StopSa recv stop SA:%{public}d req", systemAbilityId);
479     nlohmann::json stopReason = ParseUtil::StringToJsonObj(eventStr);
480     SetStopReason(systemAbilityId, stopReason);
481     auto task = [this, systemAbilityId] {this->StopOndemandSystemAbility(systemAbilityId);};
482     std::thread thread(task);
483     thread.detach();
484     return true;
485 }
486 
ActiveAbility(int32_t systemAbilityId,const nlohmann::json & activeReason)487 bool LocalAbilityManager::ActiveAbility(int32_t systemAbilityId,
488     const nlohmann::json& activeReason)
489 {
490     LOGD("ActiveSa:%{public}d", systemAbilityId);
491     auto ability = GetAbility(systemAbilityId);
492     if (ability == nullptr) {
493         return false;
494     }
495     SystemAbilityOnDemandReason onDemandActiveReason = JsonToOnDemandReason(activeReason);
496     ability->Active(onDemandActiveReason);
497     return true;
498 }
499 
IdleAbility(int32_t systemAbilityId,const nlohmann::json & idleReason,int32_t & delayTime)500 bool LocalAbilityManager::IdleAbility(int32_t systemAbilityId,
501     const nlohmann::json& idleReason, int32_t& delayTime)
502 {
503     HILOGD(TAG, "idle SA:%{public}d", systemAbilityId);
504     auto ability = GetAbility(systemAbilityId);
505     if (ability == nullptr) {
506         return false;
507     }
508     SystemAbilityOnDemandReason onDemandIdleReason = JsonToOnDemandReason(idleReason);
509     ability->Idle(onDemandIdleReason, delayTime);
510     return true;
511 }
512 
JsonToOnDemandReason(const nlohmann::json & reasonJson)513 SystemAbilityOnDemandReason LocalAbilityManager::JsonToOnDemandReason(const nlohmann::json& reasonJson)
514 {
515     SystemAbilityOnDemandReason onDemandStartReason;
516     if (reasonJson.contains(EVENT_ID) && reasonJson[EVENT_ID].is_number()) {
517         onDemandStartReason.SetId(reasonJson[EVENT_ID]);
518     }
519     if (reasonJson.contains(NAME) && reasonJson[NAME].is_string()) {
520         onDemandStartReason.SetName(reasonJson[NAME]);
521     }
522     if (reasonJson.contains(VALUE) && reasonJson[VALUE].is_string()) {
523         onDemandStartReason.SetValue(reasonJson[VALUE]);
524     }
525     if (reasonJson.contains(EXTRA_DATA_ID) && reasonJson[EXTRA_DATA_ID].is_number()) {
526         onDemandStartReason.SetExtraDataId(reasonJson[EXTRA_DATA_ID]);
527     }
528     return onDemandStartReason;
529 }
530 
InitializeOnDemandSaProfile(int32_t saId)531 bool LocalAbilityManager::InitializeOnDemandSaProfile(int32_t saId)
532 {
533     int64_t begin = GetTickCount();
534     LOGD("InitOnDemandSa LoadSaLib SA:%{public}d", saId);
535     bool result = profileParser_->LoadSaLib(saId);
536     LOGI("InitOnDemandSa LoadSaLib SA:%{public}d finished,spend:%{public}"
537         PRId64 "ms", saId, (GetTickCount() - begin));
538     if (!result) {
539         LOGW("InitOnDemandSa LoadSaLib fail,SA:{public}%d", saId);
540         return false;
541     }
542     SaProfile saProfile;
543     bool ret = profileParser_->GetProfile(saId, saProfile);
544     if (ret) {
545         return InitializeSaProfilesInnerLocked(saProfile);
546     }
547     return false;
548 }
549 
InitializeSaProfilesInnerLocked(const SaProfile & saProfile)550 bool LocalAbilityManager::InitializeSaProfilesInnerLocked(const SaProfile& saProfile)
551 {
552     std::unique_lock<std::shared_mutex> readLock(abilityMapLock_);
553     auto iterProfile = abilityMap_.find(saProfile.saId);
554     if (iterProfile == abilityMap_.end()) {
555         HILOGW(TAG, "SA:%{public}d not found", saProfile.saId);
556         return false;
557     }
558     auto systemAbility = iterProfile->second;
559     if (systemAbility == nullptr) {
560         HILOGW(TAG, "SA:%{public}d is null", saProfile.saId);
561         return false;
562     }
563     if (saProfile.bootPhase > OTHER_START) {
564         HILOGW(TAG, "invalid boot phase: %{public}d", saProfile.bootPhase);
565         return false;
566     }
567     auto& saList = abilityPhaseMap_[saProfile.bootPhase];
568     saList.emplace_back(systemAbility);
569     return true;
570 }
571 
CheckDependencyStatus(const vector<int32_t> & dependSa)572 vector<int32_t> LocalAbilityManager::CheckDependencyStatus(const vector<int32_t>& dependSa)
573 {
574     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
575     if (samgrProxy == nullptr) {
576         HILOGW(TAG, "failed to get samgrProxy");
577         return dependSa;
578     }
579 
580     vector<int32_t> checkSaStatusResult;
581     for (const auto& saId : dependSa) {
582         if (CheckInputSysAbilityId(saId)) {
583             sptr<IRemoteObject> saObject = samgrProxy->CheckSystemAbility(saId);
584             if (saObject == nullptr) {
585                 checkSaStatusResult.emplace_back(saId);
586             }
587         } else {
588             HILOGW(TAG, "dependency's SA:%{public}d is invalid", saId);
589         }
590     }
591     return checkSaStatusResult;
592 }
593 
StartDependSaTask(SystemAbility * ability)594 void LocalAbilityManager::StartDependSaTask(SystemAbility* ability)
595 {
596     if (ability == nullptr) {
597         HILOGE(TAG, "ability is null");
598         return;
599     }
600     int64_t start = GetTickCount();
601     int64_t dependTimeout = ability->GetDependTimeout();
602     size_t lastSize = CheckDependencyStatus(ability->GetDependSa()).size();
603     HILOGI(TAG, "SA:%{public}d's depend timeout:%{public}" PRId64 " ms,depend size:%{public}zu",
604         ability->GetSystemAbilitId(), dependTimeout, lastSize);
605     {
606         SamgrXCollie samgrXCollie("DependSaTimeout_" + ToString(ability->GetSystemAbilitId()), MAX_DEPEND_TIMEOUT);
607         while (lastSize > 0) {
608             int64_t end = GetTickCount();
609             int64_t duration = ((end >= start) ? (end - start) : (INT64_MAX - end + start));
610             if (duration < dependTimeout) {
611                 usleep(CHECK_DEPENDENT_SA_PERIOD);
612             } else {
613                 break;
614             }
615             vector<int32_t> temp = CheckDependencyStatus(ability->GetDependSa());
616             size_t curSize = temp.size();
617             if (curSize != lastSize) {
618                 HILOGI(TAG, "SA:%{public}d's depend left:%{public}zu", ability->GetSystemAbilitId(), curSize);
619             }
620             lastSize = curSize;
621         }
622     }
623     vector<int32_t> unpreparedDeps = CheckDependencyStatus(ability->GetDependSa());
624     if (unpreparedDeps.empty()) {
625         HILOGI(TAG, "SA:%{public}d's depend all start", ability->GetSystemAbilitId());
626         ability->Start();
627     } else {
628         for (const auto& unpreparedDep : unpreparedDeps) {
629             HILOGI(TAG, "%{public}d's dependency:%{public}d not started in %{public}d ms",
630                 ability->GetSystemAbilitId(), unpreparedDep, ability->GetDependTimeout());
631         }
632     }
633 }
634 
StartSystemAbilityTask(SystemAbility * ability)635 void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
636 {
637     if (ability != nullptr) {
638         HILOGD(TAG, "StartSystemAbility is called for SA:%{public}d", ability->GetSystemAbilitId());
639         if (ability->GetDependSa().empty()) {
640             ability->Start();
641         } else {
642             StartDependSaTask(ability);
643         }
644         KHILOGI(TAG, "%{public}s SA:%{public}d init finished, %{public}" PRId64 " ms",
645             Str16ToStr8(procName_).c_str(), ability->GetSystemAbilitId(), (GetTickCount() - startBegin_));
646     }
647 
648     std::lock_guard<std::mutex> lock(startPhaseLock_);
649     if (startTaskNum_ > 0) {
650         --startTaskNum_;
651     }
652     startPhaseCV_.notify_one();
653 }
654 
RegisterOnDemandSystemAbility(int32_t saId)655 void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId)
656 {
657     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
658     if (samgrProxy == nullptr) {
659         HILOGI(TAG, "failed to get samgrProxy");
660         return;
661     }
662 
663     auto& saProfileList = profileParser_->GetAllSaProfiles();
664     for (const auto& saProfile : saProfileList) {
665         if (NeedRegisterOnDemand(saProfile, saId)) {
666             HILOGD(TAG, "register ondemand SA:%{public}d to samgr", saProfile.saId);
667             int32_t ret = samgrProxy->AddOnDemandSystemAbilityInfo(saProfile.saId, procName_);
668             if (ret != ERR_OK) {
669                 HILOGI(TAG, "failed to add ability info for on-demand SA:%{public}d", saProfile.saId);
670             }
671         }
672     }
673 }
674 
675 // on default load, not-run-on-create SA will register to OnDemandSystemAbility
676 // on demand load, other SA will register to OnDemandSystemAbility, although some are runOnCreate
NeedRegisterOnDemand(const SaProfile & saProfile,int32_t saId)677 bool LocalAbilityManager::NeedRegisterOnDemand(const SaProfile& saProfile, int32_t saId)
678 {
679     return (saId == DEFAULT_SAID && !saProfile.runOnCreate) ||
680         (saId != DEFAULT_SAID && saProfile.saId != saId);
681 }
682 
StartPhaseTasks(const std::list<SystemAbility * > & systemAbilityList)683 void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
684 {
685     if (systemAbilityList.empty()) {
686         return;
687     }
688 
689     for (auto systemAbility : systemAbilityList) {
690         if (systemAbility != nullptr) {
691             HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
692             std::lock_guard<std::mutex> autoLock(startPhaseLock_);
693             ++startTaskNum_;
694             auto task = [this, systemAbility] {this->StartSystemAbilityTask(systemAbility);};
695             initPool_->AddTask(task);
696         }
697     }
698 }
699 
WaitForTasks()700 void LocalAbilityManager::WaitForTasks()
701 {
702     int64_t begin = GetTickCount();
703     HILOGD(TAG, "start waiting for all tasks!");
704     std::unique_lock<std::mutex> lck(startPhaseLock_);
705     if (!startPhaseCV_.wait_for(lck, std::chrono::seconds(MAX_SA_STARTUP_TIME),
706         [this] () { return startTaskNum_ == 0; })) {
707         HILOGW(TAG, "start timeout!");
708     }
709     startTaskNum_ = 0;
710     int64_t end = GetTickCount();
711     LOGI("start tasks proc:%{public}s end,spend %{public}" PRId64 "ms",
712         Str16ToStr8(procName_).c_str(), (end - begin));
713 }
714 
FindAndStartPhaseTasks(int32_t saId)715 void LocalAbilityManager::FindAndStartPhaseTasks(int32_t saId)
716 {
717     if (saId == DEFAULT_SAID) {
718         for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
719             auto iter = abilityPhaseMap_.find(bootPhase);
720             if (iter != abilityPhaseMap_.end()) {
721                 StartPhaseTasks(iter->second);
722                 InitializeRunOnCreateSaProfiles(bootPhase + 1);
723                 WaitForTasks();
724             } else {
725                 InitializeRunOnCreateSaProfiles(bootPhase + 1);
726             }
727         }
728     } else {
729         for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
730             auto iter = abilityPhaseMap_.find(bootPhase);
731             if (iter != abilityPhaseMap_.end()) {
732                 StartPhaseTasks(iter->second);
733                 WaitForTasks();
734             }
735         }
736     }
737 }
738 
InitializeRunOnCreateSaProfiles(uint32_t bootPhase)739 bool LocalAbilityManager::InitializeRunOnCreateSaProfiles(uint32_t bootPhase)
740 {
741     if (bootPhase > OTHER_START) {
742         return false;
743     }
744     int64_t begin = GetTickCount();
745     LOGD("ROC_InitProfiles load phase %{public}d libraries", bootPhase);
746     profileParser_->OpenSo(bootPhase);
747     LOGI("ROC_InitProfiles proc:%{public}s phase:%{public}d end, spend:%{public}" PRId64 "ms",
748         Str16ToStr8(procName_).c_str(), bootPhase, (GetTickCount() - begin));
749     auto& saProfileList = profileParser_->GetAllSaProfiles();
750     if (saProfileList.empty()) {
751         HILOGW(TAG, "sa profile is empty");
752         return false;
753     }
754     for (const auto& saProfile : saProfileList) {
755         if (saProfile.bootPhase != bootPhase) {
756             continue;
757         }
758         if (!InitializeSaProfilesInnerLocked(saProfile)) {
759             HILOGW(TAG, "SA:%{public}d init fail", saProfile.saId);
760             continue;
761         }
762     }
763     return true;
764 }
765 
Run(int32_t saId)766 bool LocalAbilityManager::Run(int32_t saId)
767 {
768     HILOGD(TAG, "local ability manager is running...");
769     bool addResult = AddLocalAbilityManager();
770     if (!addResult) {
771         HILOGE(TAG, "failed to add local abilitymanager");
772         return false;
773     }
774     LOGD("Run succ to add proc name:%{public}s", Str16ToStr8(procName_).c_str());
775     uint32_t concurrentThreads = std::thread::hardware_concurrency();
776     LOGI("Run curThread is %{public}d,proc:%{public}s,SA:%{public}d",
777         concurrentThreads, Str16ToStr8(procName_).c_str(), saId);
778     initPool_->Start(concurrentThreads);
779     initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
780 
781     RegisterOnDemandSystemAbility(saId);
782     FindAndStartPhaseTasks(saId);
783     initPool_->Stop();
784     return true;
785 }
786 
AddLocalAbilityManager()787 bool LocalAbilityManager::AddLocalAbilityManager()
788 {
789     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
790     if (samgrProxy == nullptr) {
791         HILOGE(TAG, "failed to get samgrProxy");
792         return false;
793     }
794 
795     if (localAbilityManager_ == nullptr) {
796         localAbilityManager_ = this;
797     }
798     int32_t ret = samgrProxy->AddSystemProcess(procName_, localAbilityManager_);
799     return ret == ERR_OK;
800 }
801 
SetStartReason(int32_t saId,const nlohmann::json & event)802 void LocalAbilityManager::SetStartReason(int32_t saId, const nlohmann::json& event)
803 {
804     std::lock_guard<std::mutex> autoLock(ReasonLock_);
805     saIdToStartReason_[saId] = event;
806 }
807 
SetStopReason(int32_t saId,const nlohmann::json & event)808 void LocalAbilityManager::SetStopReason(int32_t saId, const nlohmann::json& event)
809 {
810     std::lock_guard<std::mutex> autoLock(ReasonLock_);
811     saIdToStopReason_[saId] = event;
812 }
813 
GetStartReason(int32_t saId)814 nlohmann::json LocalAbilityManager::GetStartReason(int32_t saId)
815 {
816     std::lock_guard<std::mutex> autoLock(ReasonLock_);
817     return saIdToStartReason_[saId];
818 }
819 
GetStopReason(int32_t saId)820 nlohmann::json LocalAbilityManager::GetStopReason(int32_t saId)
821 {
822     std::lock_guard<std::mutex> autoLock(ReasonLock_);
823     return saIdToStopReason_[saId];
824 }
825 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)826 void LocalAbilityManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
827     const std::string& deviceId)
828 {
829     HILOGD(TAG, "SA:%{public}d added", systemAbilityId);
830     if (!CheckInputSysAbilityId(systemAbilityId)) {
831         HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
832         return;
833     }
834 
835     GetInstance().NotifyAbilityListener(systemAbilityId, GetListenerSaId(), deviceId,
836         ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
837 }
838 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)839 void LocalAbilityManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
840     const std::string& deviceId)
841 {
842     HILOGD(TAG, "SA:%{public}d removed", systemAbilityId);
843     if (!CheckInputSysAbilityId(systemAbilityId)) {
844         HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
845         return;
846     }
847 
848     GetInstance().NotifyAbilityListener(systemAbilityId, GetListenerSaId(), deviceId,
849         ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY);
850 }
851 
SendStrategyToSA(int32_t type,int32_t systemAbilityId,int32_t level,std::string & action)852 bool LocalAbilityManager::SendStrategyToSA(int32_t type, int32_t systemAbilityId, int32_t level, std::string& action)
853 {
854     HILOGD(TAG, "SendStrategyTo SA:%{public}d", systemAbilityId);
855     auto ability = GetAbility(systemAbilityId);
856     if (ability == nullptr) {
857         HILOGW(TAG, "failed to get SA:%{public}d", systemAbilityId);
858         return false;
859     }
860     ability->OnDeviceLevelChanged(type, level, action);
861     return true;
862 }
863 
IpcStatCmdProc(int32_t fd,int32_t cmd)864 bool LocalAbilityManager::IpcStatCmdProc(int32_t fd, int32_t cmd)
865 {
866     bool ret = false;
867     std::string result;
868 
869     HILOGI(TAG, "IpcStatCmdProc:fd=%{public}d cmd=%{public}d request", fd, cmd);
870     if (cmd < IPC_STAT_CMD_START || cmd >= IPC_STAT_CMD_MAX) {
871         HILOGW(TAG, "para invalid, fd=%{public}d cmd=%{public}d", fd, cmd);
872         return false;
873     }
874 
875     switch (cmd) {
876         case IPC_STAT_CMD_START: {
877             ret = LocalAbilityManagerDumper::StartIpcStatistics(result);
878             break;
879         }
880         case IPC_STAT_CMD_STOP: {
881             ret = LocalAbilityManagerDumper::StopIpcStatistics(result);
882             break;
883         }
884         case IPC_STAT_CMD_GET: {
885             ret = LocalAbilityManagerDumper::GetIpcStatistics(result);
886             break;
887         }
888         default:
889             return false;
890     }
891 
892     if (!SaveStringToFd(fd, result)) {
893         HILOGW(TAG, "save to fd failed");
894         return false;
895     }
896     return ret;
897 }
898 
899 typedef void (*PGetSdkName)(uint32_t cmd, char *buf, uint32_t len);
900 
FfrtDumperProc(std::string & ffrtDumperInfo)901 bool LocalAbilityManager::FfrtDumperProc(std::string& ffrtDumperInfo)
902 {
903     HILOGI(TAG, "FfrtDumperPorc request");
904     PGetSdkName pFFrtDumpInfo = (PGetSdkName)dlsym(RTLD_DEFAULT, "ffrt_dump");
905     char* pszErr = dlerror();
906     if (pszErr != NULL) {
907         HILOGE(TAG, "dlsym err info: %{public}s", pszErr);
908     }
909     if (pFFrtDumpInfo == NULL) {
910         HILOGE(TAG, "dlsym failed");
911         ffrtDumperInfo.append("process " + std::to_string(getpid()) + " did not load ffrt\n");
912         return false;
913     }
914     char* buffer = new char[FFRT_BUFFER_SIZE + 1]();
915     buffer[FFRT_BUFFER_SIZE] = 0;
916     (*pFFrtDumpInfo)(FFRT_DUMP_INFO_ALL, buffer, FFRT_BUFFER_SIZE);
917     if (strlen(buffer) == 0) {
918         HILOGE(TAG, "get samgr FfrtDumperInfo failed");
919         delete[] buffer;
920         return false;
921     }
922     ffrtDumperInfo += buffer;
923     delete[] buffer;
924     return true;
925 }
926 
SystemAbilityExtProc(const std::string & extension,int32_t said,SystemAbilityExtensionPara * callback,bool isAsync)927 int32_t LocalAbilityManager::SystemAbilityExtProc(const std::string& extension, int32_t said,
928     SystemAbilityExtensionPara* callback, bool isAsync)
929 {
930     (void)isAsync;
931     if (callback == nullptr) {
932         return INVALID_DATA;
933     }
934 
935     HILOGD(TAG, "SystemAbilityExtProc Extension %{public}s SA:%{public}d", extension.c_str(), said);
936     auto ability = GetAbility(said);
937     if (ability == nullptr) {
938         return INVALID_DATA;
939     }
940     return ability->OnExtension(extension, *callback->data_, *callback->reply_);
941 }
942 }
943