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 allowedCacheNum_ = OHOS::system::GetIntParameter<int>(MAX_ALLOWED_CACHE_NUM, DEFAULT_ALLOWED_CACHE_NUM);
49 if (maxProcCacheNum_ > 0) {
50 allowedCacheNum_ = maxProcCacheNum_;
51 }
52 TAG_LOGW(AAFwkTag::APPMGR,
53 "maxProcCacheNum_ %{public}d, allowedCacheNum_ %{public}d", maxProcCacheNum_, allowedCacheNum_);
54 }
55
~CacheProcessManager()56 CacheProcessManager::~CacheProcessManager()
57 {
58 }
59
SetAppMgr(const std::weak_ptr<AppMgrServiceInner> & appMgr)60 void CacheProcessManager::SetAppMgr(const std::weak_ptr<AppMgrServiceInner> &appMgr)
61 {
62 TAG_LOGD(AAFwkTag::APPMGR, "Called");
63 appMgr_ = appMgr;
64 }
65
RefreshCacheNum()66 void CacheProcessManager::RefreshCacheNum()
67 {
68 maxProcCacheNum_ = OHOS::system::GetIntParameter<int>(MAX_PROC_CACHE_NUM, 0);
69 allowedCacheNum_ = maxProcCacheNum_;
70 TAG_LOGW(AAFwkTag::APPMGR, "maxProcCacheNum %{public}d", maxProcCacheNum_);
71 }
72
QueryEnableProcessCache()73 bool CacheProcessManager::QueryEnableProcessCache()
74 {
75 return maxProcCacheNum_ > 0 || warmStartProcesEnable_;
76 }
77
PenddingCacheProcess(const std::shared_ptr<AppRunningRecord> & appRecord)78 bool CacheProcessManager::PenddingCacheProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
79 {
80 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
81 TAG_LOGD(AAFwkTag::APPMGR, "Called");
82 if (!QueryEnableProcessCache()) {
83 return false;
84 }
85 if (appRecord == nullptr) {
86 TAG_LOGE(AAFwkTag::APPMGR, "nullptr precheck failed");
87 return false;
88 }
89 if (IsCachedProcess(appRecord)) {
90 return false;
91 }
92 if (appRecord->IsKeepAliveApp()) {
93 TAG_LOGW(AAFwkTag::APPMGR, "Not cache keepalive process");
94 return false;
95 }
96 {
97 std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
98 cachedAppRecordQueue_.push_back(appRecord);
99 AddToApplicationSet(appRecord);
100 if (warmStartProcesEnable_) {
101 appRecord->SetProcessCaching(true);
102 }
103 }
104 ShrinkAndKillCache();
105 TAG_LOGI(AAFwkTag::APPMGR, "Pending %{public}s success, %{public}s", appRecord->GetName().c_str(),
106 PrintCacheQueue().c_str());
107 return true;
108 }
109
CheckAndCacheProcess(const std::shared_ptr<AppRunningRecord> & appRecord)110 bool CacheProcessManager::CheckAndCacheProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
111 {
112 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
113 TAG_LOGD(AAFwkTag::APPMGR, "Called");
114 if (!QueryEnableProcessCache()) {
115 return false;
116 }
117 if (appRecord == nullptr) {
118 TAG_LOGE(AAFwkTag::APPMGR, "appRecord nullptr precheck failed");
119 return false;
120 }
121 if (!IsCachedProcess(appRecord)) {
122 return false;
123 }
124 if (!IsAppAbilitiesEmpty(appRecord)) {
125 TAG_LOGD(AAFwkTag::APPMGR, "%{public}s not cache for abilities not empty",
126 appRecord->GetName().c_str());
127 return true;
128 }
129 if (!warmStartProcesEnable_) {
130 appRecord->ScheduleCacheProcess();
131 }
132 appRecord->SetProcessCaching(false);
133 auto notifyCached = [appRecord]() {
134 DelayedSingleton<CacheProcessManager>::GetInstance()->CheckAndNotifyCachedState(appRecord);
135 };
136 std::string taskName = "DELAY_CACHED_STATE_NOTIFY";
137 if (appRecord->GetPriorityObject()) {
138 taskName += std::to_string(appRecord->GetPriorityObject()->GetPid());
139 }
140 auto res = appRecord->CancelTask(taskName);
141 if (res) {
142 TAG_LOGD(AAFwkTag::APPMGR, "Early delay task canceled.");
143 }
144 appRecord->PostTask(taskName, AMSEventHandler::DELAY_NOTIFY_PROCESS_CACHED_STATE, notifyCached);
145 return true;
146 }
147
CheckAndNotifyCachedState(const std::shared_ptr<AppRunningRecord> & appRecord)148 bool CacheProcessManager::CheckAndNotifyCachedState(const std::shared_ptr<AppRunningRecord> &appRecord)
149 {
150 if (appRecord == nullptr) {
151 TAG_LOGE(AAFwkTag::APPMGR, "appRecord nullptr precheck failed");
152 return false;
153 }
154 auto appMgrSptr = appMgr_.lock();
155 if (appMgrSptr == nullptr) {
156 TAG_LOGE(AAFwkTag::APPMGR, "appMgr is nullptr");
157 return false;
158 }
159 auto &bundleName = appRecord->GetBundleName();
160 auto uid = appRecord->GetUid();
161 std::shared_ptr<AppRunningRecord> notifyRecord = nullptr;
162 {
163 std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
164 if (sameAppSet.find(bundleName) == sameAppSet.end() ||
165 sameAppSet[bundleName].find(uid) == sameAppSet[bundleName].end()) {
166 TAG_LOGD(AAFwkTag::APPMGR, "app set not found.");
167 return false;
168 }
169 if (sameAppSet[bundleName][uid].size() == 0) {
170 return false;
171 }
172 if (!appMgrSptr->IsAppProcessesAllCached(bundleName, uid, sameAppSet[bundleName][uid])) {
173 TAG_LOGI(AAFwkTag::APPMGR, "Not all processes of one app is cached, abort notify");
174 return false;
175 }
176 notifyRecord = *(sameAppSet[bundleName][uid].begin());
177 }
178 appRecord->SetProcessCaching(false);
179 appMgrSptr->OnAppCacheStateChanged(notifyRecord, ApplicationState::APP_STATE_CACHED);
180 TAG_LOGI(AAFwkTag::APPMGR, "app cached state is notified: %{public}s, uid:%{public}d", bundleName.c_str(), uid);
181 return true;
182 }
183
IsCachedProcess(const std::shared_ptr<AppRunningRecord> & appRecord)184 bool CacheProcessManager::IsCachedProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
185 {
186 if (appRecord == nullptr) {
187 TAG_LOGI(AAFwkTag::APPMGR, "appRecord nullptr precheck failed");
188 return false;
189 }
190 std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
191 for (auto& tmpAppRecord : cachedAppRecordQueue_) {
192 if (tmpAppRecord == appRecord) {
193 return true;
194 }
195 }
196 return false;
197 }
198
OnProcessKilled(const std::shared_ptr<AppRunningRecord> & appRecord)199 void CacheProcessManager::OnProcessKilled(const std::shared_ptr<AppRunningRecord> &appRecord)
200 {
201 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
202 if (!QueryEnableProcessCache()) {
203 return;
204 }
205 if (appRecord == nullptr) {
206 TAG_LOGE(AAFwkTag::APPMGR, "appRecord nullptr precheck failed");
207 return;
208 }
209 CheckAndNotifyCachedState(appRecord);
210 {
211 std::lock_guard<ffrt::recursive_mutex> queueLock(cacheQueueMtx);
212 srvExtRecords.erase(appRecord);
213 srvExtCheckedFlag.erase(appRecord);
214 }
215 if (!IsCachedProcess(appRecord)) {
216 return;
217 }
218 RemoveCacheRecord(appRecord);
219 TAG_LOGI(AAFwkTag::APPMGR, "%{public}s is killed, %{public}s", appRecord->GetName().c_str(),
220 PrintCacheQueue().c_str());
221 }
222
ReuseCachedProcess(const std::shared_ptr<AppRunningRecord> & appRecord)223 void CacheProcessManager::ReuseCachedProcess(const std::shared_ptr<AppRunningRecord> &appRecord)
224 {
225 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
226 if (!QueryEnableProcessCache()) {
227 return;
228 }
229 if (appRecord == nullptr) {
230 TAG_LOGE(AAFwkTag::APPMGR, "appRecord nullptr precheck failed");
231 return;
232 }
233 if (!IsCachedProcess(appRecord)) {
234 return;
235 }
236 RemoveCacheRecord(appRecord);
237 auto appMgrSptr = appMgr_.lock();
238 if (appMgrSptr == nullptr) {
239 TAG_LOGE(AAFwkTag::APPMGR, "appMgr is nullptr");
240 return;
241 }
242 if (AAFwk::UIExtensionUtils::IsUIExtension(appRecord->GetExtensionType())) {
243 if (appRecord->GetEnableProcessCache()) {
244 appRecord->SetEnableProcessCache(false);
245 }
246 }
247 appMgrSptr->OnAppCacheStateChanged(appRecord, ApplicationState::APP_STATE_READY);
248 TAG_LOGI(AAFwkTag::APPMGR, "app none cached state is notified: %{public}s, uid: %{public}d, %{public}s",
249 appRecord->GetBundleName().c_str(), appRecord->GetUid(), PrintCacheQueue().c_str());
250 }
251
IsProcessSupportHotStart(const std::shared_ptr<AppRunningRecord> & appRecord)252 bool CacheProcessManager::IsProcessSupportHotStart(const std::shared_ptr<AppRunningRecord> &appRecord)
253 {
254 if (appRecord == nullptr) {
255 return false;
256 }
257 auto appInfo = appRecord->GetApplicationInfo();
258 if (appInfo == nullptr) {
259 TAG_LOGD(AAFwkTag::APPMGR, "appinfo nullptr");
260 return false;
261 }
262 auto actualVer = appInfo->apiTargetVersion % API_VERSION_MOD;
263 if (shouldCheckApi && actualVer < API12) {
264 TAG_LOGD(AAFwkTag::APPMGR, "App %{public}s 's apiTargetVersion has %{public}d, smaller than 12",
265 appRecord->GetName().c_str(), actualVer);
266 return false;
267 }
268 if (IsAppContainsSrvExt(appRecord)) {
269 TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s is service, not support cache.",
270 appRecord->GetProcessName().c_str(), appRecord->GetBundleName().c_str());
271 return false;
272 }
273 if (!appRecord->HasUIAbilityLaunched()) {
274 TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s has not created uiability before",
275 appRecord->GetProcessName().c_str(), appRecord->GetBundleName().c_str());
276 }
277 return true;
278 }
279
CheckAndSetProcessCacheEnable(const std::shared_ptr<AppRunningRecord> & appRecord)280 void CacheProcessManager::CheckAndSetProcessCacheEnable(const std::shared_ptr<AppRunningRecord> &appRecord)
281 {
282 if (appRecord == nullptr || !warmStartProcesEnable_) {
283 return;
284 }
285 if (appRecord->GetSupportProcessCacheState() != SupportProcessCacheState::SUPPORT) {
286 return;
287 }
288 if (!appRecord->GetPriorityObject()) {
289 return;
290 }
291 bool forceKillProcess =
292 AAFwk::ResSchedUtil::GetInstance().CheckShouldForceKillProcess(appRecord->GetPriorityObject()->GetPid());
293 if (forceKillProcess) {
294 appRecord->SetProcessCacheBlocked(true);
295 return;
296 }
297 }
298
IsAppSupportProcessCache(const std::shared_ptr<AppRunningRecord> & appRecord)299 bool CacheProcessManager::IsAppSupportProcessCache(const std::shared_ptr<AppRunningRecord> &appRecord)
300 {
301 if (appRecord == nullptr) {
302 TAG_LOGI(AAFwkTag::APPMGR, "precheck failed");
303 return false;
304 }
305 if (appRecord->IsAttachedToStatusBar()) {
306 TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s is attached to statusbar, not support cache",
307 appRecord->GetProcessName().c_str(), appRecord->GetBundleName().c_str());
308 return false;
309 }
310 if (appRecord->IsKeepAliveApp()) {
311 TAG_LOGD(AAFwkTag::APPMGR, "Keepalive app.");
312 return false;
313 }
314 if (appRecord->GetParentAppRecord() != nullptr) {
315 TAG_LOGD(AAFwkTag::APPMGR, "Child App, not support.");
316 return false;
317 }
318 if (maxProcCacheNum_ > 0 && !IsProcessSupportHotStart(appRecord)) {
319 return false;
320 }
321 return IsAppSupportProcessCacheInnerFirst(appRecord);
322 }
323
IsAppSupportProcessCacheInnerFirst(const std::shared_ptr<AppRunningRecord> & appRecord)324 bool CacheProcessManager::IsAppSupportProcessCacheInnerFirst(const std::shared_ptr<AppRunningRecord> &appRecord)
325 {
326 if (appRecord == nullptr) {
327 TAG_LOGI(AAFwkTag::APPMGR, "appRecord nullptr precheck failed");
328 return false;
329 }
330 if (appRecord->GetBundleName() == SHELL_ASSISTANT_BUNDLENAME) {
331 TAG_LOGD(AAFwkTag::APPMGR, "shell assistant, not support.");
332 return false;
333 }
334 if (appRecord->GetProcessCacheBlocked()) {
335 TAG_LOGD(AAFwkTag::APPMGR, "%{public}s of %{public}s 's process cache temporarily blocked.",
336 appRecord->GetProcessName().c_str(), appRecord->GetBundleName().c_str());
337 return false;
338 }
339 if (warmStartProcesEnable_) {
340 if (!appRecord->HasUIAbilityLaunched() &&
341 !AAFwk::UIExtensionUtils::IsUIExtension(appRecord->GetExtensionType())) {
342 return false;
343 }
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