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 #include <csignal>
25 #include <sys/time.h>
26 #include <securec.h>
27
28 #include "datetime_ex.h"
29 #include "errors.h"
30 #include "hitrace_meter.h"
31 #include "ipc_skeleton.h"
32 #include "iservice_registry.h"
33 #include "safwk_log.h"
34 #include "file_ex.h"
35 #include "string_ex.h"
36 #include "hisysevent_adapter.h"
37 #include "system_ability_ondemand_reason.h"
38 #include "local_ability_manager_dumper.h"
39 #include "timer.h"
40 #include "hisysevent_adapter.h"
41 #include "system_ability_definition.h"
42 #include "samgr_xcollie.h"
43 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
44 #include <sys/syscall.h>
45 #include <sys/resource.h>
46 #endif
47
48 namespace OHOS {
49 using std::u16string;
50 using std::string;
51 using std::vector;
52
53 namespace {
54 constexpr int32_t RETRY_TIMES_FOR_ONDEMAND = 10;
55 constexpr int32_t RETRY_TIMES_FOR_SAMGR = 50;
56 constexpr int32_t DEFAULT_SAID = -1;
57 constexpr int32_t IDLE_SA_REPORT_SIGNUM = 60;
58 constexpr int32_t UNUSED_RESIDENT_TIMER_INTERVAL_SECONDS = 60 * 60;
59 constexpr int32_t UNUSED_ONDEMAND_TIMER_INTERVAL_MSECONDS = 1000 * 60 * 1;
60 constexpr int32_t ONDEMAND_SA_UNUSED_TIMEOUT_LOWLIMIT = UNUSED_ONDEMAND_TIMER_INTERVAL_MSECONDS;
61 constexpr int32_t ONDEMAND_SA_UNUSED_TIMEOUT_UPLIMIT = 1000 * 60 * 120;
62 constexpr int32_t RESIDENT_SA_UNUSED_TIMEOUT = 1000 * 60 * 60;
63 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_SAMGR_ONE_TIME(200);
64 constexpr std::chrono::milliseconds MILLISECONDS_WAITING_ONDEMAND_ONE_TIME(100);
65 constexpr int32_t TIME_S_TO_MS = 1000;
66 constexpr int32_t MAX_STARTSA_TIMEOUT = 65;
67 constexpr int32_t MAX_CHECK_TIMEOUT = 10;
68
69 constexpr int32_t MAX_SA_STARTUP_TIME = 100;
70 constexpr int32_t SUFFIX_LENGTH = 5; // .json length
71 constexpr uint32_t FFRT_DUMP_INFO_ALL = 0;
72 constexpr int FFRT_BUFFER_SIZE = 512 * 1024;
73
74 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
75 constexpr int OPEN_SO_PRIO = -20;
76 constexpr int NORMAL_PRIO = 0;
77 #endif
78
79 constexpr const char* PROFILES_DIR = "/system/profile/";
80 constexpr const char* PREFIX = PROFILES_DIR;
81 constexpr const char* SUFFIX = "_trust.json";
82
83 constexpr const char* ONDEMAND_WORKER = "SaOndemand";
84 constexpr const char* INIT_POOL = "SaInit";
85
86 constexpr const char* EVENT_ID = "eventId";
87 constexpr const char* NAME = "name";
88 constexpr const char* VALUE = "value";
89 constexpr const char* EXTRA_DATA_ID = "extraDataId";
90
91 enum {
92 BOOT_START = 1,
93 CORE_START = 2,
94 OTHER_START = 3,
95 };
96 }
97
98 IMPLEMENT_SINGLE_INSTANCE(LocalAbilityManager);
99
100 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
SetThreadPrio(int priority)101 static void SetThreadPrio(int priority)
102 {
103 int tid = syscall(SYS_gettid);
104 LOGI("set tid:%{public}d priority:%{public}d.", tid, priority);
105 if (setpriority(PRIO_PROCESS, tid, priority) != 0) {
106 LOGE("set tid:%{public}d priority:%{public}d failed.", tid, priority);
107 }
108 }
109 #endif
110
LocalAbilityManager()111 LocalAbilityManager::LocalAbilityManager()
112 {
113 profileParser_ = std::make_shared<ParseUtil>();
114 initPool_ = std::make_unique<ThreadPool>(INIT_POOL);
115 }
116
~LocalAbilityManager()117 LocalAbilityManager::~LocalAbilityManager()
118 {
119 StopTimedQuery();
120 }
121
DoStartSAProcess(const std::string & profilePath,int32_t saId)122 void LocalAbilityManager::DoStartSAProcess(const std::string& profilePath, int32_t saId)
123 {
124 startBegin_ = GetTickCount();
125 HILOGD(TAG, "SA:%{public}d", saId);
126 string realProfilePath = "";
127 if (!CheckAndGetProfilePath(profilePath, realProfilePath)) {
128 ReportSaMainExit("DoStartSAProcess invalid path");
129 HILOGE(TAG, "DoStartSAProcess invalid path");
130 return;
131 }
132 {
133 std::string traceTag = GetTraceTag(realProfilePath);
134 HitraceScopedEx samgrHitrace(HITRACE_LEVEL_INFO, HITRACE_TAG_SAMGR, traceTag.c_str());
135 bool ret = InitSystemAbilityProfiles(realProfilePath, saId);
136 if (!ret) {
137 ReportSaMainExit("InitSaProfiles no right profile");
138 HILOGE(TAG, "InitSystemAbilityProfiles no right profile, will exit");
139 return;
140 }
141 {
142 SamgrXCollie samgrXCollie("safwk--CheckSamgrReady", MAX_CHECK_TIMEOUT);
143 ret = CheckSystemAbilityManagerReady();
144 }
145 if (!ret) {
146 ReportSaMainExit("CheckSamgrReady failed");
147 HILOGE(TAG, "CheckSystemAbilityManagerReady failed! will exit");
148 return;
149 }
150 ret = Run(saId);
151 if (!ret) {
152 ReportSaMainExit("SA Run failed");
153 HILOGE(TAG, "Run failed! will exit");
154 return;
155 }
156 }
157
158 StartTimedQuery();
159 IPCSkeleton::JoinWorkThread();
160 HILOGE(TAG, "JoinWorkThread stop, will exit");
161 }
162
GetTraceTag(const std::string & profilePath)163 std::string LocalAbilityManager::GetTraceTag(const std::string& profilePath)
164 {
165 std::vector<std::string> libPathVec;
166 string traceTag = "default_proc";
167 SplitStr(profilePath, "/", libPathVec);
168 if ((libPathVec.size() > 0)) {
169 traceTag = libPathVec[libPathVec.size() - 1];
170 auto size = traceTag.length();
171 if (size > SUFFIX_LENGTH) {
172 return traceTag.substr(0, size - SUFFIX_LENGTH);
173 }
174 }
175 return traceTag;
176 }
177
CheckAndGetProfilePath(const std::string & profilePath,std::string & realProfilePath)178 bool LocalAbilityManager::CheckAndGetProfilePath(const std::string& profilePath, std::string& realProfilePath)
179 {
180 if (profilePath.length() > PATH_MAX) {
181 HILOGE(TAG, "profilePath length too long!");
182 return false;
183 }
184 char realPath[PATH_MAX] = {'\0'};
185 if (realpath(profilePath.c_str(), realPath) == nullptr) {
186 HILOGE(TAG, "file path does not exist!");
187 return false;
188 }
189 realProfilePath = realPath;
190 return true;
191 }
192
CheckSystemAbilityManagerReady()193 bool LocalAbilityManager::CheckSystemAbilityManagerReady()
194 {
195 int32_t timeout = RETRY_TIMES_FOR_SAMGR;
196 constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_SAMGR_ONE_TIME).count();
197 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
198 while (samgrProxy == nullptr) {
199 HILOGI(TAG, "%{public}s waiting for samgr...", Str16ToStr8(procName_).c_str());
200 if (timeout > 0) {
201 usleep(duration);
202 samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
203 } else {
204 HILOGE(TAG, "wait for samgr time out (10s)");
205 return false;
206 }
207 timeout--;
208 }
209 return true;
210 }
211
InitSystemAbilityProfiles(const std::string & profilePath,int32_t saId)212 bool LocalAbilityManager::InitSystemAbilityProfiles(const std::string& profilePath, int32_t saId)
213 {
214 LOGD("InitProfiles parse sa profiles!");
215 int64_t begin = GetTickCount();
216 bool ret = profileParser_->ParseSaProfiles(profilePath);
217 if (!ret) {
218 HILOGW(TAG, "ParseSaProfiles failed!");
219 return false;
220 }
221
222 procName_ = profileParser_->GetProcessName();
223 auto saInfos = profileParser_->GetAllSaProfiles();
224 std::string process = Str16ToStr8(procName_);
225 LOGI("InitProfiles proc:%{public}s end,spend:%{public}" PRId64 "ms", process.c_str(), (GetTickCount() - begin));
226 std::string path = PREFIX + process + SUFFIX;
227 bool isExist = profileParser_->CheckPathExist(path);
228 if (isExist) {
229 CheckTrustSa(path, process, saInfos);
230 }
231 return InitializeSaProfiles(saId);
232 }
233
InitializeSaProfiles(int32_t saId)234 bool LocalAbilityManager::InitializeSaProfiles(int32_t saId)
235 {
236 if (saId != DEFAULT_SAID) {
237 return InitializeOnDemandSaProfile(saId);
238 } else {
239 return InitializeRunOnCreateSaProfiles(BOOT_START);
240 }
241 }
242
CheckTrustSa(const std::string & path,const std::string & process,const std::list<SaProfile> & saInfos)243 void LocalAbilityManager::CheckTrustSa(const std::string& path, const std::string& process,
244 const std::list<SaProfile>& saInfos)
245 {
246 HILOGD(TAG, "CheckTrustSa start");
247 std::map<std::u16string, std::set<int32_t>> trustMaps;
248 bool ret = profileParser_->ParseTrustConfig(path, trustMaps);
249 if (ret && !trustMaps.empty()) {
250 // 1.get allowed sa set in the process
251 const auto& saSets = trustMaps[Str8ToStr16(process)];
252 // 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
253 for (const auto& saInfo : saInfos) {
254 if (saSets.find(saInfo.saId) == saSets.end()) {
255 HILOGW(TAG, "SA:%{public}d not allow to load in %{public}s", saInfo.saId, process.c_str());
256 profileParser_->RemoveSaProfile(saInfo.saId);
257 }
258 }
259 }
260 }
261
ClearResource()262 void LocalAbilityManager::ClearResource()
263 {
264 profileParser_->ClearResource();
265 }
266
AddAbility(SystemAbility * ability)267 bool LocalAbilityManager::AddAbility(SystemAbility* ability)
268 {
269 if (ability == nullptr) {
270 HILOGW(TAG, "try to add null ability!");
271 return false;
272 }
273
274 int32_t saId = ability->GetSystemAbilitId();
275 SaProfile saProfile;
276 bool ret = profileParser_->GetProfile(saId, saProfile);
277 if (!ret) {
278 return false;
279 }
280 std::unique_lock<std::shared_mutex> writeLock(localAbilityMapLock_);
281 auto iter = localAbilityMap_.find(saId);
282 if (iter != localAbilityMap_.end()) {
283 HILOGW(TAG, "try to add existed SA:%{public}d!", saId);
284 return false;
285 }
286 HILOGI(TAG, "set profile attr for SA:%{public}d", saId);
287 ability->SetLibPath(saProfile.libPath);
288 ability->SetRunOnCreate(saProfile.runOnCreate);
289 ability->SetDependSa(saProfile.dependSa);
290 ability->SetDependTimeout(saProfile.dependTimeout);
291 ability->SetDistributed(saProfile.distributed);
292 ability->SetDumpLevel(saProfile.dumpLevel);
293 ability->SetCapability(saProfile.capability);
294 ability->SetPermission(saProfile.permission);
295 localAbilityMap_.emplace(saId, ability);
296 return true;
297 }
298
RemoveAbility(int32_t systemAbilityId)299 bool LocalAbilityManager::RemoveAbility(int32_t systemAbilityId)
300 {
301 if (systemAbilityId <= 0) {
302 HILOGW(TAG, "invalid systemAbilityId");
303 return false;
304 }
305 std::unique_lock<std::shared_mutex> writeLock(localAbilityMapLock_);
306 (void)localAbilityMap_.erase(systemAbilityId);
307 return true;
308 }
309
AddSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)310 bool LocalAbilityManager::AddSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
311 {
312 if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
313 HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!", systemAbilityId, listenerSaId);
314 return false;
315 }
316 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
317 if (samgrProxy == nullptr) {
318 HILOGE(TAG, "failed to get samgrProxy");
319 return false;
320 }
321 bool isNeedNotify = false;
322 size_t listenerListSize = 0;
323 {
324 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
325 std::lock_guard<std::mutex> autoLock(listenerLock_);
326 auto& listenerList = localListenerMap_[systemAbilityId];
327 auto iter = std::find_if(listenerList.begin(), listenerList.end(),
328 [listenerSaId](const std::pair<int32_t, ListenerState>& listener) {
329 return listener.first == listenerSaId;
330 });
331 if (listenerList.size() > 0) {
332 sptr<IRemoteObject> object = samgrProxy->CheckSystemAbility(systemAbilityId);
333 if (object != nullptr) {
334 isNeedNotify = true;
335 }
336 }
337 if (iter == listenerList.end()) {
338 listenerList.push_back({listenerSaId,
339 (isNeedNotify) ? ListenerState::NOTIFIED : ListenerState::INIT});
340 }
341 listenerListSize = listenerList.size();
342 LOGI("AddSaListener SA:%{public}d,listenerSA:%{public}d,size:%{public}zu", systemAbilityId, listenerSaId,
343 listenerList.size());
344 }
345 if (listenerListSize > 1) {
346 if (isNeedNotify) {
347 NotifyAbilityListener(systemAbilityId, listenerSaId, "",
348 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
349 }
350 return true;
351 }
352 int32_t ret = samgrProxy->SubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
353 if (ret) {
354 HILOGE(TAG, "failed to subscribe SA:%{public}d, process name:%{public}s", systemAbilityId,
355 Str16ToStr8(procName_).c_str());
356 return false;
357 }
358 return true;
359 }
360
RemoveSystemAbilityListener(int32_t systemAbilityId,int32_t listenerSaId)361 bool LocalAbilityManager::RemoveSystemAbilityListener(int32_t systemAbilityId, int32_t listenerSaId)
362 {
363 if (!CheckInputSysAbilityId(systemAbilityId) || !CheckInputSysAbilityId(listenerSaId)) {
364 HILOGW(TAG, "SA:%{public}d or listenerSA:%{public}d invalid!",
365 systemAbilityId, listenerSaId);
366 return false;
367 }
368 {
369 HILOGD(TAG, "SA:%{public}d, listenerSA:%{public}d", systemAbilityId, listenerSaId);
370 std::lock_guard<std::mutex> autoLock(listenerLock_);
371 if (localListenerMap_.count(systemAbilityId) == 0) {
372 return true;
373 }
374 auto& listenerList = localListenerMap_[systemAbilityId];
375 auto iter = std::find_if(listenerList.begin(), listenerList.end(),
376 [listenerSaId](const std::pair<int32_t, ListenerState>& listener) {
377 return listener.first == listenerSaId;
378 });
379 if (iter != listenerList.end()) {
380 listenerList.erase(iter);
381 }
382 HILOGI(TAG, "SA:%{public}d, size:%{public}zu", systemAbilityId,
383 listenerList.size());
384 if (!listenerList.empty()) {
385 return true;
386 }
387 localListenerMap_.erase(systemAbilityId);
388 }
389
390 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
391 if (samgrProxy == nullptr) {
392 HILOGE(TAG, "failed to get samgrProxy");
393 return false;
394 }
395 int32_t ret = samgrProxy->UnSubscribeSystemAbility(systemAbilityId, GetSystemAbilityStatusChange());
396 if (ret) {
397 HILOGE(TAG, "failed to unsubscribe SA:%{public}d, process name:%{public}s",
398 systemAbilityId, Str16ToStr8(procName_).c_str());
399 return false;
400 }
401 return true;
402 }
403
NotifyAbilityListener(int32_t systemAbilityId,int32_t listenerSaId,const std::string & deviceId,int32_t code)404 void LocalAbilityManager::NotifyAbilityListener(int32_t systemAbilityId, int32_t listenerSaId,
405 const std::string& deviceId, int32_t code)
406 {
407 LOGI("NotifyListener SA:%{public}d,listenerSA:%{public}d,code:%{public}d", systemAbilityId, listenerSaId, code);
408 auto ability = GetAbility(listenerSaId);
409 if (ability == nullptr) {
410 HILOGE(TAG, "failed to get listener SA:%{public}d", listenerSaId);
411 return;
412 }
413
414 switch (code) {
415 case ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY: {
416 HILOGD(TAG, "OnAddSystemAbility, SA:%{public}d", listenerSaId);
417 ability->OnAddSystemAbility(systemAbilityId, deviceId);
418 break;
419 }
420 case ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY: {
421 HILOGD(TAG, "OnRemoveSystemAbility, SA:%{public}d", listenerSaId);
422 ability->OnRemoveSystemAbility(systemAbilityId, deviceId);
423 break;
424 }
425 default:
426 break;
427 }
428 }
429
FindAndNotifyAbilityListeners(int32_t systemAbilityId,const std::string & deviceId,int32_t code)430 void LocalAbilityManager::FindAndNotifyAbilityListeners(int32_t systemAbilityId,
431 const std::string& deviceId, int32_t code)
432 {
433 HILOGD(TAG, "SA:%{public}d, code:%{public}d", systemAbilityId, code);
434 int64_t begin = GetTickCount();
435 std::vector<int32_t> listenerSaIdVec;
436 {
437 std::lock_guard<std::mutex> autoLock(listenerLock_);
438 auto iter = localListenerMap_.find(systemAbilityId);
439 if (iter == localListenerMap_.end()) {
440 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
441 return;
442 }
443 if (code == ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY) {
444 for (auto& listener : iter->second) {
445 if (listener.second == ListenerState::INIT) {
446 listenerSaIdVec.push_back(listener.first);
447 listener.second = ListenerState::NOTIFIED;
448 } else {
449 HILOGW(TAG, "listener SA:%{public}d has been notified add", listener.first);
450 }
451 }
452 } else if (code == ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY) {
453 for (auto& listener : iter->second) {
454 listenerSaIdVec.push_back(listener.first);
455 if (listener.second == ListenerState::NOTIFIED) {
456 listener.second = ListenerState::INIT;
457 }
458 }
459 }
460 }
461 for (auto listenerSaId : listenerSaIdVec) {
462 NotifyAbilityListener(systemAbilityId, listenerSaId, deviceId, code);
463 }
464 LOGI("FindNotifyListeners SA:%{public}d,size:%{public}zu,code:%{public}d,spend:%{public}" PRId64 "ms",
465 systemAbilityId, listenerSaIdVec.size(), code, GetTickCount() - begin);
466 }
467
OnStartAbility(int32_t systemAbilityId)468 bool LocalAbilityManager::OnStartAbility(int32_t systemAbilityId)
469 {
470 HILOGD(TAG, "try to start SA:%{public}d", systemAbilityId);
471 auto ability = GetAbility(systemAbilityId);
472 if (ability == nullptr) {
473 return false;
474 }
475 ability->Start();
476 return true;
477 }
478
OnStopAbility(int32_t systemAbilityId)479 bool LocalAbilityManager::OnStopAbility(int32_t systemAbilityId)
480 {
481 HILOGD(TAG, "try to stop SA:%{public}d", systemAbilityId);
482 auto ability = GetAbility(systemAbilityId);
483 if (ability == nullptr) {
484 return false;
485 }
486 ability->Stop();
487 return true;
488 }
489
GetAbility(int32_t systemAbilityId)490 SystemAbility* LocalAbilityManager::GetAbility(int32_t systemAbilityId)
491 {
492 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
493 auto it = localAbilityMap_.find(systemAbilityId);
494 if (it == localAbilityMap_.end()) {
495 HILOGW(TAG, "SA:%{public}d not register", systemAbilityId);
496 return nullptr;
497 }
498
499 return it->second;
500 }
501
GetRunningStatus(int32_t systemAbilityId)502 bool LocalAbilityManager::GetRunningStatus(int32_t systemAbilityId)
503 {
504 auto ability = GetAbility(systemAbilityId);
505 if (ability == nullptr) {
506 return false;
507 }
508
509 return ability->GetRunningStatus();
510 }
511
StartOndemandSystemAbility(int32_t systemAbilityId)512 void LocalAbilityManager::StartOndemandSystemAbility(int32_t systemAbilityId)
513 {
514 pthread_setname_np(pthread_self(), ONDEMAND_WORKER);
515 LOGD("StartOndemandSa LoadSaLib SA:%{public}d library", systemAbilityId);
516 int64_t begin = GetTickCount();
517 bool isExist = profileParser_->LoadSaLib(systemAbilityId);
518 LOGI("StartOndemandSa LoadSaLib SA:%{public}d,spend:%{public}" PRId64 "ms",
519 systemAbilityId, (GetTickCount() - begin));
520 if (isExist) {
521 int32_t timeout = RETRY_TIMES_FOR_ONDEMAND;
522 constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_ONDEMAND_ONE_TIME).count();
523 {
524 auto it = localAbilityMap_.begin();
525 {
526 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
527 it = localAbilityMap_.find(systemAbilityId);
528 }
529 while (it == localAbilityMap_.end()) {
530 HILOGI(TAG, "waiting for SA:%{public}d...", systemAbilityId);
531 if (timeout > 0) {
532 usleep(duration);
533 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
534 it = localAbilityMap_.find(systemAbilityId);
535 } else {
536 HILOGE(TAG, "waiting for SA:%{public}d time out (1s)", systemAbilityId);
537 return;
538 }
539 timeout--;
540 }
541 }
542
543 if (!OnStartAbility(systemAbilityId)) {
544 HILOGE(TAG, "failed to start SA:%{public}d", systemAbilityId);
545 }
546 } else {
547 HILOGW(TAG, "SA:%{public}d not found", systemAbilityId);
548 }
549 }
550
StartAbility(int32_t systemAbilityId,const std::string & eventStr)551 bool LocalAbilityManager::StartAbility(int32_t systemAbilityId, const std::string& eventStr)
552 {
553 LOGI("StartSa recv start SA:%{public}d req", systemAbilityId);
554 nlohmann::json startReason = ParseUtil::StringToJsonObj(eventStr);
555 SetStartReason(systemAbilityId, startReason);
556 auto task = [this, systemAbilityId] {this->StartOndemandSystemAbility(systemAbilityId);};
557 std::thread thread(task);
558 thread.detach();
559 return true;
560 }
561
StopOndemandSystemAbility(int32_t systemAbilityId)562 void LocalAbilityManager::StopOndemandSystemAbility(int32_t systemAbilityId)
563 {
564 pthread_setname_np(pthread_self(), ONDEMAND_WORKER);
565 if (!OnStopAbility(systemAbilityId)) {
566 HILOGE(TAG, "failed to stop SA:%{public}d", systemAbilityId);
567 }
568 }
569
StopAbility(int32_t systemAbilityId,const std::string & eventStr)570 bool LocalAbilityManager::StopAbility(int32_t systemAbilityId, const std::string& eventStr)
571 {
572 LOGI("StopSa recv stop SA:%{public}d req", systemAbilityId);
573 nlohmann::json stopReason = ParseUtil::StringToJsonObj(eventStr);
574 SetStopReason(systemAbilityId, stopReason);
575 auto task = [this, systemAbilityId] {this->StopOndemandSystemAbility(systemAbilityId);};
576 std::thread thread(task);
577 thread.detach();
578 return true;
579 }
580
ActiveAbility(int32_t systemAbilityId,const nlohmann::json & activeReason)581 bool LocalAbilityManager::ActiveAbility(int32_t systemAbilityId,
582 const nlohmann::json& activeReason)
583 {
584 LOGD("ActiveSa:%{public}d", systemAbilityId);
585 auto ability = GetAbility(systemAbilityId);
586 if (ability == nullptr) {
587 return false;
588 }
589 SystemAbilityOnDemandReason onDemandActiveReason = JsonToOnDemandReason(activeReason);
590 ability->Active(onDemandActiveReason);
591 return true;
592 }
593
IdleAbility(int32_t systemAbilityId,const nlohmann::json & idleReason,int32_t & delayTime)594 bool LocalAbilityManager::IdleAbility(int32_t systemAbilityId,
595 const nlohmann::json& idleReason, int32_t& delayTime)
596 {
597 HILOGD(TAG, "idle SA:%{public}d", systemAbilityId);
598 auto ability = GetAbility(systemAbilityId);
599 if (ability == nullptr) {
600 return false;
601 }
602 SystemAbilityOnDemandReason onDemandIdleReason = JsonToOnDemandReason(idleReason);
603 ability->Idle(onDemandIdleReason, delayTime);
604 return true;
605 }
606
JsonToOnDemandReason(const nlohmann::json & reasonJson)607 SystemAbilityOnDemandReason LocalAbilityManager::JsonToOnDemandReason(const nlohmann::json& reasonJson)
608 {
609 SystemAbilityOnDemandReason onDemandStartReason;
610 if (reasonJson.contains(EVENT_ID) && reasonJson[EVENT_ID].is_number()) {
611 onDemandStartReason.SetId(reasonJson[EVENT_ID]);
612 }
613 if (reasonJson.contains(NAME) && reasonJson[NAME].is_string()) {
614 onDemandStartReason.SetName(reasonJson[NAME]);
615 }
616 if (reasonJson.contains(VALUE) && reasonJson[VALUE].is_string()) {
617 onDemandStartReason.SetValue(reasonJson[VALUE]);
618 }
619 if (reasonJson.contains(EXTRA_DATA_ID) && reasonJson[EXTRA_DATA_ID].is_number()) {
620 onDemandStartReason.SetExtraDataId(reasonJson[EXTRA_DATA_ID]);
621 }
622 return onDemandStartReason;
623 }
624
InitializeOnDemandSaProfile(int32_t saId)625 bool LocalAbilityManager::InitializeOnDemandSaProfile(int32_t saId)
626 {
627 int64_t begin = GetTickCount();
628 LOGD("InitOnDemandSa LoadSaLib SA:%{public}d", saId);
629 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
630 SetThreadPrio(OPEN_SO_PRIO);
631 #endif
632 bool result = profileParser_->LoadSaLib(saId);
633 #ifdef SAFWK_ENABLE_RUN_ON_DEMAND_QOS
634 SetThreadPrio(NORMAL_PRIO);
635 #endif
636 LOGI("InitOnDemandSa LoadSaLib SA:%{public}d finished,spend:%{public}"
637 PRId64 "ms", saId, (GetTickCount() - begin));
638 if (!result) {
639 LOGW("InitOnDemandSa LoadSaLib fail,SA:{public}%d", saId);
640 return false;
641 }
642 SaProfile saProfile;
643 bool ret = profileParser_->GetProfile(saId, saProfile);
644 if (ret) {
645 return InitializeSaProfilesInnerLocked(saProfile);
646 }
647 return false;
648 }
649
InitializeSaProfilesInnerLocked(const SaProfile & saProfile)650 bool LocalAbilityManager::InitializeSaProfilesInnerLocked(const SaProfile& saProfile)
651 {
652 std::unique_lock<std::shared_mutex> readLock(localAbilityMapLock_);
653 auto iterProfile = localAbilityMap_.find(saProfile.saId);
654 if (iterProfile == localAbilityMap_.end()) {
655 HILOGW(TAG, "SA:%{public}d not found", saProfile.saId);
656 return false;
657 }
658 auto systemAbility = iterProfile->second;
659 if (systemAbility == nullptr) {
660 HILOGW(TAG, "SA:%{public}d is null", saProfile.saId);
661 return false;
662 }
663 if (saProfile.bootPhase > OTHER_START) {
664 HILOGW(TAG, "invalid boot phase: %{public}d", saProfile.bootPhase);
665 return false;
666 }
667 auto& saList = abilityPhaseMap_[saProfile.bootPhase];
668 saList.emplace_back(systemAbility);
669 return true;
670 }
671
CheckDependencyStatus(const vector<int32_t> & dependSa)672 vector<int32_t> LocalAbilityManager::CheckDependencyStatus(const vector<int32_t>& dependSa)
673 {
674 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
675 if (samgrProxy == nullptr) {
676 HILOGW(TAG, "failed to get samgrProxy");
677 return dependSa;
678 }
679
680 vector<int32_t> checkSaStatusResult;
681 for (const auto& saId : dependSa) {
682 if (CheckInputSysAbilityId(saId)) {
683 sptr<IRemoteObject> saObject = samgrProxy->CheckSystemAbility(saId);
684 if (saObject == nullptr) {
685 checkSaStatusResult.emplace_back(saId);
686 }
687 } else {
688 HILOGW(TAG, "dependency's SA:%{public}d is invalid", saId);
689 }
690 }
691 return checkSaStatusResult;
692 }
693
StartDependSaTask(SystemAbility * ability)694 void LocalAbilityManager::StartDependSaTask(SystemAbility* ability)
695 {
696 if (ability == nullptr) {
697 HILOGE(TAG, "ability is null");
698 return;
699 }
700 int64_t start = GetTickCount();
701 int64_t dependTimeout = ability->GetDependTimeout();
702 size_t lastSize = CheckDependencyStatus(ability->GetDependSa()).size();
703 HILOGI(TAG, "SA:%{public}d's depend timeout:%{public}" PRId64 " ms,depend size:%{public}zu",
704 ability->GetSystemAbilitId(), dependTimeout, lastSize);
705 while (lastSize > 0) {
706 int64_t end = GetTickCount();
707 int64_t duration = ((end >= start) ? (end - start) : (INT64_MAX - end + start));
708 if (duration < dependTimeout) {
709 usleep(CHECK_DEPENDENT_SA_PERIOD);
710 } else {
711 break;
712 }
713 vector<int32_t> temp = CheckDependencyStatus(ability->GetDependSa());
714 size_t curSize = temp.size();
715 if (curSize != lastSize) {
716 HILOGI(TAG, "SA:%{public}d's depend left:%{public}zu", ability->GetSystemAbilitId(), curSize);
717 }
718 lastSize = curSize;
719 }
720 vector<int32_t> unpreparedDeps = CheckDependencyStatus(ability->GetDependSa());
721 if (unpreparedDeps.empty()) {
722 HILOGI(TAG, "SA:%{public}d's depend all start", ability->GetSystemAbilitId());
723 ability->Start();
724 } else {
725 for (const auto& unpreparedDep : unpreparedDeps) {
726 HILOGI(TAG, "%{public}d's dependency:%{public}d not started in %{public}d ms",
727 ability->GetSystemAbilitId(), unpreparedDep, ability->GetDependTimeout());
728 }
729 }
730 }
731
StartSystemAbilityTask(SystemAbility * ability)732 void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
733 {
734 if (ability != nullptr) {
735 SamgrXCollie samgrXCollie("StartSaTimeout_" + ToString(ability->GetSystemAbilitId()), MAX_STARTSA_TIMEOUT);
736 HILOGD(TAG, "StartSystemAbility is called for SA:%{public}d", ability->GetSystemAbilitId());
737 if (ability->GetDependSa().empty()) {
738 ability->Start();
739 } else {
740 StartDependSaTask(ability);
741 }
742 KHILOGI(TAG, "%{public}s SA:%{public}d init finished, %{public}" PRId64 " ms",
743 Str16ToStr8(procName_).c_str(), ability->GetSystemAbilitId(), (GetTickCount() - startBegin_));
744 }
745
746 std::lock_guard<std::mutex> lock(startPhaseLock_);
747 if (startTaskNum_ > 0) {
748 --startTaskNum_;
749 }
750 startPhaseCV_.notify_one();
751 }
752
RegisterOnDemandSystemAbility(int32_t saId)753 void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId)
754 {
755 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
756 if (samgrProxy == nullptr) {
757 HILOGI(TAG, "failed to get samgrProxy");
758 return;
759 }
760
761 auto& saProfileList = profileParser_->GetAllSaProfiles();
762 for (const auto& saProfile : saProfileList) {
763 if (NeedRegisterOnDemand(saProfile, saId)) {
764 HILOGD(TAG, "register ondemand SA:%{public}d to samgr", saProfile.saId);
765 int32_t ret = samgrProxy->AddOnDemandSystemAbilityInfo(saProfile.saId, procName_);
766 if (ret != ERR_OK) {
767 HILOGI(TAG, "failed to add ability info for on-demand SA:%{public}d", saProfile.saId);
768 }
769 }
770 }
771 }
772
773 // on default load, not-run-on-create SA will register to OnDemandSystemAbility
774 // on demand load, other SA will register to OnDemandSystemAbility, although some are runOnCreate
NeedRegisterOnDemand(const SaProfile & saProfile,int32_t saId)775 bool LocalAbilityManager::NeedRegisterOnDemand(const SaProfile& saProfile, int32_t saId)
776 {
777 return (saId == DEFAULT_SAID && !saProfile.runOnCreate) ||
778 (saId != DEFAULT_SAID && saProfile.saId != saId);
779 }
780
StartPhaseTasks(const std::list<SystemAbility * > & systemAbilityList)781 void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
782 {
783 if (systemAbilityList.empty()) {
784 return;
785 }
786
787 for (auto systemAbility : systemAbilityList) {
788 if (systemAbility != nullptr) {
789 HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
790 std::lock_guard<std::mutex> autoLock(startPhaseLock_);
791 ++startTaskNum_;
792 auto task = [this, systemAbility] {this->StartSystemAbilityTask(systemAbility);};
793 initPool_->AddTask(task);
794 }
795 }
796 }
797
WaitForTasks()798 void LocalAbilityManager::WaitForTasks()
799 {
800 int64_t begin = GetTickCount();
801 HILOGD(TAG, "start waiting for all tasks!");
802 std::unique_lock<std::mutex> lck(startPhaseLock_);
803 if (!startPhaseCV_.wait_for(lck, std::chrono::seconds(MAX_SA_STARTUP_TIME),
804 [this] () { return startTaskNum_ == 0; })) {
805 HILOGW(TAG, "start timeout!");
806 }
807 startTaskNum_ = 0;
808 int64_t end = GetTickCount();
809 LOGI("start tasks proc:%{public}s end,spend %{public}" PRId64 "ms",
810 Str16ToStr8(procName_).c_str(), (end - begin));
811 }
812
FindAndStartPhaseTasks(int32_t saId)813 void LocalAbilityManager::FindAndStartPhaseTasks(int32_t saId)
814 {
815 if (saId == DEFAULT_SAID) {
816 for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
817 auto iter = abilityPhaseMap_.find(bootPhase);
818 if (iter != abilityPhaseMap_.end()) {
819 StartPhaseTasks(iter->second);
820 InitializeRunOnCreateSaProfiles(bootPhase + 1);
821 WaitForTasks();
822 } else {
823 InitializeRunOnCreateSaProfiles(bootPhase + 1);
824 }
825 }
826 } else {
827 for (uint32_t bootPhase = BOOT_START; bootPhase <= OTHER_START; ++bootPhase) {
828 auto iter = abilityPhaseMap_.find(bootPhase);
829 if (iter != abilityPhaseMap_.end()) {
830 StartPhaseTasks(iter->second);
831 WaitForTasks();
832 }
833 }
834 }
835 }
836
InitializeRunOnCreateSaProfiles(uint32_t bootPhase)837 bool LocalAbilityManager::InitializeRunOnCreateSaProfiles(uint32_t bootPhase)
838 {
839 if (bootPhase > OTHER_START) {
840 return false;
841 }
842 int64_t begin = GetTickCount();
843 LOGD("ROC_InitProfiles load phase %{public}d libraries", bootPhase);
844 profileParser_->OpenSo(bootPhase);
845 LOGI("ROC_InitProfiles proc:%{public}s phase:%{public}d end, spend:%{public}" PRId64 "ms",
846 Str16ToStr8(procName_).c_str(), bootPhase, (GetTickCount() - begin));
847 auto& saProfileList = profileParser_->GetAllSaProfiles();
848 if (saProfileList.empty()) {
849 HILOGW(TAG, "sa profile is empty");
850 return false;
851 }
852 for (const auto& saProfile : saProfileList) {
853 if (saProfile.bootPhase != bootPhase) {
854 continue;
855 }
856 if (!InitializeSaProfilesInnerLocked(saProfile)) {
857 HILOGW(TAG, "SA:%{public}d init fail", saProfile.saId);
858 continue;
859 }
860 }
861 return true;
862 }
863
Run(int32_t saId)864 bool LocalAbilityManager::Run(int32_t saId)
865 {
866 HILOGD(TAG, "local ability manager is running...");
867 bool addResult = AddLocalAbilityManager();
868 if (!addResult) {
869 HILOGE(TAG, "failed to add local abilitymanager");
870 return false;
871 }
872 LOGD("Run succ to add proc name:%{public}s", Str16ToStr8(procName_).c_str());
873 uint32_t concurrentThreads = std::thread::hardware_concurrency();
874 LOGI("Run curThread is %{public}d,proc:%{public}s,SA:%{public}d",
875 concurrentThreads, Str16ToStr8(procName_).c_str(), saId);
876 initPool_->Start(concurrentThreads);
877 initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
878
879 RegisterOnDemandSystemAbility(saId);
880 FindAndStartPhaseTasks(saId);
881 initPool_->Stop();
882 return true;
883 }
884
AddLocalAbilityManager()885 bool LocalAbilityManager::AddLocalAbilityManager()
886 {
887 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
888 if (samgrProxy == nullptr) {
889 HILOGE(TAG, "failed to get samgrProxy");
890 return false;
891 }
892
893 if (localAbilityManager_ == nullptr) {
894 localAbilityManager_ = this;
895 }
896 int32_t ret = samgrProxy->AddSystemProcess(procName_, localAbilityManager_);
897 return ret == ERR_OK;
898 }
899
SetStartReason(int32_t saId,const nlohmann::json & event)900 void LocalAbilityManager::SetStartReason(int32_t saId, const nlohmann::json& event)
901 {
902 std::lock_guard<std::mutex> autoLock(ReasonLock_);
903 saIdToStartReason_[saId] = event;
904 }
905
SetStopReason(int32_t saId,const nlohmann::json & event)906 void LocalAbilityManager::SetStopReason(int32_t saId, const nlohmann::json& event)
907 {
908 std::lock_guard<std::mutex> autoLock(ReasonLock_);
909 saIdToStopReason_[saId] = event;
910 }
911
GetStartReason(int32_t saId)912 nlohmann::json LocalAbilityManager::GetStartReason(int32_t saId)
913 {
914 std::lock_guard<std::mutex> autoLock(ReasonLock_);
915 return saIdToStartReason_[saId];
916 }
917
GetStopReason(int32_t saId)918 nlohmann::json LocalAbilityManager::GetStopReason(int32_t saId)
919 {
920 std::lock_guard<std::mutex> autoLock(ReasonLock_);
921 return saIdToStopReason_[saId];
922 }
923
GetSystemAbilityStatusChange()924 sptr<ISystemAbilityStatusChange> LocalAbilityManager::GetSystemAbilityStatusChange()
925 {
926 std::lock_guard<std::mutex> autoLock(listenerLock_);
927 if (statusChangeListener_ == nullptr) {
928 statusChangeListener_ = new SystemAbilityListener();
929 }
930 return statusChangeListener_;
931 }
932
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)933 void LocalAbilityManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
934 const std::string& deviceId)
935 {
936 HILOGD(TAG, "SA:%{public}d added", systemAbilityId);
937 if (!CheckInputSysAbilityId(systemAbilityId)) {
938 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
939 return;
940 }
941
942 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
943 ISystemAbilityStatusChange::ON_ADD_SYSTEM_ABILITY);
944 }
945
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)946 void LocalAbilityManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
947 const std::string& deviceId)
948 {
949 HILOGD(TAG, "SA:%{public}d removed", systemAbilityId);
950 if (!CheckInputSysAbilityId(systemAbilityId)) {
951 HILOGW(TAG, "SA:%{public}d is invalid!", systemAbilityId);
952 return;
953 }
954
955 GetInstance().FindAndNotifyAbilityListeners(systemAbilityId, deviceId,
956 ISystemAbilityStatusChange::ON_REMOVE_SYSTEM_ABILITY);
957 }
958
SendStrategyToSA(int32_t type,int32_t systemAbilityId,int32_t level,std::string & action)959 bool LocalAbilityManager::SendStrategyToSA(int32_t type, int32_t systemAbilityId, int32_t level, std::string& action)
960 {
961 HILOGD(TAG, "SendStrategyTo SA:%{public}d", systemAbilityId);
962 auto ability = GetAbility(systemAbilityId);
963 if (ability == nullptr) {
964 HILOGW(TAG, "failed to get SA:%{public}d", systemAbilityId);
965 return false;
966 }
967 ability->OnDeviceLevelChanged(type, level, action);
968 return true;
969 }
970
IpcStatCmdProc(int32_t fd,int32_t cmd)971 bool LocalAbilityManager::IpcStatCmdProc(int32_t fd, int32_t cmd)
972 {
973 bool ret = false;
974 std::string result;
975
976 HILOGI(TAG, "IpcStatCmdProc:fd=%{public}d cmd=%{public}d request", fd, cmd);
977 if (cmd < IPC_STAT_CMD_START || cmd >= IPC_STAT_CMD_MAX) {
978 HILOGW(TAG, "para invalid, fd=%{public}d cmd=%{public}d", fd, cmd);
979 return false;
980 }
981
982 switch (cmd) {
983 case IPC_STAT_CMD_START: {
984 ret = LocalAbilityManagerDumper::StartIpcStatistics(result);
985 break;
986 }
987 case IPC_STAT_CMD_STOP: {
988 ret = LocalAbilityManagerDumper::StopIpcStatistics(result);
989 break;
990 }
991 case IPC_STAT_CMD_GET: {
992 ret = LocalAbilityManagerDumper::GetIpcStatistics(result);
993 break;
994 }
995 default:
996 return false;
997 }
998
999 if (!SaveStringToFd(fd, result)) {
1000 HILOGW(TAG, "save to fd failed");
1001 return false;
1002 }
1003 return ret;
1004 }
1005
FfrtStatCmdProc(int32_t fd,int32_t cmd)1006 bool LocalAbilityManager::FfrtStatCmdProc(int32_t fd, int32_t cmd)
1007 {
1008 HILOGI(TAG, "FfrtStatCmdProc:fd=%{public}d cmd=%{public}d request", fd, cmd);
1009 if (cmd < FFRT_STAT_CMD_START || cmd >= FFRT_STAT_CMD_MAX) {
1010 HILOGW(TAG, "para invalid, fd=%{public}d cmd=%{public}d", fd, cmd);
1011 return false;
1012 }
1013 std::string result;
1014 auto ret = LocalAbilityManagerDumper::CollectFfrtStatistics(cmd, result);
1015 if (!SaveStringToFd(fd, result)) {
1016 HILOGW(TAG, "save to fd failed");
1017 return false;
1018 }
1019 return ret;
1020 }
1021
1022 typedef void (*PGetSdkName)(uint32_t cmd, char *buf, uint32_t len);
1023
FfrtDumperProc(std::string & ffrtDumperInfo)1024 bool LocalAbilityManager::FfrtDumperProc(std::string& ffrtDumperInfo)
1025 {
1026 HILOGI(TAG, "FfrtDumperPorc request");
1027 PGetSdkName pFFrtDumpInfo = (PGetSdkName)dlsym(RTLD_DEFAULT, "ffrt_dump");
1028 char* pszErr = dlerror();
1029 if (pszErr != NULL) {
1030 HILOGE(TAG, "dlsym err info: %{public}s", pszErr);
1031 }
1032 if (pFFrtDumpInfo == NULL) {
1033 HILOGE(TAG, "dlsym failed");
1034 ffrtDumperInfo.append("process " + std::to_string(getpid()) + " did not load ffrt\n");
1035 return false;
1036 }
1037 char* buffer = new char[FFRT_BUFFER_SIZE + 1]();
1038 buffer[FFRT_BUFFER_SIZE] = 0;
1039 (*pFFrtDumpInfo)(FFRT_DUMP_INFO_ALL, buffer, FFRT_BUFFER_SIZE);
1040 if (strlen(buffer) == 0) {
1041 HILOGE(TAG, "get samgr FfrtDumperInfo failed");
1042 delete[] buffer;
1043 return false;
1044 }
1045 ffrtDumperInfo += buffer;
1046 delete[] buffer;
1047 return true;
1048 }
1049
SystemAbilityExtProc(const std::string & extension,int32_t said,SystemAbilityExtensionPara * callback,bool isAsync)1050 int32_t LocalAbilityManager::SystemAbilityExtProc(const std::string& extension, int32_t said,
1051 SystemAbilityExtensionPara* callback, bool isAsync)
1052 {
1053 (void)isAsync;
1054 if (callback == nullptr) {
1055 return INVALID_DATA;
1056 }
1057
1058 HILOGD(TAG, "SystemAbilityExtProc Extension %{public}s SA:%{public}d", extension.c_str(), said);
1059 auto ability = GetAbility(said);
1060 if (ability == nullptr) {
1061 return INVALID_DATA;
1062 }
1063 return ability->OnExtension(extension, *callback->data_, *callback->reply_);
1064 }
1065
IsResident()1066 bool LocalAbilityManager::IsResident()
1067 {
1068 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
1069 for (const auto& it : localAbilityMap_) {
1070 if ((it.second != nullptr) && (it.second->IsRunOnCreate())) {
1071 return true;
1072 }
1073 }
1074 return false;
1075 }
1076
NoNeedCheckUnused(int32_t saId)1077 bool LocalAbilityManager::NoNeedCheckUnused(int32_t saId)
1078 {
1079 std::set<int32_t> saIdWhiteList = {};
1080 return saIdWhiteList.find(saId) != saIdWhiteList.end();
1081 }
1082
IsConfigUnused()1083 bool LocalAbilityManager::IsConfigUnused()
1084 {
1085 std::shared_lock<std::shared_mutex> readLock(unusedCfgMapLock_);
1086 HILOGI(TAG, "unusedCfgMap_ size:%{public}zu", unusedCfgMap_.size());
1087 return !unusedCfgMap_.empty();
1088 }
1089
LimitUnusedTimeout(int32_t saId,int32_t timeout)1090 void LocalAbilityManager::LimitUnusedTimeout(int32_t saId, int32_t timeout)
1091 {
1092 int64_t millisecTimeout = static_cast<int64_t>(timeout * TIME_S_TO_MS);
1093 if (millisecTimeout < ONDEMAND_SA_UNUSED_TIMEOUT_LOWLIMIT) {
1094 unusedCfgMap_[saId] = ONDEMAND_SA_UNUSED_TIMEOUT_LOWLIMIT;
1095 } else if (millisecTimeout > ONDEMAND_SA_UNUSED_TIMEOUT_UPLIMIT) {
1096 unusedCfgMap_[saId] = ONDEMAND_SA_UNUSED_TIMEOUT_UPLIMIT;
1097 } else {
1098 unusedCfgMap_[saId] = millisecTimeout;
1099 }
1100 }
1101
InitUnusedCfg()1102 void LocalAbilityManager::InitUnusedCfg()
1103 {
1104 auto saProfileList = profileParser_->GetAllSaProfiles();
1105 std::shared_lock<std::shared_mutex> writeLock(unusedCfgMapLock_);
1106 for (const auto& saProfile : saProfileList) {
1107 if (!saProfile.runOnCreate && saProfile.stopOnDemand.unusedTimeout != -1) {
1108 LimitUnusedTimeout(saProfile.saId, saProfile.stopOnDemand.unusedTimeout);
1109 }
1110 }
1111 }
1112
GetSaLastRequestTime(int32_t saId,uint64_t & lastRequestTime)1113 bool LocalAbilityManager::GetSaLastRequestTime(int32_t saId, uint64_t& lastRequestTime)
1114 {
1115 auto ability = GetAbility(saId);
1116 if (ability == nullptr) {
1117 return false;
1118 }
1119 sptr<IRemoteObject> object = ability->GetAbilityRemoteObject();
1120 if (object == nullptr) {
1121 return false;
1122 }
1123 sptr<IPCObjectStub> saStub = reinterpret_cast<IPCObjectStub*>(object.GetRefPtr());
1124 if (saStub == nullptr) {
1125 return false;
1126 }
1127 lastRequestTime = saStub->GetLastRequestTime();
1128 return true;
1129 }
1130
IdentifyUnusedResident()1131 void LocalAbilityManager::IdentifyUnusedResident()
1132 {
1133 auto cur = std::chrono::steady_clock::now();
1134 uint64_t currTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
1135 cur.time_since_epoch()).count());
1136
1137 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
1138 for (const auto& it : localAbilityMap_) {
1139 int32_t saId = it.first;
1140 uint64_t lastRequestTime = 0;
1141 bool ret = GetSaLastRequestTime(saId, lastRequestTime);
1142 if ((ret != true) || (currTime <= lastRequestTime)) {
1143 continue;
1144 }
1145 uint64_t idleTime = currTime - lastRequestTime;
1146 uint64_t threshold = static_cast<uint64_t>(RESIDENT_SA_UNUSED_TIMEOUT);
1147 if (idleTime > threshold) {
1148 char reason[128] = {0};
1149 errno_t res = snprintf_s(reason, sizeof(reason), sizeof(reason) - 1,
1150 "saId:%d REASON:long time unused: %" PRIu64, saId, idleTime);
1151 if (res < 0) {
1152 continue;
1153 }
1154 ReportSAIdle(reason);
1155 }
1156 }
1157 }
1158
IdentifyUnusedOndemand()1159 void LocalAbilityManager::IdentifyUnusedOndemand()
1160 {
1161 auto cur = std::chrono::steady_clock::now();
1162 uint64_t currTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
1163 cur.time_since_epoch()).count());
1164
1165 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1166 if (samgr == nullptr) {
1167 HILOGE(TAG, "failed to get samgrProxy");
1168 return;
1169 }
1170
1171 std::shared_lock<std::shared_mutex> readLock(unusedCfgMapLock_);
1172 for (const auto& it : unusedCfgMap_) {
1173 int32_t saId = it.first;
1174 uint64_t lastRequestTime;
1175 bool ret = GetSaLastRequestTime(saId, lastRequestTime);
1176 if ((ret != true) || (currTime <= lastRequestTime)) {
1177 continue;
1178 }
1179 uint64_t threshold = it.second;
1180 uint64_t idleTime = currTime - lastRequestTime;
1181 HILOGD(TAG, "ondemand SA:%{public}d, idleTime:%{public}" PRIu64 ", longtime-unused threshold:%{public}" PRIu64,
1182 saId, idleTime, threshold);
1183 if (idleTime > threshold) {
1184 samgr->UnloadSystemAbility(saId);
1185 HILOGI(TAG, "ondemand SA:%{public}d, longtime:%{public}" PRIu64 "unused", saId, idleTime);
1186 }
1187 }
1188 }
1189
IdentifyUnusedResidentSignalHandler(int signo)1190 void IdentifyUnusedResidentSignalHandler(int signo)
1191 {
1192 if (signo == IDLE_SA_REPORT_SIGNUM) {
1193 LocalAbilityManager::GetInstance().IdentifyUnusedResident();
1194 }
1195 }
1196
StartResidentTimer()1197 void LocalAbilityManager::StartResidentTimer()
1198 {
1199 struct sigaction sa;
1200 struct sigevent sev;
1201 struct itimerspec ts;
1202
1203 if (sigaction(IDLE_SA_REPORT_SIGNUM, nullptr, &sa) == -1) {
1204 HILOGE(TAG, "sigsaction get old handler failed");
1205 return;
1206 }
1207
1208 if (sa.sa_handler != SIG_DFL) {
1209 HILOGE(TAG, "sig %{public}d has been used", IDLE_SA_REPORT_SIGNUM);
1210 return;
1211 }
1212
1213 sa.sa_handler = &IdentifyUnusedResidentSignalHandler;
1214 sa.sa_flags = 0;
1215 sa.sa_flags |= SA_RESTART;
1216 sigemptyset(&sa.sa_mask);
1217 if (sigaction(IDLE_SA_REPORT_SIGNUM, &sa, nullptr) == -1) {
1218 HILOGE(TAG, "sigsaction set new handler failed");
1219 return;
1220 }
1221
1222 sev.sigev_notify = SIGEV_SIGNAL;
1223 sev.sigev_signo = IDLE_SA_REPORT_SIGNUM;
1224 sev.sigev_value.sival_ptr = &residentTimer_;
1225 if (timer_create(CLOCK_REALTIME, &sev, &residentTimer_) != 0) {
1226 HILOGE(TAG, "timer_create failed");
1227 return;
1228 }
1229
1230 ts.it_value.tv_sec = UNUSED_RESIDENT_TIMER_INTERVAL_SECONDS;
1231 ts.it_value.tv_nsec = 0;
1232 ts.it_interval.tv_sec = UNUSED_RESIDENT_TIMER_INTERVAL_SECONDS;
1233 ts.it_interval.tv_nsec = 0;
1234 if (timer_settime(residentTimer_, 0, &ts, nullptr) != 0) {
1235 HILOGE(TAG, "timer_settime failed");
1236 return;
1237 }
1238 }
1239
StartOnDemandTimer()1240 void LocalAbilityManager::StartOnDemandTimer()
1241 {
1242 int32_t timerInterval = 0;
1243 std::function<void()> timerCallback;
1244 InitUnusedCfg();
1245 if (IsConfigUnused()) {
1246 timerInterval = UNUSED_ONDEMAND_TIMER_INTERVAL_MSECONDS;
1247 timerCallback = std::bind(&LocalAbilityManager::IdentifyUnusedOndemand, this);
1248 idleTimer_ = std::make_unique<Utils::Timer>("OS_IdleSaReport", -1);
1249 idleTimer_->Setup();
1250 ondemandTimer_ = idleTimer_->Register(timerCallback, timerInterval);
1251 HILOGI(TAG, "StartIdleTimer timerId:%{public}u, interval:%{public}d", ondemandTimer_, timerInterval);
1252 }
1253 }
1254
StartTimedQuery()1255 void LocalAbilityManager::StartTimedQuery()
1256 {
1257 {
1258 std::shared_lock<std::shared_mutex> readLock(localAbilityMapLock_);
1259 for (const auto& it : localAbilityMap_) {
1260 if (NoNeedCheckUnused(it.first)) {
1261 HILOGI(TAG, "SA:%{public}d no need check unused", it.first);
1262 return;
1263 }
1264 }
1265 }
1266
1267 if (IsResident()) {
1268 StartResidentTimer();
1269 } else {
1270 StartOnDemandTimer();
1271 }
1272 }
1273
StopTimedQuery()1274 void LocalAbilityManager::StopTimedQuery()
1275 {
1276 if (residentTimer_ != nullptr) {
1277 timer_delete(residentTimer_);
1278 residentTimer_ = nullptr;
1279 }
1280
1281 if (idleTimer_!= nullptr) {
1282 idleTimer_->Unregister(ondemandTimer_);
1283 idleTimer_->Shutdown();
1284 idleTimer_ = nullptr;
1285 }
1286 }
1287
ServiceControlCmd(int32_t fd,int32_t systemAbilityId,const std::vector<std::u16string> & args)1288 int32_t LocalAbilityManager::ServiceControlCmd(int32_t fd, int32_t systemAbilityId,
1289 const std::vector<std::u16string>& args)
1290 {
1291 auto ability = GetAbility(systemAbilityId);
1292 if (ability == nullptr) {
1293 HILOGE(TAG, "failed to get ability");
1294 return INVALID_DATA;
1295 }
1296 return ability->OnSvcCmd(fd, args);
1297 }
1298 }
1299