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