• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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