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