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