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 HILOGI(TAG, "DoStartSAProcess saId : %{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, "waiting for samgr...");
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] SAFWK parse system ability 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] SAFWK parse process:%{public}s system ability 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 ability:%{public}d!", saId);
245 return false;
246 }
247 HILOGI(TAG, "set profile attributes 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 {
285 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
286 std::lock_guard<std::mutex> autoLock(listenerLock_);
287 auto& listenerSaIdList = listenerMap_[systemAbilityId];
288 auto iter = std::find_if(listenerSaIdList.begin(), listenerSaIdList.end(), [listenerSaId](int32_t SaId) {
289 return SaId == listenerSaId;
290 });
291 if (iter == listenerSaIdList.end()) {
292 listenerSaIdList.emplace_back(listenerSaId);
293 }
294 HILOGI(TAG, "AddSystemAbilityListener SA:%{public}d, size:%{public}zu", systemAbilityId,
295 listenerSaIdList.size());
296 if (listenerSaIdList.size() > 1) {
297 sptr<IRemoteObject> object = samgrProxy->CheckSystemAbility(systemAbilityId);
298 if (object != nullptr) {
299 NotifyAbilityListener(systemAbilityId, listenerSaId, "",
300 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
301 }
302 return true;
303 }
304 }
305
306 int32_t ret = samgrProxy->SubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
307 if (ret) {
308 HILOGE(TAG, "failed to subscribe sa:%{public}d, process name:%{public}s", systemAbilityId,
309 Str16ToStr8(procName_).c_str());
310 return false;
311 }
312 return true;
313 }
314
RemoveSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)315 bool LocalAbilityManager::RemoveSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
316 {
317 if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
318 HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!",
319 systemAbilityId, listenerSaId);
320 return false;
321 }
322
323 {
324 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
325 std::lock_guard<std::mutex> autoLock(listenerLock_);
326 if (listenerMap_.count(systemAbilityId) == 0) {
327 return true;
328 }
329 auto& listenerSaIdList = listenerMap_[systemAbilityId];
330 auto iter = std::find_if(listenerSaIdList.begin(), listenerSaIdList.end(), [listenerSaId](int32_t SaId) {
331 return SaId == listenerSaId;
332 });
333 if (iter != listenerSaIdList.end()) {
334 listenerSaIdList.erase(iter);
335 }
336 HILOGI(TAG, "RemoveSystemAbilityListener SA:%{public}d, size:%{public}zu", systemAbilityId,
337 listenerSaIdList.size());
338 if (!listenerSaIdList.empty()) {
339 return true;
340 }
341 listenerMap_.erase(systemAbilityId);
342 }
343
344 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
345 if (samgrProxy == nullptr) {
346 HILOGE(TAG, "failed to get samgrProxy");
347 return false;
348 }
349 int32_t ret = samgrProxy->UnSubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
350 if (ret) {
351 HILOGE(TAG, "failed to unsubscribe SA:%{public}d, process name:%{public}s",
352 systemAbilityId, Str16ToStr8(procName_).c_str());
353 return false;
354 }
355 return true;
356 }
357
NotifyAbilityListener(int32_t systemAbilityId,int32_t listenerSaId,const std::string & deviceId,int32_t code)358 void LocalAbilityManager::NotifyAbilityListener(int32_t systemAbilityId, int32_t listenerSaId,
359 const std::string& deviceId, int32_t code)
360 {
361 HILOGI(TAG, "SA:%{public}d, listenerSA:%{public}d, code:%{public}d", systemAbilityId, listenerSaId, code);
362 auto ability = GetAbility(listenerSaId);
363 if (ability == nullptr) {
364 HILOGE(TAG, "failed to get listener SA:%{public}d", listenerSaId);
365 return;
366 }
367
368 switch (code) {
369 case ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY: {
370 HILOGD(TAG, "OnAddSystemAbility, SA:%{public}d", listenerSaId);
371 ability->OnAddSystemAbility(systemAbilityId, deviceId);
372 break;
373 }
374 case ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY: {
375 HILOGD(TAG, "OnRemoveSystemAbility, SA:%{public}d", listenerSaId);
376 ability->OnRemoveSystemAbility(systemAbilityId, deviceId);
377 break;
378 }
379 default:
380 break;
381 }
382 }
383
FindAndNotifyAbilityListeners(int32_t systemAbilityId,const std::string & deviceId,int32_t code)384 void LocalAbilityManager::FindAndNotifyAbilityListeners(int32_t systemAbilityId,
385 const std::string& deviceId, int32_t code)
386 {
387 HILOGD(TAG, "SA:%{public}d, code:%{public}d", systemAbilityId, code);
388 int64_t begin = GetTickCount();
389 std::list<int32_t> listenerSaIdList;
390 {
391 std::lock_guard<std::mutex> autoLock(listenerLock_);
392 auto iter = listenerMap_.find(systemAbilityId);
393 if (iter != listenerMap_.end()) {
394 listenerSaIdList = iter->second;
395 } else {
396 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
397 }
398 }
399 for (auto listenerSaId : listenerSaIdList) {
400 NotifyAbilityListener(systemAbilityId, listenerSaId, deviceId, code);
401 }
402 HILOGI(TAG, "SA:%{public}d, code:%{public}d spend:%{public}" PRId64 " ms", systemAbilityId, code,
403 GetTickCount() - begin);
404 }
405
OnStartAbility(int32_t systemAbilityId)406 bool LocalAbilityManager::OnStartAbility(int32_t systemAbilityId)
407 {
408 HILOGD(TAG, "try to start SA:%{public}d", systemAbilityId);
409 auto ability = GetAbility(systemAbilityId);
410 if (ability == nullptr) {
411 return false;
412 }
413 ability->Start();
414 return true;
415 }
416
OnStopAbility(int32_t systemAbilityId)417 bool LocalAbilityManager::OnStopAbility(int32_t systemAbilityId)
418 {
419 HILOGD(TAG, "try to stop SA:%{public}d", systemAbilityId);
420 auto ability = GetAbility(systemAbilityId);
421 if (ability == nullptr) {
422 return false;
423 }
424 ability->Stop();
425 return true;
426 }
427
GetAbility(int32_t systemAbilityId)428 SystemAbility* LocalAbilityManager::GetAbility(int32_t systemAbilityId)
429 {
430 std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
431 auto it = abilityMap_.find(systemAbilityId);
432 if (it == abilityMap_.end()) {
433 HILOGW(TAG, "SA:%{public}d not register", systemAbilityId);
434 return nullptr;
435 }
436
437 return it->second;
438 }
439
GetRunningStatus(int32_t systemAbilityId)440 bool LocalAbilityManager::GetRunningStatus(int32_t systemAbilityId)
441 {
442 auto ability = GetAbility(systemAbilityId);
443 if (ability == nullptr) {
444 return false;
445 }
446
447 return ability->GetRunningStatus();
448 }
449
StartOndemandSystemAbility(int32_t systemAbilityId)450 void LocalAbilityManager::StartOndemandSystemAbility(int32_t systemAbilityId)
451 {
452 pthread_setname_np(pthread_self(), ONDEMAND_WORKER.c_str());
453 HILOGD(TAG, "[PerformanceTest] SAFWK ondemand LoadSaLib systemAbilityId:%{public}d library", systemAbilityId);
454 int64_t begin = GetTickCount();
455 bool isExist = profileParser_->LoadSaLib(systemAbilityId);
456 HILOGI(TAG, "[PerformanceTest] SAFWK ondemand LoadSaLib systemAbilityId:%{public}d, spend:%{public}" PRId64 " ms",
457 systemAbilityId, (GetTickCount() - begin));
458 if (isExist) {
459 int32_t timeout = RETRY_TIMES_FOR_ONDEMAND;
460 constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_ONDEMAND_ONE_TIME).count();
461 {
462 std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
463 auto it = abilityMap_.find(systemAbilityId);
464 while (it == abilityMap_.end()) {
465 HILOGI(TAG, "waiting for SA:%{public}d...", systemAbilityId);
466 if (timeout > 0) {
467 usleep(duration);
468 it = abilityMap_.find(systemAbilityId);
469 } else {
470 HILOGE(TAG, "waiting for SA:%{public}d time out (1s)", systemAbilityId);
471 return;
472 }
473 timeout--;
474 }
475 }
476
477 if (!OnStartAbility(systemAbilityId)) {
478 HILOGE(TAG, "failed to start ability:%{public}d", systemAbilityId);
479 }
480 } else {
481 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
482 }
483 }
484
StartAbility(int32_t systemAbilityId,const std::string & eventStr)485 bool LocalAbilityManager::StartAbility(int32_t systemAbilityId, const std::string& eventStr)
486 {
487 HILOGI(TAG, "[PerformanceTest] SAFWK received start systemAbilityId:%{public}d request", systemAbilityId);
488 nlohmann::json startReason = ParseUtil::StringToJsonObj(eventStr);
489 SetStartReason(systemAbilityId, startReason);
490 auto task = std::bind(&LocalAbilityManager::StartOndemandSystemAbility, this, systemAbilityId);
491 std::thread thread(task);
492 thread.detach();
493 return true;
494 }
495
StopOndemandSystemAbility(int32_t systemAbilityId)496 void LocalAbilityManager::StopOndemandSystemAbility(int32_t systemAbilityId)
497 {
498 pthread_setname_np(pthread_self(), ONDEMAND_WORKER.c_str());
499 if (!OnStopAbility(systemAbilityId)) {
500 HILOGE(TAG, "failed to stop ability:%{public}d", systemAbilityId);
501 }
502 }
503
StopAbility(int32_t systemAbilityId,const std::string & eventStr)504 bool LocalAbilityManager::StopAbility(int32_t systemAbilityId, const std::string& eventStr)
505 {
506 HILOGI(TAG, "[PerformanceTest] SAFWK received stop systemAbilityId:%{public}d request", systemAbilityId);
507 nlohmann::json stopReason = ParseUtil::StringToJsonObj(eventStr);
508 SetStopReason(systemAbilityId, stopReason);
509 auto task = std::bind(&LocalAbilityManager::StopOndemandSystemAbility, this, systemAbilityId);
510 std::thread thread(task);
511 thread.detach();
512 return true;
513 }
514
ActiveAbility(int32_t systemAbilityId,const nlohmann::json & activeReason)515 bool LocalAbilityManager::ActiveAbility(int32_t systemAbilityId,
516 const nlohmann::json& activeReason)
517 {
518 HILOGD(TAG, "active SA:%{public}d", systemAbilityId);
519 auto ability = GetAbility(systemAbilityId);
520 if (ability == nullptr) {
521 return false;
522 }
523 SystemAbilityOnDemandReason onDemandActiveReason = JsonToOnDemandReason(activeReason);
524 ability->Active(onDemandActiveReason);
525 return true;
526 }
527
IdleAbility(int32_t systemAbilityId,const nlohmann::json & idleReason,int32_t & delayTime)528 bool LocalAbilityManager::IdleAbility(int32_t systemAbilityId,
529 const nlohmann::json& idleReason, int32_t& delayTime)
530 {
531 HILOGD(TAG, "idle SA:%{public}d", systemAbilityId);
532 auto ability = GetAbility(systemAbilityId);
533 if (ability == nullptr) {
534 return false;
535 }
536 SystemAbilityOnDemandReason onDemandIdleReason = JsonToOnDemandReason(idleReason);
537 ability->Idle(onDemandIdleReason, delayTime);
538 return true;
539 }
540
JsonToOnDemandReason(const nlohmann::json & reasonJson)541 SystemAbilityOnDemandReason LocalAbilityManager::JsonToOnDemandReason(const nlohmann::json& reasonJson)
542 {
543 SystemAbilityOnDemandReason onDemandStartReason;
544 if (reasonJson.contains(EVENT_ID) && reasonJson[EVENT_ID].is_number()) {
545 onDemandStartReason.SetId(reasonJson[EVENT_ID]);
546 }
547 if (reasonJson.contains(NAME) && reasonJson[NAME].is_string()) {
548 onDemandStartReason.SetName(reasonJson[NAME]);
549 }
550 if (reasonJson.contains(VALUE) && reasonJson[VALUE].is_string()) {
551 onDemandStartReason.SetValue(reasonJson[VALUE]);
552 }
553 if (reasonJson.contains(EXTRA_DATA_ID) && reasonJson[EXTRA_DATA_ID].is_number()) {
554 onDemandStartReason.SetExtraDataId(reasonJson[EXTRA_DATA_ID]);
555 }
556 return onDemandStartReason;
557 }
558
InitializeOnDemandSaProfile(int32_t saId)559 bool LocalAbilityManager::InitializeOnDemandSaProfile(int32_t saId)
560 {
561 int64_t begin = GetTickCount();
562 HILOGD(TAG, "[PerformanceTest] SAFWK LoadSaLib systemAbilityId:%{public}d", saId);
563 bool result = profileParser_->LoadSaLib(saId);
564 HILOGI(TAG, "[PerformanceTest] SAFWK LoadSaLib systemAbilityId:%{public}d finished, spend:%{public}"
565 PRId64 " ms", saId, (GetTickCount() - begin));
566 if (!result) {
567 HILOGW(TAG, "[PerformanceTest] LoadSaLib failed, Said:{public}%d", saId);
568 return false;
569 }
570 SaProfile saProfile;
571 bool ret = profileParser_->GetProfile(saId, saProfile);
572 if (ret) {
573 return InitializeSaProfilesInnerLocked(saProfile);
574 }
575 return false;
576 }
577
InitializeSaProfilesInnerLocked(const SaProfile & saProfile)578 bool LocalAbilityManager::InitializeSaProfilesInnerLocked(const SaProfile& saProfile)
579 {
580 std::unique_lock<std::shared_mutex> readLock(abilityMapLock_);
581 auto iterProfile = abilityMap_.find(saProfile.saId);
582 if (iterProfile == abilityMap_.end()) {
583 HILOGW(TAG, "SA:%{public}d not found", saProfile.saId);
584 return false;
585 }
586 auto systemAbility = iterProfile->second;
587 if (systemAbility == nullptr) {
588 HILOGW(TAG, "SA:%{public}d is null", saProfile.saId);
589 return false;
590 }
591 auto& saList = abilityPhaseMap_[saProfile.bootPhase];
592 saList.emplace_back(systemAbility);
593 return true;
594 }
595
CheckDependencyStatus(const vector<int32_t> & dependSa)596 vector<int32_t> LocalAbilityManager::CheckDependencyStatus(const vector<int32_t>& dependSa)
597 {
598 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
599 if (samgrProxy == nullptr) {
600 HILOGW(TAG, "failed to get samgrProxy");
601 return dependSa;
602 }
603
604 vector<int32_t> checkSaStatusResult;
605 for (const auto& saId : dependSa) {
606 if (CheckInputSysAbilityId(saId)) {
607 sptr<IRemoteObject> saObject = samgrProxy->CheckSystemAbility(saId);
608 if (saObject == nullptr) {
609 checkSaStatusResult.emplace_back(saId);
610 }
611 } else {
612 HILOGW(TAG, "dependency's id:%{public}d is invalid", saId);
613 }
614 }
615 return checkSaStatusResult;
616 }
617
StartDependSaTask(SystemAbility * ability)618 void LocalAbilityManager::StartDependSaTask(SystemAbility* ability)
619 {
620 if (ability == nullptr) {
621 HILOGE(TAG, "ability is null");
622 return;
623 }
624 int64_t start = GetTickCount();
625 int64_t dependTimeout = ability->GetDependTimeout();
626 while (!CheckDependencyStatus(ability->GetDependSa()).empty()) {
627 int64_t end = GetTickCount();
628 int64_t duration = ((end >= start) ? (end - start) : (INT64_MAX - end + start));
629 if (duration < dependTimeout) {
630 usleep(CHECK_DEPENDENT_SA_PERIOD);
631 } else {
632 break;
633 }
634 }
635 vector<int32_t> unpreparedDeps = CheckDependencyStatus(ability->GetDependSa());
636 if (unpreparedDeps.empty()) {
637 ability->Start();
638 } else {
639 for (const auto& unpreparedDep : unpreparedDeps) {
640 HILOGI(TAG, "%{public}d's dependency:%{public}d not started in %{public}d ms",
641 ability->GetSystemAbilitId(), unpreparedDep, ability->GetDependTimeout());
642 }
643 }
644 }
645
StartSystemAbilityTask(SystemAbility * ability)646 void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
647 {
648 if (ability != nullptr) {
649 HILOGD(TAG, "StartSystemAbility is called for %{public}d", ability->GetSystemAbilitId());
650 if (ability->GetDependSa().empty()) {
651 ability->Start();
652 } else {
653 StartDependSaTask(ability);
654 }
655 HILOGI(TAG, "%{public}s SA : %{public}d init finished, %{public}" PRId64 " ms",
656 Str16ToStr8(procName_).c_str(), ability->GetSystemAbilitId(), (GetTickCount() - startBegin_));
657 }
658
659 std::lock_guard<std::mutex> lock(startPhaseLock_);
660 if (startTaskNum_ > 0) {
661 --startTaskNum_;
662 }
663 startPhaseCV_.notify_one();
664 }
665
RegisterOnDemandSystemAbility(int32_t saId)666 void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId)
667 {
668 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
669 if (samgrProxy == nullptr) {
670 HILOGI(TAG, "failed to get samgrProxy");
671 return;
672 }
673
674 auto& saProfileList = profileParser_->GetAllSaProfiles();
675 for (const auto& saProfile : saProfileList) {
676 if (NeedRegisterOnDemand(saProfile, saId)) {
677 HILOGD(TAG, "register ondemand ability:%{public}d to samgr", saProfile.saId);
678 int32_t ret = samgrProxy->AddOnDemandSystemAbilityInfo(saProfile.saId, procName_);
679 if (ret != ERR_OK) {
680 HILOGI(TAG, "failed to add ability info for on-demand SA:%{public}d", saProfile.saId);
681 }
682 }
683 }
684 }
685
686 // on default load, not-run-on-create SA will register to OnDemandSystemAbility
687 // on demand load, other SA will register to OnDemandSystemAbility, although some are runOnCreate
NeedRegisterOnDemand(const SaProfile & saProfile,int32_t saId)688 bool LocalAbilityManager::NeedRegisterOnDemand(const SaProfile& saProfile, int32_t saId)
689 {
690 return (saId == DEFAULT_SAID && !saProfile.runOnCreate) ||
691 (saId != DEFAULT_SAID && saProfile.saId != saId);
692 }
693
StartPhaseTasks(const std::list<SystemAbility * > & systemAbilityList)694 void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
695 {
696 if (systemAbilityList.empty()) {
697 return;
698 }
699
700 for (auto systemAbility : systemAbilityList) {
701 if (systemAbility != nullptr) {
702 HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
703 std::lock_guard<std::mutex> autoLock(startPhaseLock_);
704 ++startTaskNum_;
705 auto task = std::bind(&LocalAbilityManager::StartSystemAbilityTask, this, systemAbility);
706 initPool_->AddTask(task);
707 }
708 }
709 }
710
WaitForTasks()711 void LocalAbilityManager::WaitForTasks()
712 {
713 int64_t begin = GetTickCount();
714 HILOGD(TAG, "start waiting for all tasks!");
715 std::unique_lock<std::mutex> lck(startPhaseLock_);
716 if (!startPhaseCV_.wait_for(lck, std::chrono::seconds(MAX_SA_STARTUP_TIME),
717 [this] () { return startTaskNum_ == 0; })) {
718 HILOGW(TAG, "start timeout!");
719 }
720 startTaskNum_ = 0;
721 int64_t end = GetTickCount();
722 HILOGI(TAG, "start tasks finished and spend %{public}" PRId64 " ms", (end - begin));
723 }
724
FindAndStartPhaseTasks(int32_t saId)725 void LocalAbilityManager::FindAndStartPhaseTasks(int32_t saId)
726 {
727 if (saId == DEFAULT_SAID) {
728 for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
729 auto iter = abilityPhaseMap_.find(bootPhase);
730 if (iter != abilityPhaseMap_.end()) {
731 StartPhaseTasks(iter->second);
732 InitializeRunOnCreateSaProfiles(bootPhase + 1);
733 WaitForTasks();
734 } else {
735 InitializeRunOnCreateSaProfiles(bootPhase + 1);
736 }
737 }
738 } else {
739 for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
740 auto iter = abilityPhaseMap_.find(bootPhase);
741 if (iter != abilityPhaseMap_.end()) {
742 StartPhaseTasks(iter->second);
743 WaitForTasks();
744 }
745 }
746 }
747 }
748
InitializeRunOnCreateSaProfiles(uint32_t bootPhase)749 bool LocalAbilityManager::InitializeRunOnCreateSaProfiles(uint32_t bootPhase)
750 {
751 if (bootPhase > OTHER_START) {
752 return false;
753 }
754 int64_t begin = GetTickCount();
755 HILOGD(TAG, "[PerformanceTest] SAFWK load phase %{public}d libraries", bootPhase);
756 profileParser_->OpenSo(bootPhase);
757 HILOGI(TAG, "[PerformanceTest] SAFWK load phase %{public}d libraries finished, spend:%{public}" PRId64 " ms",
758 bootPhase, (GetTickCount() - begin));
759 auto& saProfileList = profileParser_->GetAllSaProfiles();
760 if (saProfileList.empty()) {
761 HILOGW(TAG, "sa profile is empty");
762 return false;
763 }
764 for (const auto& saProfile : saProfileList) {
765 if (saProfile.bootPhase != bootPhase) {
766 continue;
767 }
768 if (!InitializeSaProfilesInnerLocked(saProfile)) {
769 HILOGW(TAG, "SA:%{public}d init fail", saProfile.saId);
770 continue;
771 }
772 }
773 return true;
774 }
775
Run(int32_t saId)776 bool LocalAbilityManager::Run(int32_t saId)
777 {
778 HILOGD(TAG, "local ability manager is running...");
779 bool addResult = AddLocalAbilityManager();
780 if (!addResult) {
781 HILOGE(TAG, "failed to add local abilitymanager");
782 return false;
783 }
784 HILOGD(TAG, "success to add process name:%{public}s", Str16ToStr8(procName_).c_str());
785 uint32_t concurrentThreads = std::thread::hardware_concurrency();
786 HILOGI(TAG, "concurrentThreads is %{public}d", concurrentThreads);
787 initPool_->Start(concurrentThreads);
788 initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
789
790 RegisterOnDemandSystemAbility(saId);
791 FindAndStartPhaseTasks(saId);
792 initPool_->Stop();
793 return true;
794 }
795
AddLocalAbilityManager()796 bool LocalAbilityManager::AddLocalAbilityManager()
797 {
798 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
799 if (samgrProxy == nullptr) {
800 HILOGE(TAG, "failed to get samgrProxy");
801 return false;
802 }
803
804 if (localAbilityManager_ == nullptr) {
805 localAbilityManager_ = this;
806 }
807 int32_t ret = samgrProxy->AddSystemProcess(procName_, localAbilityManager_);
808 return ret == ERR_OK;
809 }
810
SetStartReason(int32_t saId,const nlohmann::json & event)811 void LocalAbilityManager::SetStartReason(int32_t saId, const nlohmann::json& event)
812 {
813 std::lock_guard<std::mutex> autoLock(ReasonLock_);
814 saIdToStartReason_[saId] = event;
815 }
816
SetStopReason(int32_t saId,const nlohmann::json & event)817 void LocalAbilityManager::SetStopReason(int32_t saId, const nlohmann::json& event)
818 {
819 std::lock_guard<std::mutex> autoLock(ReasonLock_);
820 saIdToStopReason_[saId] = event;
821 }
822
GetStartReason(int32_t saId)823 nlohmann::json& LocalAbilityManager::GetStartReason(int32_t saId)
824 {
825 std::lock_guard<std::mutex> autoLock(ReasonLock_);
826 return saIdToStartReason_[saId];
827 }
828
GetStopReason(int32_t saId)829 nlohmann::json& LocalAbilityManager::GetStopReason(int32_t saId)
830 {
831 std::lock_guard<std::mutex> autoLock(ReasonLock_);
832 return saIdToStopReason_[saId];
833 }
834
GetSystemAbilityStatusChange()835 sptr<ISystemAbilityStatusChange> LocalAbilityManager::GetSystemAbilityStatusChange()
836 {
837 std::lock_guard<std::mutex> autoLock(listenerLock_);
838 if (statusChangeListener_ == nullptr) {
839 statusChangeListener_ = new SystemAbilityListener();
840 }
841 return statusChangeListener_;
842 }
843
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)844 void LocalAbilityManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
845 const std::string& deviceId)
846 {
847 HILOGD(TAG, "SA:%{public}d added", systemAbilityId);
848 if (!CheckInputSysAbilityId(systemAbilityId)) {
849 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
850 return;
851 }
852
853 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
854 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
855 }
856
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)857 void LocalAbilityManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
858 const std::string& deviceId)
859 {
860 HILOGD(TAG, "SA:%{public}d removed", systemAbilityId);
861 if (!CheckInputSysAbilityId(systemAbilityId)) {
862 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
863 return;
864 }
865
866 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
867 ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY);
868 }
869 }
870