• 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 
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     auto& saList = abilityPhaseMap_[saProfile.bootPhase];
560     saList.emplace_back(systemAbility);
561     return true;
562 }
563 
CheckDependencyStatus(const vector<int32_t> & dependSa)564 vector<int32_t> LocalAbilityManager::CheckDependencyStatus(const vector<int32_t>& dependSa)
565 {
566     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
567     if (samgrProxy == nullptr) {
568         HILOGW(TAG, "failed to get samgrProxy");
569         return dependSa;
570     }
571 
572     vector<int32_t> checkSaStatusResult;
573     for (const auto& saId : dependSa) {
574         if (CheckInputSysAbilityId(saId)) {
575             sptr<IRemoteObject> saObject = samgrProxy->CheckSystemAbility(saId);
576             if (saObject == nullptr) {
577                 checkSaStatusResult.emplace_back(saId);
578             }
579         } else {
580             HILOGW(TAG, "dependency's SA:%{public}d is invalid", saId);
581         }
582     }
583     return checkSaStatusResult;
584 }
585 
StartDependSaTask(SystemAbility * ability)586 void LocalAbilityManager::StartDependSaTask(SystemAbility* ability)
587 {
588     if (ability == nullptr) {
589         HILOGE(TAG, "ability is null");
590         return;
591     }
592     int64_t start = GetTickCount();
593     int64_t dependTimeout = ability->GetDependTimeout();
594     size_t lastSize = CheckDependencyStatus(ability->GetDependSa()).size();
595     HILOGI(TAG, "SA:%{public}d's depend timeout:%{public}" PRId64 " ms,depend size:%{public}zu",
596         ability->GetSystemAbilitId(), dependTimeout, lastSize);
597     {
598         SamgrXCollie samgrXCollie("DependSaTimeout_" + ToString(ability->GetSystemAbilitId()), MAX_DEPEND_TIMEOUT);
599         while (lastSize > 0) {
600             int64_t end = GetTickCount();
601             int64_t duration = ((end >= start) ? (end - start) : (INT64_MAX - end + start));
602             if (duration < dependTimeout) {
603                 usleep(CHECK_DEPENDENT_SA_PERIOD);
604             } else {
605                 break;
606             }
607             vector<int32_t> temp = CheckDependencyStatus(ability->GetDependSa());
608             size_t curSize = temp.size();
609             if (curSize != lastSize) {
610                 HILOGI(TAG, "SA:%{public}d's depend left:%{public}zu", ability->GetSystemAbilitId(), curSize);
611             }
612             lastSize = curSize;
613         }
614     }
615     vector<int32_t> unpreparedDeps = CheckDependencyStatus(ability->GetDependSa());
616     if (unpreparedDeps.empty()) {
617         HILOGI(TAG, "SA:%{public}d's depend all start", ability->GetSystemAbilitId());
618         ability->Start();
619     } else {
620         for (const auto& unpreparedDep : unpreparedDeps) {
621             HILOGI(TAG, "%{public}d's dependency:%{public}d not started in %{public}d ms",
622                 ability->GetSystemAbilitId(), unpreparedDep, ability->GetDependTimeout());
623         }
624     }
625 }
626 
StartSystemAbilityTask(SystemAbility * ability)627 void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
628 {
629     if (ability != nullptr) {
630         HILOGD(TAG, "StartSystemAbility is called for SA:%{public}d", ability->GetSystemAbilitId());
631         if (ability->GetDependSa().empty()) {
632             ability->Start();
633         } else {
634             StartDependSaTask(ability);
635         }
636         KHILOGI(TAG, "%{public}s SA:%{public}d init finished, %{public}" PRId64 " ms",
637             Str16ToStr8(procName_).c_str(), ability->GetSystemAbilitId(), (GetTickCount() - startBegin_));
638     }
639 
640     std::lock_guard<std::mutex> lock(startPhaseLock_);
641     if (startTaskNum_ > 0) {
642         --startTaskNum_;
643     }
644     startPhaseCV_.notify_one();
645 }
646 
RegisterOnDemandSystemAbility(int32_t saId)647 void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId)
648 {
649     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
650     if (samgrProxy == nullptr) {
651         HILOGI(TAG, "failed to get samgrProxy");
652         return;
653     }
654 
655     auto& saProfileList = profileParser_->GetAllSaProfiles();
656     for (const auto& saProfile : saProfileList) {
657         if (NeedRegisterOnDemand(saProfile, saId)) {
658             HILOGD(TAG, "register ondemand SA:%{public}d to samgr", saProfile.saId);
659             int32_t ret = samgrProxy->AddOnDemandSystemAbilityInfo(saProfile.saId, procName_);
660             if (ret != ERR_OK) {
661                 HILOGI(TAG, "failed to add ability info for on-demand SA:%{public}d", saProfile.saId);
662             }
663         }
664     }
665 }
666 
667 // on default load, not-run-on-create SA will register to OnDemandSystemAbility
668 // on demand load, other SA will register to OnDemandSystemAbility, although some are runOnCreate
NeedRegisterOnDemand(const SaProfile & saProfile,int32_t saId)669 bool LocalAbilityManager::NeedRegisterOnDemand(const SaProfile& saProfile, int32_t saId)
670 {
671     return (saId == DEFAULT_SAID && !saProfile.runOnCreate) ||
672         (saId != DEFAULT_SAID && saProfile.saId != saId);
673 }
674 
StartPhaseTasks(const std::list<SystemAbility * > & systemAbilityList)675 void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
676 {
677     if (systemAbilityList.empty()) {
678         return;
679     }
680 
681     for (auto systemAbility : systemAbilityList) {
682         if (systemAbility != nullptr) {
683             HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
684             std::lock_guard<std::mutex> autoLock(startPhaseLock_);
685             ++startTaskNum_;
686             auto task = [this, systemAbility] {this->StartSystemAbilityTask(systemAbility);};
687             initPool_->AddTask(task);
688         }
689     }
690 }
691 
WaitForTasks()692 void LocalAbilityManager::WaitForTasks()
693 {
694     int64_t begin = GetTickCount();
695     HILOGD(TAG, "start waiting for all tasks!");
696     std::unique_lock<std::mutex> lck(startPhaseLock_);
697     if (!startPhaseCV_.wait_for(lck, std::chrono::seconds(MAX_SA_STARTUP_TIME),
698         [this] () { return startTaskNum_ == 0; })) {
699         HILOGW(TAG, "start timeout!");
700     }
701     startTaskNum_ = 0;
702     int64_t end = GetTickCount();
703     LOGI("start tasks proc:%{public}s end,spend %{public}" PRId64 "ms",
704         Str16ToStr8(procName_).c_str(), (end - begin));
705 }
706 
FindAndStartPhaseTasks(int32_t saId)707 void LocalAbilityManager::FindAndStartPhaseTasks(int32_t saId)
708 {
709     if (saId == DEFAULT_SAID) {
710         for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
711             auto iter = abilityPhaseMap_.find(bootPhase);
712             if (iter != abilityPhaseMap_.end()) {
713                 StartPhaseTasks(iter->second);
714                 InitializeRunOnCreateSaProfiles(bootPhase + 1);
715                 WaitForTasks();
716             } else {
717                 InitializeRunOnCreateSaProfiles(bootPhase + 1);
718             }
719         }
720     } else {
721         for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
722             auto iter = abilityPhaseMap_.find(bootPhase);
723             if (iter != abilityPhaseMap_.end()) {
724                 StartPhaseTasks(iter->second);
725                 WaitForTasks();
726             }
727         }
728     }
729 }
730 
InitializeRunOnCreateSaProfiles(uint32_t bootPhase)731 bool LocalAbilityManager::InitializeRunOnCreateSaProfiles(uint32_t bootPhase)
732 {
733     if (bootPhase > OTHER_START) {
734         return false;
735     }
736     int64_t begin = GetTickCount();
737     LOGD("ROC_InitProfiles load phase %{public}d libraries", bootPhase);
738     profileParser_->OpenSo(bootPhase);
739     LOGI("ROC_InitProfiles proc:%{public}s phase:%{public}d end, spend:%{public}" PRId64 "ms",
740         Str16ToStr8(procName_).c_str(), bootPhase, (GetTickCount() - begin));
741     auto& saProfileList = profileParser_->GetAllSaProfiles();
742     if (saProfileList.empty()) {
743         HILOGW(TAG, "sa profile is empty");
744         return false;
745     }
746     for (const auto& saProfile : saProfileList) {
747         if (saProfile.bootPhase != bootPhase) {
748             continue;
749         }
750         if (!InitializeSaProfilesInnerLocked(saProfile)) {
751             HILOGW(TAG, "SA:%{public}d init fail", saProfile.saId);
752             continue;
753         }
754     }
755     return true;
756 }
757 
Run(int32_t saId)758 bool LocalAbilityManager::Run(int32_t saId)
759 {
760     HILOGD(TAG, "local ability manager is running...");
761     bool addResult = AddLocalAbilityManager();
762     if (!addResult) {
763         HILOGE(TAG, "failed to add local abilitymanager");
764         return false;
765     }
766     LOGD("Run succ to add proc name:%{public}s", Str16ToStr8(procName_).c_str());
767     uint32_t concurrentThreads = std::thread::hardware_concurrency();
768     LOGI("Run curThread is %{public}d,proc:%{public}s,SA:%{public}d",
769         concurrentThreads, Str16ToStr8(procName_).c_str(), saId);
770     initPool_->Start(concurrentThreads);
771     initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
772 
773     RegisterOnDemandSystemAbility(saId);
774     FindAndStartPhaseTasks(saId);
775     initPool_->Stop();
776     return true;
777 }
778 
AddLocalAbilityManager()779 bool LocalAbilityManager::AddLocalAbilityManager()
780 {
781     auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
782     if (samgrProxy == nullptr) {
783         HILOGE(TAG, "failed to get samgrProxy");
784         return false;
785     }
786 
787     if (localAbilityManager_ == nullptr) {
788         localAbilityManager_ = this;
789     }
790     int32_t ret = samgrProxy->AddSystemProcess(procName_, localAbilityManager_);
791     return ret == ERR_OK;
792 }
793 
SetStartReason(int32_t saId,const nlohmann::json & event)794 void LocalAbilityManager::SetStartReason(int32_t saId, const nlohmann::json& event)
795 {
796     std::lock_guard<std::mutex> autoLock(ReasonLock_);
797     saIdToStartReason_[saId] = event;
798 }
799 
SetStopReason(int32_t saId,const nlohmann::json & event)800 void LocalAbilityManager::SetStopReason(int32_t saId, const nlohmann::json& event)
801 {
802     std::lock_guard<std::mutex> autoLock(ReasonLock_);
803     saIdToStopReason_[saId] = event;
804 }
805 
GetStartReason(int32_t saId)806 nlohmann::json LocalAbilityManager::GetStartReason(int32_t saId)
807 {
808     std::lock_guard<std::mutex> autoLock(ReasonLock_);
809     return saIdToStartReason_[saId];
810 }
811 
GetStopReason(int32_t saId)812 nlohmann::json LocalAbilityManager::GetStopReason(int32_t saId)
813 {
814     std::lock_guard<std::mutex> autoLock(ReasonLock_);
815     return saIdToStopReason_[saId];
816 }
817 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)818 void LocalAbilityManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
819     const std::string& deviceId)
820 {
821     HILOGD(TAG, "SA:%{public}d added", systemAbilityId);
822     if (!CheckInputSysAbilityId(systemAbilityId)) {
823         HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
824         return;
825     }
826 
827     GetInstance().NotifyAbilityListener(systemAbilityId, GetListenerSaId(), deviceId,
828         ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
829 }
830 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)831 void LocalAbilityManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
832     const std::string& deviceId)
833 {
834     HILOGD(TAG, "SA:%{public}d removed", systemAbilityId);
835     if (!CheckInputSysAbilityId(systemAbilityId)) {
836         HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
837         return;
838     }
839 
840     GetInstance().NotifyAbilityListener(systemAbilityId, GetListenerSaId(), deviceId,
841         ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY);
842 }
843 
SendStrategyToSA(int32_t type,int32_t systemAbilityId,int32_t level,std::string & action)844 bool LocalAbilityManager::SendStrategyToSA(int32_t type, int32_t systemAbilityId, int32_t level, std::string& action)
845 {
846     HILOGD(TAG, "SendStrategyTo SA:%{public}d", systemAbilityId);
847     auto ability = GetAbility(systemAbilityId);
848     if (ability == nullptr) {
849         HILOGW(TAG, "failed to get SA:%{public}d", systemAbilityId);
850         return false;
851     }
852     ability->OnDeviceLevelChanged(type, level, action);
853     return true;
854 }
855 
IpcStatCmdProc(int32_t fd,int32_t cmd)856 bool LocalAbilityManager::IpcStatCmdProc(int32_t fd, int32_t cmd)
857 {
858     bool ret = false;
859     std::string result;
860 
861     HILOGI(TAG, "IpcStatCmdProc:fd=%{public}d cmd=%{public}d request", fd, cmd);
862     if (cmd < IPC_STAT_CMD_START || cmd >= IPC_STAT_CMD_MAX) {
863         HILOGW(TAG, "para invalid, fd=%{public}d cmd=%{public}d", fd, cmd);
864         return false;
865     }
866 
867     switch (cmd) {
868         case IPC_STAT_CMD_START: {
869             ret = LocalAbilityManagerDumper::StartIpcStatistics(result);
870             break;
871         }
872         case IPC_STAT_CMD_STOP: {
873             ret = LocalAbilityManagerDumper::StopIpcStatistics(result);
874             break;
875         }
876         case IPC_STAT_CMD_GET: {
877             ret = LocalAbilityManagerDumper::GetIpcStatistics(result);
878             break;
879         }
880         default:
881             return false;
882     }
883 
884     if (!SaveStringToFd(fd, result)) {
885         HILOGW(TAG, "save to fd failed");
886         return false;
887     }
888     return ret;
889 }
890 
891 typedef void (*PGetSdkName)(uint32_t cmd, char *buf, uint32_t len);
892 
FfrtDumperProc(std::string & ffrtDumperInfo)893 bool LocalAbilityManager::FfrtDumperProc(std::string& ffrtDumperInfo)
894 {
895     HILOGI(TAG, "FfrtDumperPorc request");
896     PGetSdkName pFFrtDumpInfo = (PGetSdkName)dlsym(RTLD_DEFAULT, "ffrt_dump");
897     char* pszErr = dlerror();
898     if (pszErr != NULL) {
899         HILOGE(TAG, "dlsym err info: %{public}s", pszErr);
900     }
901     if (pFFrtDumpInfo == NULL) {
902         HILOGE(TAG, "dlsym failed");
903         ffrtDumperInfo.append("process " + std::to_string(getpid()) + " did not load ffrt\n");
904         return false;
905     }
906     char* buffer = new char[FFRT_BUFFER_SIZE + 1]();
907     buffer[FFRT_BUFFER_SIZE] = 0;
908     (*pFFrtDumpInfo)(FFRT_DUMP_INFO_ALL, buffer, FFRT_BUFFER_SIZE);
909     if (strlen(buffer) == 0) {
910         HILOGE(TAG, "get samgr FfrtDumperInfo failed");
911         delete[] buffer;
912         return false;
913     }
914     ffrtDumperInfo += buffer;
915     delete[] buffer;
916     return true;
917 }
918 
SystemAbilityExtProc(const std::string & extension,int32_t said,SystemAbilityExtensionPara * callback,bool isAsync)919 int32_t LocalAbilityManager::SystemAbilityExtProc(const std::string& extension, int32_t said,
920     SystemAbilityExtensionPara* callback, bool isAsync)
921 {
922     (void)isAsync;
923     if (callback == nullptr) {
924         return INVALID_DATA;
925     }
926 
927     HILOGD(TAG, "SystemAbilityExtProc Extension %{public}s SA:%{public}d", extension.c_str(), said);
928     auto ability = GetAbility(said);
929     if (ability == nullptr) {
930         return INVALID_DATA;
931     }
932     return ability->OnExtension(extension, *callback->data_, *callback->reply_);
933 }
934 }
935