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