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