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