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