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