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