• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 <vector>
17 #include <sstream>
18 #include "hitrace_meter.h"
19 #include "parameters.h"
20 #include "hilog_tag_wrapper.h"
21 #include "app_state_observer_manager.h"
22 #include "app_mgr_service_inner.h"
23 #include "app_utils.h"
24 #include "cache_process_manager.h"
25 #include "hisysevent.h"
26 #include "res_sched_util.h"
27 #include "ui_extension_utils.h"
28 
29 namespace {
30 const std::string MAX_PROC_CACHE_NUM = "persist.sys.abilityms.maxProcessCacheNum";
31 const std::string RESOURCE_WARM_START_PROCESS_ENABLE = "persist.resourceschedule.enable_warm_start_process";
32 const std::string MAX_ALLOWED_CACHE_NUM = "const.resourceschedule.max_cached_process_nums";
33 const std::string PROCESS_CACHE_API_CHECK_CONFIG = "persist.sys.abilityms.processCacheApiCheck";
34 const std::string PROCESS_CACHE_SET_SUPPORT_CHECK_CONFIG = "persist.sys.abilityms.processCacheSetSupportCheck";
35 constexpr int32_t API12 = 12;
36 constexpr int32_t API_VERSION_MOD = 100;
37 constexpr int32_t DEFAULT_ALLOWED_CACHE_NUM = 64;
38 constexpr const char *EVENT_KEY_VERSION_NAME = "VERSION_NAME";
39 constexpr const char *EVENT_KEY_VERSION_CODE = "VERSION_CODE";
40 constexpr const char *EVENT_KEY_BUNDLE_NAME = "BUNDLE_NAME";
41 constexpr const char *EVENT_KEY_CACHE_STATE = "CACHE_STATE";
42 }
43 
44 namespace OHOS {
45 namespace AppExecFwk {
46 
CacheProcessManager()47 CacheProcessManager::CacheProcessManager()
48 {
49     maxProcCacheNum_ = OHOS::system::GetIntParameter<int>(MAX_PROC_CACHE_NUM, 0);
50     shouldCheckApi = OHOS::system::GetBoolParameter(PROCESS_CACHE_API_CHECK_CONFIG, true);
51     shouldCheckSupport = OHOS::system::GetBoolParameter(PROCESS_CACHE_SET_SUPPORT_CHECK_CONFIG, true);
52     warmStartProcesEnable_ = OHOS::system::GetBoolParameter(RESOURCE_WARM_START_PROCESS_ENABLE, false);
53     allowedCacheNum_ = OHOS::system::GetIntParameter<int>(MAX_ALLOWED_CACHE_NUM, DEFAULT_ALLOWED_CACHE_NUM);
54     if (maxProcCacheNum_ > 0) {
55         allowedCacheNum_ = maxProcCacheNum_;
56     }
57     TAG_LOGW(AAFwkTag::APPMGR,
58         "maxProcCacheNum_ %{public}d, allowedCacheNum_ %{public}d", maxProcCacheNum_, allowedCacheNum_);
59 }
60 
~CacheProcessManager()61 CacheProcessManager::~CacheProcessManager()
62 {
63 }
64 
SetAppMgr(const std::weak_ptr<AppMgrServiceInner> & appMgr)65 void CacheProcessManager::SetAppMgr(const std::weak_ptr<AppMgrServiceInner> &appMgr)
66 {
67     TAG_LOGD(AAFwkTag::APPMGR, "Called");
68     appMgr_ = appMgr;
69 }
70 
RefreshCacheNum()71 void CacheProcessManager::RefreshCacheNum()
72 {
73     maxProcCacheNum_ = OHOS::system::GetIntParameter<int>(MAX_PROC_CACHE_NUM, 0);
74     allowedCacheNum_ = maxProcCacheNum_;
75     TAG_LOGW(AAFwkTag::APPMGR, "maxProcCacheNum %{public}d", maxProcCacheNum_);
76 }
77 
QueryEnableProcessCache()78 bool CacheProcessManager::QueryEnableProcessCache()
79 {
80     return maxProcCacheNum_ > 0 || warmStartProcesEnable_;
81 }
82 
PenddingCacheProcess(const std::shared_ptr<AppRunningRecord> & appRecord)83 bool CacheProcessManager::PenddingCacheProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
84 {
85     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
86     TAG_LOGD(AAFwkTag::APPMGR, "Called");
87     if (!QueryEnableProcessCache()) {
88         return false;
89     }
90     if (appRecord == nullptr) {
91         TAG_LOGE(AAFwkTag::APPMGR, "precheck failed");
92         return false;
93     }
94     if (IsCachedProcess(appRecord)) {
95         return false;
96     }
97     if (appRecord->IsKeepAliveApp()) {
98         TAG_LOGW(AAFwkTag::APPMGR, "Not cache process");
99         return false;
100     }
101     {
102         std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
103         cachedAppRecordQueue_.push_back(appRecord);
104         AddToApplicationSet(appRecord);
105         if (warmStartProcesEnable_) {
106             appRecord->SetProcessCaching(true);
107         }
108     }
109     ShrinkAndKillCache();
110     TAG_LOGI(AAFwkTag::APPMGR, "Pending %{public}s success, %{public}s", appRecord->GetName().c_str(),
111         PrintCacheQueue().c_str());
112     return true;
113 }
114 
CheckAndCacheProcess(const std::shared_ptr<AppRunningRecord> & appRecord)115 bool CacheProcessManager::CheckAndCacheProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
116 {
117     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
118     TAG_LOGD(AAFwkTag::APPMGR, "Called");
119     if (!QueryEnableProcessCache()) {
120         return false;
121     }
122     if (appRecord == nullptr) {
123         TAG_LOGE(AAFwkTag::APPMGR, "precheck failed");
124         return false;
125     }
126     appRecord->SetProcessCaching(false);
127     if (!IsCachedProcess(appRecord)) {
128         return false;
129     }
130     if (!IsAppAbilitiesEmpty(appRecord)) {
131         TAG_LOGD(AAFwkTag::APPMGR, "%{public}s not cache for abilities not empty",
132             appRecord->GetName().c_str());
133         return true;
134     }
135     if (!warmStartProcesEnable_) {
136         appRecord->ScheduleCacheProcess();
137     }
138     auto appInfo = appRecord->GetApplicationInfo();
139     HiSysEventWrite(HiSysEvent::Domain::AAFWK, "CACHE_START_APP", HiSysEvent::EventType::BEHAVIOR,
140         EVENT_KEY_VERSION_CODE, appInfo->versionCode, EVENT_KEY_VERSION_NAME, appInfo->versionName,
141         EVENT_KEY_BUNDLE_NAME, appInfo->bundleName, EVENT_KEY_CACHE_STATE, "processEnterCache");
142     auto notifyCached = [appRecord]() {
143         DelayedSingleton<CacheProcessManager>::GetInstance()->CheckAndNotifyCachedState(appRecord);
144     };
145     std::string taskName = "DELAY_CACHED_STATE_NOTIFY";
146     if (appRecord->GetPriorityObject()) {
147         taskName += std::to_string(appRecord->GetPid());
148     }
149     auto res = appRecord->CancelTask(taskName);
150     if (res) {
151         TAG_LOGD(AAFwkTag::APPMGR, "Early delay task canceled.");
152     }
153     appRecord->PostTask(taskName, AMSEventHandler::DELAY_NOTIFY_PROCESS_CACHED_STATE, notifyCached);
154     return true;
155 }
156 
CheckAndNotifyCachedState(const std::shared_ptr<AppRunningRecord> & appRecord)157 bool CacheProcessManager::CheckAndNotifyCachedState(const std::shared_ptr<AppRunningRecord> &appRecord)
158 {
159     if (appRecord == nullptr) {
160         TAG_LOGE(AAFwkTag::APPMGR, "precheck failed");
161         return false;
162     }
163     auto appMgrSptr = appMgr_.lock();
164     if (appMgrSptr == nullptr) {
165         TAG_LOGE(AAFwkTag::APPMGR, "null appMgr");
166         return false;
167     }
168     auto &bundleName = appRecord->GetBundleName();
169     auto uid = appRecord->GetUid();
170     std::shared_ptr<AppRunningRecord> notifyRecord = nullptr;
171     {
172         std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
173         if (sameAppSet.find(bundleName) == sameAppSet.end() ||
174             sameAppSet[bundleName].find(uid) == sameAppSet[bundleName].end()) {
175             TAG_LOGD(AAFwkTag::APPMGR, "app set not found.");
176             return false;
177         }
178         if (sameAppSet[bundleName][uid].size() == 0) {
179             return false;
180         }
181         if (!appMgrSptr->IsAppProcessesAllCached(bundleName, uid, sameAppSet[bundleName][uid])) {
182             TAG_LOGI(AAFwkTag::APPMGR, "Not cache process");
183             return false;
184         }
185         notifyRecord = *(sameAppSet[bundleName][uid].begin());
186     }
187     appRecord->SetProcessCaching(false);
188     appMgrSptr->OnAppCacheStateChanged(notifyRecord, ApplicationState::APP_STATE_CACHED);
189     TAG_LOGI(AAFwkTag::APPMGR, "notified: %{public}s, uid:%{public}d", bundleName.c_str(), uid);
190     return true;
191 }
192 
IsCachedProcess(const std::shared_ptr<AppRunningRecord> & appRecord)193 bool CacheProcessManager::IsCachedProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
194 {
195     if (appRecord == nullptr) {
196         TAG_LOGI(AAFwkTag::APPMGR, "precheck failed");
197         return false;
198     }
199     std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
200     for (auto& tmpAppRecord : cachedAppRecordQueue_) {
201         if (tmpAppRecord == appRecord) {
202             return true;
203         }
204     }
205     return false;
206 }
207 
OnProcessKilled(const std::shared_ptr<AppRunningRecord> & appRecord)208 void CacheProcessManager::OnProcessKilled(const std::shared_ptr<AppRunningRecord> &appRecord)
209 {
210     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
211     if (!QueryEnableProcessCache()) {
212         return;
213     }
214     if (appRecord == nullptr) {
215         TAG_LOGE(AAFwkTag::APPMGR, "precheck failed");
216         return;
217     }
218     CheckAndNotifyCachedState(appRecord);
219     {
220         std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
221         srvExtRecords.erase(appRecord);
222         srvExtCheckedFlag.erase(appRecord);
223     }
224     if (!IsCachedProcess(appRecord)) {
225         return;
226     }
227     RemoveCacheRecord(appRecord);
228     auto appInfo = appRecord->GetApplicationInfo();
229     HiSysEventWrite(HiSysEvent::Domain::AAFWK, "CACHE_START_APP", HiSysEvent::EventType::BEHAVIOR,
230         EVENT_KEY_VERSION_CODE, appInfo->versionCode, EVENT_KEY_VERSION_NAME, appInfo->versionName,
231         EVENT_KEY_BUNDLE_NAME, appInfo->bundleName, EVENT_KEY_CACHE_STATE, "destroyedByExternal");
232     TAG_LOGI(AAFwkTag::APPMGR, "%{public}s is killed, %{public}s", appRecord->GetName().c_str(),
233         PrintCacheQueue().c_str());
234 }
235 
ReuseCachedProcess(const std::shared_ptr<AppRunningRecord> & appRecord)236 bool CacheProcessManager::ReuseCachedProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
237 {
238     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
239     if (!QueryEnableProcessCache()) {
240         return false;
241     }
242     if (appRecord == nullptr) {
243         TAG_LOGE(AAFwkTag::APPMGR, "precheck failed");
244         return false;
245     }
246     auto appInfo = appRecord->GetApplicationInfo();
247     if (!IsCachedProcess(appRecord)) {
248         return false;
249     }
250     RemoveCacheRecord(appRecord);
251     HiSysEventWrite(HiSysEvent::Domain::AAFWK, "CACHE_START_APP", HiSysEvent::EventType::BEHAVIOR,
252         EVENT_KEY_VERSION_CODE, appInfo->versionCode, EVENT_KEY_VERSION_NAME, appInfo->versionName,
253         EVENT_KEY_BUNDLE_NAME, appInfo->bundleName, EVENT_KEY_CACHE_STATE, "exitCacheNormal");
254     HiSysEventWrite(HiSysEvent::Domain::AAFWK, "CACHE_START_APP", HiSysEvent::EventType::BEHAVIOR,
255         EVENT_KEY_VERSION_CODE, appInfo->versionCode, EVENT_KEY_VERSION_NAME, appInfo->versionName,
256         EVENT_KEY_BUNDLE_NAME, appInfo->bundleName, EVENT_KEY_CACHE_STATE, "processCacheLaunch");
257     auto appMgrSptr = appMgr_.lock();
258     if (appMgrSptr == nullptr) {
259         TAG_LOGE(AAFwkTag::APPMGR, "null appMgr");
260         return true;
261     }
262     appMgrSptr->OnAppCacheStateChanged(appRecord, ApplicationState::APP_STATE_READY);
263     TAG_LOGI(AAFwkTag::APPMGR, "app none cached state is notified: %{public}s, uid: %{public}d, %{public}s",
264         appRecord->GetBundleName().c_str(), appRecord->GetUid(), PrintCacheQueue().c_str());
265     return true;
266 }
267 
IsProcessSupportHotStart(const std::shared_ptr<AppRunningRecord> & appRecord)268 bool CacheProcessManager::IsProcessSupportHotStart(const std::shared_ptr<AppRunningRecord> &appRecord)
269 {
270     if (appRecord == nullptr) {
271         return false;
272     }
273     auto appInfo = appRecord->GetApplicationInfo();
274     if (appInfo == nullptr) {
275         TAG_LOGD(AAFwkTag::APPMGR, "appinfo nullptr");
276         return false;
277     }
278     auto actualVer = appInfo->apiTargetVersion % API_VERSION_MOD;
279     if (shouldCheckApi && actualVer < API12) {
280         TAG_LOGD(AAFwkTag::APPMGR, "App %{public}s 's apiTargetVersion has %{public}d, smaller than 12",
281             appRecord->GetName().c_str(), actualVer);
282         return false;
283     }
284     if (!appRecord->HasUIAbilityLaunched() &&
285         !AAFwk::UIExtensionUtils::IsUIExtension(appRecord->GetExtensionType())) {
286         TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s has not created uiability before.",
287             appRecord->GetProcessName().c_str(), appRecord->GetBundleName().c_str());
288         return false;
289     }
290     return true;
291 }
292 
CheckAndSetProcessCacheEnable(const std::shared_ptr<AppRunningRecord> & appRecord)293 void CacheProcessManager::CheckAndSetProcessCacheEnable(const std::shared_ptr<AppRunningRecord> &appRecord)
294 {
295     if (appRecord == nullptr || !warmStartProcesEnable_) {
296         return;
297     }
298     if (appRecord->GetSupportProcessCacheState() != SupportProcessCacheState::SUPPORT) {
299         return;
300     }
301     if (!appRecord->GetPriorityObject()) {
302         return;
303     }
304     if (appRecord->GetProcessCacheBlocked()) {
305         return;
306     }
307     bool forceKillProcess =
308         AAFwk::ResSchedUtil::GetInstance().CheckShouldForceKillProcess(appRecord->GetPid());
309     if (forceKillProcess) {
310         appRecord->SetProcessCacheBlocked(true);
311         return;
312     }
313 }
314 
IsAppSupportProcessCache(const std::shared_ptr<AppRunningRecord> & appRecord)315 bool CacheProcessManager::IsAppSupportProcessCache(const std::shared_ptr<AppRunningRecord> &appRecord)
316 {
317     if (appRecord == nullptr) {
318         TAG_LOGI(AAFwkTag::APPMGR, "precheck failed");
319         return false;
320     }
321     if (appRecord->IsAttachedToStatusBar()) {
322         TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s is attached to statusbar, not support cache",
323             appRecord->GetProcessName().c_str(), appRecord->GetBundleName().c_str());
324         return false;
325     }
326     if (appRecord->IsKeepAliveApp()) {
327         TAG_LOGD(AAFwkTag::APPMGR, "Keepalive app.");
328         return false;
329     }
330     if (appRecord->GetParentAppRecord() != nullptr) {
331         TAG_LOGD(AAFwkTag::APPMGR, "Child App, not support.");
332         return false;
333     }
334     if (maxProcCacheNum_ > 0 && !IsProcessSupportHotStart(appRecord)) {
335         return false;
336     }
337     return IsAppSupportProcessCacheInnerFirst(appRecord);
338 }
339 
IsAppSupportProcessCacheInnerFirst(const std::shared_ptr<AppRunningRecord> & appRecord)340 bool CacheProcessManager::IsAppSupportProcessCacheInnerFirst(const std::shared_ptr<AppRunningRecord> &appRecord)
341 {
342     if (appRecord == nullptr) {
343         TAG_LOGI(AAFwkTag::APPMGR, "precheck failed");
344         return false;
345     }
346     if (appRecord->GetBundleName() == AAFwk::AppUtils::GetInstance().GetBrokerDelegateBundleName()) {
347         TAG_LOGD(AAFwkTag::APPMGR, "shell assistant, not support.");
348         return false;
349     }
350     if (appRecord->GetProcessCacheBlocked()) {
351         TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s 's process cache temporarily blocked.",
352             appRecord->GetProcessName().c_str(), appRecord->GetBundleName().c_str());
353         return false;
354     }
355     if (warmStartProcesEnable_) {
356         if (!appRecord->HasUIAbilityLaunched() &&
357             !AAFwk::UIExtensionUtils::IsUIExtension(appRecord->GetExtensionType())) {
358             return false;
359         }
360     }
361 
362     auto supportState = appRecord->GetSupportProcessCacheState();
363     switch (supportState) {
364         case SupportProcessCacheState::UNSPECIFIED:
365             TAG_LOGD(AAFwkTag::APPMGR, "App %{public}s has not defined support state.",
366                 appRecord->GetBundleName().c_str());
367             return shouldCheckSupport ? false : true;
368         case SupportProcessCacheState::SUPPORT:
369             return true;
370         case SupportProcessCacheState::NOT_SUPPORT:
371             TAG_LOGD(AAFwkTag::APPMGR, "App %{public}s defines not support.",
372                 appRecord->GetBundleName().c_str());
373             return false;
374         default:
375             TAG_LOGD(AAFwkTag::APPMGR, "Invalid support state.");
376             return false;
377     }
378 }
379 
IsAppShouldCache(const std::shared_ptr<AppRunningRecord> & appRecord)380 bool CacheProcessManager::IsAppShouldCache(const std::shared_ptr<AppRunningRecord> &appRecord)
381 {
382     if (appRecord == nullptr) {
383         return false;
384     }
385     if (!QueryEnableProcessCache()) {
386         return false;
387     }
388     if (IsCachedProcess(appRecord) && !appRecord->GetProcessCacheBlocked()) {
389         return true;
390     }
391     if (!IsAppSupportProcessCache(appRecord)) {
392         return false;
393     }
394     return true;
395 }
396 
IsAppAbilitiesEmpty(const std::shared_ptr<AppRunningRecord> & appRecord)397 bool CacheProcessManager::IsAppAbilitiesEmpty(const std::shared_ptr<AppRunningRecord> &appRecord)
398 {
399     if (appRecord == nullptr) {
400         TAG_LOGI(AAFwkTag::APPMGR, "precheck failed");
401         return false;
402     }
403     auto allModuleRecord = appRecord->GetAllModuleRecord();
404     for (auto moduleRecord : allModuleRecord) {
405         if (moduleRecord != nullptr && !moduleRecord->GetAbilities().empty()) {
406             return false;
407         }
408     }
409     TAG_LOGD(AAFwkTag::APPMGR, "abilities all empty: %{public}s",
410         appRecord->GetName().c_str());
411     return true;
412 }
413 
GetCurrentCachedProcNum()414 int CacheProcessManager::GetCurrentCachedProcNum()
415 {
416     std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
417     return static_cast<int>(cachedAppRecordQueue_.size());
418 }
419 
RemoveCacheRecord(const std::shared_ptr<AppRunningRecord> & appRecord)420 void CacheProcessManager::RemoveCacheRecord(const std::shared_ptr<AppRunningRecord> &appRecord)
421 {
422     std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
423     for (auto it = cachedAppRecordQueue_.begin(); it != cachedAppRecordQueue_.end();) {
424         if (appRecord == *it) {
425             RemoveFromApplicationSet(*it);
426             it = cachedAppRecordQueue_.erase(it);
427         } else {
428             it++;
429         }
430     }
431 }
432 
ShrinkAndKillCache()433 void CacheProcessManager::ShrinkAndKillCache()
434 {
435     TAG_LOGD(AAFwkTag::APPMGR, "Called");
436     if (maxProcCacheNum_ <= 0 && !warmStartProcesEnable_) {
437         TAG_LOGI(AAFwkTag::APPMGR, "Cache disabled.");
438         return;
439     }
440     std::vector<std::shared_ptr<AppRunningRecord>> cleanList;
441     {
442         std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
443         while (GetCurrentCachedProcNum() > allowedCacheNum_) {
444             const auto& tmpAppRecord = cachedAppRecordQueue_.front();
445             cachedAppRecordQueue_.pop_front();
446             RemoveFromApplicationSet(tmpAppRecord);
447             if (tmpAppRecord == nullptr) {
448                 continue;
449             }
450             cleanList.push_back(tmpAppRecord);
451             TAG_LOGI(AAFwkTag::APPMGR, "need clean record %{public}s, current =%{public}d",
452                 tmpAppRecord->GetName().c_str(), GetCurrentCachedProcNum());
453         }
454     }
455     for (auto& tmpAppRecord : cleanList) {
456         auto appInfo = tmpAppRecord->GetApplicationInfo();
457         HiSysEventWrite(HiSysEvent::Domain::AAFWK, "CACHE_START_APP", HiSysEvent::EventType::BEHAVIOR,
458             EVENT_KEY_VERSION_CODE, appInfo->versionCode, EVENT_KEY_VERSION_NAME, appInfo->versionName,
459             EVENT_KEY_BUNDLE_NAME, appInfo->bundleName, EVENT_KEY_CACHE_STATE, "killForOverload");
460         KillProcessByRecord(tmpAppRecord);
461     }
462 }
463 
KillProcessByRecord(const std::shared_ptr<AppRunningRecord> & appRecord)464 bool CacheProcessManager::KillProcessByRecord(const std::shared_ptr<AppRunningRecord> &appRecord)
465 {
466     if (appRecord == nullptr) {
467         TAG_LOGW(AAFwkTag::APPMGR, "precheck failed");
468         return false;
469     }
470     auto appMgrSptr = appMgr_.lock();
471     if (appMgrSptr == nullptr) {
472         TAG_LOGE(AAFwkTag::APPMGR, "null appMgr");
473         return false;
474     }
475     appRecord->SetProcessCaching(false);
476     // notify before kill
477     appMgrSptr->OnAppCacheStateChanged(appRecord, ApplicationState::APP_STATE_READY);
478     // this uses ScheduleProcessSecurityExit
479     appMgrSptr->KillApplicationByRecord(appRecord);
480     return true;
481 }
482 
PrintCacheQueue()483 std::string CacheProcessManager::PrintCacheQueue()
484 {
485     std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
486     std::stringstream ss;
487     ss << "queue size: " << cachedAppRecordQueue_.size() << ", record in queue: ";
488     for (auto& record : cachedAppRecordQueue_) {
489         if (record == nullptr) {
490             ss << "null, ";
491         } else {
492             ss << record->GetName() << ", ";
493         }
494     }
495     ss << ".";
496     return ss.str();
497 }
498 
AddToApplicationSet(const std::shared_ptr<AppRunningRecord> & appRecord)499 void CacheProcessManager::AddToApplicationSet(const std::shared_ptr<AppRunningRecord> &appRecord)
500 {
501     if (appRecord == nullptr) {
502         return;
503     }
504     auto &bundleName = appRecord->GetBundleName();
505     std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
506     if (sameAppSet.find(bundleName) == sameAppSet.end()) {
507         std::map<int32_t, std::set<std::shared_ptr<AppRunningRecord>>> uidMap;
508         std::set<std::shared_ptr<AppRunningRecord>> recordSet;
509         recordSet.insert(appRecord);
510         uidMap.insert(std::make_pair(appRecord->GetUid(), recordSet));
511         sameAppSet.insert(std::make_pair(bundleName, uidMap));
512     }
513     auto uid = appRecord->GetUid();
514     if (sameAppSet[bundleName].find(uid) == sameAppSet[bundleName].end()) {
515         std::set<std::shared_ptr<AppRunningRecord>> recordSet;
516         recordSet.insert(appRecord);
517         sameAppSet[bundleName].insert(std::make_pair(uid, recordSet));
518         return;
519     }
520     sameAppSet[bundleName][uid].insert(appRecord);
521 }
522 
RemoveFromApplicationSet(const std::shared_ptr<AppRunningRecord> & appRecord)523 void CacheProcessManager::RemoveFromApplicationSet(const std::shared_ptr<AppRunningRecord> &appRecord)
524 {
525     if (appRecord == nullptr) {
526         return;
527     }
528     auto &bundleName = appRecord->GetBundleName();
529     std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
530     if (sameAppSet.find(bundleName) == sameAppSet.end()) {
531         return;
532     }
533     auto uid = appRecord->GetUid();
534     if (sameAppSet[bundleName].find(uid) == sameAppSet[bundleName].end()) {
535         return;
536     }
537     sameAppSet[bundleName][uid].erase(appRecord);
538     if (sameAppSet[bundleName][uid].size() == 0) {
539         sameAppSet[bundleName].erase(uid);
540     }
541     if (sameAppSet[bundleName].size() == 0) {
542         sameAppSet.erase(bundleName);
543     }
544 }
545 
PrepareActivateCache(const std::shared_ptr<AppRunningRecord> & appRecord)546 void CacheProcessManager::PrepareActivateCache(const std::shared_ptr<AppRunningRecord> &appRecord)
547 {
548     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
549     if (!QueryEnableProcessCache()) {
550         return;
551     }
552     if (appRecord == nullptr) {
553         return;
554     }
555     if (!IsCachedProcess(appRecord)) {
556         return;
557     }
558     TAG_LOGD(AAFwkTag::APPMGR, "%{public}s needs activate.", appRecord->GetBundleName().c_str());
559     auto appMgrSptr = appMgr_.lock();
560     if (appMgrSptr == nullptr) {
561         TAG_LOGE(AAFwkTag::APPMGR, "null appMgr");
562         return;
563     }
564     appMgrSptr->OnAppCacheStateChanged(appRecord, ApplicationState::APP_STATE_READY);
565 }
566 
IsAppContainsSrvExt(const std::shared_ptr<AppRunningRecord> & appRecord)567 bool CacheProcessManager::IsAppContainsSrvExt(const std::shared_ptr<AppRunningRecord> &appRecord)
568 {
569     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
570     std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
571     if (appRecord == nullptr) {
572         return false;
573     }
574     if (srvExtCheckedFlag.find(appRecord) != srvExtCheckedFlag.end()) {
575         return srvExtRecords.find(appRecord) != srvExtRecords.end() ? true : false;
576     }
577     auto allModuleRecord = appRecord->GetAllModuleRecord();
578     for (auto moduleRecord : allModuleRecord) {
579         if (moduleRecord == nullptr) {
580             continue;
581         }
582         HapModuleInfo hapModuleInfo;
583         moduleRecord->GetHapModuleInfo(hapModuleInfo);
584         for (auto abilityInfo : hapModuleInfo.abilityInfos) {
585             if (abilityInfo.type == AppExecFwk::AbilityType::EXTENSION &&
586                 abilityInfo.extensionAbilityType == AppExecFwk::ExtensionAbilityType::SERVICE) {
587                     srvExtRecords.insert(appRecord);
588                 TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s is service, will not cache",
589                     abilityInfo.name.c_str(), appRecord->GetBundleName().c_str());
590             }
591         }
592         for (auto extAbilityInfo : hapModuleInfo.extensionInfos) {
593             if (extAbilityInfo.type == AppExecFwk::ExtensionAbilityType::SERVICE) {
594                 srvExtRecords.insert(appRecord);
595                 TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s is service, will not cache",
596                     extAbilityInfo.name.c_str(), appRecord->GetBundleName().c_str());
597             }
598         }
599     }
600     srvExtCheckedFlag.insert(appRecord);
601     return srvExtRecords.find(appRecord) != srvExtRecords.end() ? true : false;
602 }
603 
OnAppProcessCacheBlocked(const std::shared_ptr<AppRunningRecord> & appRecord)604 void CacheProcessManager::OnAppProcessCacheBlocked(const std::shared_ptr<AppRunningRecord> &appRecord)
605 {
606     HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
607     if (!QueryEnableProcessCache()) {
608         return;
609     }
610     if (appRecord == nullptr || !IsCachedProcess(appRecord)) {
611         return;
612     }
613     TAG_LOGI(AAFwkTag::APPMGR, "%{public}s is cached and is blocked, which needs exit.",
614         appRecord->GetBundleName().c_str());
615     RemoveCacheRecord(appRecord);
616     KillProcessByRecord(appRecord);
617 }
618 } // namespace OHOS
619 } // namespace AppExecFwk