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 "ability_cache_manager.h" 17eace7efcSopenharmony_ci 18eace7efcSopenharmony_ci#include "hilog_tag_wrapper.h" 19eace7efcSopenharmony_ci 20eace7efcSopenharmony_cinamespace OHOS { 21eace7efcSopenharmony_cinamespace AAFwk { 22eace7efcSopenharmony_ciconst std::string FRS_APP_INDEX = "ohos.extra.param.key.frs_index"; 23eace7efcSopenharmony_ciconst std::string FRS_BUNDLE_NAME = "com.ohos.formrenderservice"; 24eace7efcSopenharmony_ci 25eace7efcSopenharmony_ciAbilityCacheManager::AbilityCacheManager() {} 26eace7efcSopenharmony_ci 27eace7efcSopenharmony_ciAbilityCacheManager::~AbilityCacheManager() {} 28eace7efcSopenharmony_ci 29eace7efcSopenharmony_ciAbilityCacheManager &AbilityCacheManager::GetInstance() 30eace7efcSopenharmony_ci{ 31eace7efcSopenharmony_ci static AbilityCacheManager abilityRecMgr; 32eace7efcSopenharmony_ci return abilityRecMgr; 33eace7efcSopenharmony_ci} 34eace7efcSopenharmony_ci 35eace7efcSopenharmony_civoid AbilityCacheManager::Init(uint32_t devCapacity, uint32_t procCapacity) 36eace7efcSopenharmony_ci{ 37eace7efcSopenharmony_ci devLruCapacity_ = devCapacity; 38eace7efcSopenharmony_ci procLruCapacity_ = procCapacity; 39eace7efcSopenharmony_ci} 40eace7efcSopenharmony_ci 41eace7efcSopenharmony_civoid AbilityCacheManager::RemoveAbilityRecInDevList(std::shared_ptr<AbilityRecord> abilityRecord) 42eace7efcSopenharmony_ci{ 43eace7efcSopenharmony_ci if (abilityRecord == nullptr) { 44eace7efcSopenharmony_ci return; 45eace7efcSopenharmony_ci } 46eace7efcSopenharmony_ci auto it = devRecLru_.begin(); 47eace7efcSopenharmony_ci uint32_t accessTokenId = abilityRecord->GetApplicationInfo().accessTokenId; 48eace7efcSopenharmony_ci while (it != devRecLru_.end()) { 49eace7efcSopenharmony_ci if ((*it)->GetRecordId() == abilityRecord->GetRecordId()) { 50eace7efcSopenharmony_ci devRecLru_.erase(it); 51eace7efcSopenharmony_ci devLruCnt_--; 52eace7efcSopenharmony_ci return; 53eace7efcSopenharmony_ci } else { 54eace7efcSopenharmony_ci it++; 55eace7efcSopenharmony_ci } 56eace7efcSopenharmony_ci } 57eace7efcSopenharmony_ci} 58eace7efcSopenharmony_ci 59eace7efcSopenharmony_civoid AbilityCacheManager::RemoveAbilityRecInProcList(std::shared_ptr<AbilityRecord> abilityRecord) 60eace7efcSopenharmony_ci{ 61eace7efcSopenharmony_ci if (abilityRecord == nullptr) { 62eace7efcSopenharmony_ci return; 63eace7efcSopenharmony_ci } 64eace7efcSopenharmony_ci uint32_t accessTokenId = abilityRecord->GetApplicationInfo().accessTokenId; 65eace7efcSopenharmony_ci auto findProcInfo = procLruMap_.find(accessTokenId); 66eace7efcSopenharmony_ci if (findProcInfo == procLruMap_.end()) { 67eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "can't find record"); 68eace7efcSopenharmony_ci return; 69eace7efcSopenharmony_ci } 70eace7efcSopenharmony_ci auto it = findProcInfo->second.recList.begin(); 71eace7efcSopenharmony_ci 72eace7efcSopenharmony_ci while (it != findProcInfo->second.recList.end()) { 73eace7efcSopenharmony_ci if ((*it)->GetRecordId() == abilityRecord->GetRecordId()) { 74eace7efcSopenharmony_ci findProcInfo->second.recList.erase(it); 75eace7efcSopenharmony_ci findProcInfo->second.cnt--; 76eace7efcSopenharmony_ci if (findProcInfo->second.cnt == 0) { 77eace7efcSopenharmony_ci procLruMap_.erase(findProcInfo); 78eace7efcSopenharmony_ci } 79eace7efcSopenharmony_ci return; 80eace7efcSopenharmony_ci } else { 81eace7efcSopenharmony_ci it++; 82eace7efcSopenharmony_ci } 83eace7efcSopenharmony_ci } 84eace7efcSopenharmony_ci} 85eace7efcSopenharmony_ci 86eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::AddToProcLru(std::shared_ptr<AbilityRecord> abilityRecord) 87eace7efcSopenharmony_ci{ 88eace7efcSopenharmony_ci if (abilityRecord == nullptr) { 89eace7efcSopenharmony_ci return nullptr; 90eace7efcSopenharmony_ci } 91eace7efcSopenharmony_ci auto findProcInfo = procLruMap_.find(abilityRecord->GetApplicationInfo().accessTokenId); 92eace7efcSopenharmony_ci if (findProcInfo == procLruMap_.end()) { 93eace7efcSopenharmony_ci std::list<std::shared_ptr<AbilityRecord>> recList; 94eace7efcSopenharmony_ci ProcRecordsInfo procRecInfo = {recList, 1}; 95eace7efcSopenharmony_ci procRecInfo.recList.push_back(abilityRecord); 96eace7efcSopenharmony_ci procLruMap_[abilityRecord->GetApplicationInfo().accessTokenId] = procRecInfo; 97eace7efcSopenharmony_ci return nullptr; 98eace7efcSopenharmony_ci } 99eace7efcSopenharmony_ci if (findProcInfo->second.cnt == procLruCapacity_) { 100eace7efcSopenharmony_ci RemoveAbilityRecInDevList(findProcInfo->second.recList.front()); 101eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> rec = findProcInfo->second.recList.front(); 102eace7efcSopenharmony_ci findProcInfo->second.recList.pop_front(); 103eace7efcSopenharmony_ci findProcInfo->second.recList.push_back(abilityRecord); 104eace7efcSopenharmony_ci return rec; 105eace7efcSopenharmony_ci } 106eace7efcSopenharmony_ci findProcInfo->second.cnt++; 107eace7efcSopenharmony_ci findProcInfo->second.recList.push_back(abilityRecord); 108eace7efcSopenharmony_ci return nullptr; 109eace7efcSopenharmony_ci} 110eace7efcSopenharmony_ci 111eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::AddToDevLru(std::shared_ptr<AbilityRecord> abilityRecord, 112eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> rec) 113eace7efcSopenharmony_ci{ 114eace7efcSopenharmony_ci if (rec != nullptr) { 115eace7efcSopenharmony_ci devRecLru_.push_back(abilityRecord); 116eace7efcSopenharmony_ci devLruCnt_++; 117eace7efcSopenharmony_ci return rec; 118eace7efcSopenharmony_ci } 119eace7efcSopenharmony_ci if (devLruCnt_ == devLruCapacity_) { 120eace7efcSopenharmony_ci rec = devRecLru_.front(); 121eace7efcSopenharmony_ci RemoveAbilityRecInProcList(rec); 122eace7efcSopenharmony_ci devRecLru_.pop_front(); 123eace7efcSopenharmony_ci devLruCnt_--; 124eace7efcSopenharmony_ci } 125eace7efcSopenharmony_ci devRecLru_.push_back(abilityRecord); 126eace7efcSopenharmony_ci devLruCnt_++; 127eace7efcSopenharmony_ci return rec; 128eace7efcSopenharmony_ci} 129eace7efcSopenharmony_ci 130eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::Put(std::shared_ptr<AbilityRecord> abilityRecord) 131eace7efcSopenharmony_ci{ 132eace7efcSopenharmony_ci if (abilityRecord == nullptr) { 133eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "null abilityRecord"); 134eace7efcSopenharmony_ci return nullptr; 135eace7efcSopenharmony_ci } 136eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "Put the ability to lru, service:%{public}s, extension type %{public}d", 137eace7efcSopenharmony_ci abilityRecord->GetURI().c_str(), abilityRecord->GetAbilityInfo().extensionAbilityType); 138eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 139eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> rec = AddToProcLru(abilityRecord); 140eace7efcSopenharmony_ci return AddToDevLru(abilityRecord, rec); 141eace7efcSopenharmony_ci} 142eace7efcSopenharmony_ci 143eace7efcSopenharmony_civoid AbilityCacheManager::Remove(std::shared_ptr<AbilityRecord> abilityRecord) 144eace7efcSopenharmony_ci{ 145eace7efcSopenharmony_ci if (abilityRecord == nullptr) { 146eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "null abilityRecord"); 147eace7efcSopenharmony_ci return; 148eace7efcSopenharmony_ci } 149eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "Remove the ability from lru, service:%{public}s, extension type %{public}d", 150eace7efcSopenharmony_ci abilityRecord->GetURI().c_str(), abilityRecord->GetAbilityInfo().extensionAbilityType); 151eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 152eace7efcSopenharmony_ci RemoveAbilityRecInProcList(abilityRecord); 153eace7efcSopenharmony_ci RemoveAbilityRecInDevList(abilityRecord); 154eace7efcSopenharmony_ci} 155eace7efcSopenharmony_ci 156eace7efcSopenharmony_cibool AbilityCacheManager::IsRecInfoSame(const AbilityRequest& abilityRequest, 157eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> abilityRecord) 158eace7efcSopenharmony_ci{ 159eace7efcSopenharmony_ci return abilityRecord != nullptr && 160eace7efcSopenharmony_ci abilityRequest.abilityInfo.moduleName == abilityRecord->GetAbilityInfo().moduleName && 161eace7efcSopenharmony_ci abilityRequest.want.GetElement().GetAbilityName() == abilityRecord->GetWant().GetElement().GetAbilityName(); 162eace7efcSopenharmony_ci} 163eace7efcSopenharmony_ci 164eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::GetAbilityRecInProcList(const AbilityRequest &abilityRequest) 165eace7efcSopenharmony_ci{ 166eace7efcSopenharmony_ci auto findProcInfo = procLruMap_.find(abilityRequest.appInfo.accessTokenId); 167eace7efcSopenharmony_ci if (findProcInfo == procLruMap_.end()) { 168eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "can't found bundleName"); 169eace7efcSopenharmony_ci return nullptr; 170eace7efcSopenharmony_ci } 171eace7efcSopenharmony_ci ProcRecordsInfo &procRecordsInfo = findProcInfo->second; 172eace7efcSopenharmony_ci auto recIter = procRecordsInfo.recList.begin(); 173eace7efcSopenharmony_ci while (recIter != procRecordsInfo.recList.end()) { 174eace7efcSopenharmony_ci if (IsRecInfoSame(abilityRequest, *recIter)) { 175eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> abilityRecord = *recIter; 176eace7efcSopenharmony_ci procRecordsInfo.recList.erase(recIter); 177eace7efcSopenharmony_ci procRecordsInfo.cnt--; 178eace7efcSopenharmony_ci return abilityRecord; 179eace7efcSopenharmony_ci } 180eace7efcSopenharmony_ci recIter++; 181eace7efcSopenharmony_ci } 182eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "Can't found the abilityRecord in process list for get."); 183eace7efcSopenharmony_ci return nullptr; 184eace7efcSopenharmony_ci} 185eace7efcSopenharmony_ci 186eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::Get(const AbilityRequest& abilityRequest) 187eace7efcSopenharmony_ci{ 188eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "Get the ability from lru, service:%{public}s, extension type %{public}d", 189eace7efcSopenharmony_ci abilityRequest.abilityInfo.uri.c_str(), abilityRequest.abilityInfo.extensionAbilityType); 190eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 191eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> abilityRecord = GetAbilityRecInProcList(abilityRequest); 192eace7efcSopenharmony_ci if (abilityRecord == nullptr) { 193eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, "Can't found the abilityRecord for get."); 194eace7efcSopenharmony_ci return nullptr; 195eace7efcSopenharmony_ci } 196eace7efcSopenharmony_ci RemoveAbilityRecInDevList(abilityRecord); 197eace7efcSopenharmony_ci return abilityRecord; 198eace7efcSopenharmony_ci} 199eace7efcSopenharmony_ci 200eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::FindRecordByToken(const sptr<IRemoteObject> &token) 201eace7efcSopenharmony_ci{ 202eace7efcSopenharmony_ci if (token == nullptr) { 203eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::ABILITYMGR, "null token"); 204eace7efcSopenharmony_ci return nullptr; 205eace7efcSopenharmony_ci } 206eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 207eace7efcSopenharmony_ci auto it = devRecLru_.begin(); 208eace7efcSopenharmony_ci while (it != devRecLru_.end()) { 209eace7efcSopenharmony_ci sptr<IRemoteObject> srcToken = (*it)->GetToken(); 210eace7efcSopenharmony_ci if (srcToken == token) { 211eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> &abilityRecord = *it; 212eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, 213eace7efcSopenharmony_ci "Find the ability by token from lru, service:%{public}s, extension type %{public}d", 214eace7efcSopenharmony_ci abilityRecord->GetURI().c_str(), abilityRecord->GetAbilityInfo().extensionAbilityType); 215eace7efcSopenharmony_ci return abilityRecord; 216eace7efcSopenharmony_ci } else { 217eace7efcSopenharmony_ci it++; 218eace7efcSopenharmony_ci } 219eace7efcSopenharmony_ci } 220eace7efcSopenharmony_ci return nullptr; 221eace7efcSopenharmony_ci} 222eace7efcSopenharmony_ci 223eace7efcSopenharmony_cistd::list<std::shared_ptr<AbilityRecord>> AbilityCacheManager::GetAbilityList() 224eace7efcSopenharmony_ci{ 225eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 226eace7efcSopenharmony_ci return devRecLru_; 227eace7efcSopenharmony_ci} 228eace7efcSopenharmony_ci 229eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::FindRecordBySessionId(const std::string &assertSessionId) 230eace7efcSopenharmony_ci{ 231eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 232eace7efcSopenharmony_ci auto it = devRecLru_.begin(); 233eace7efcSopenharmony_ci while (it != devRecLru_.end()) { 234eace7efcSopenharmony_ci auto assertSessionStr = (*it)->GetWant().GetStringParam(Want::PARAM_ASSERT_FAULT_SESSION_ID); 235eace7efcSopenharmony_ci if (assertSessionStr == assertSessionId) { 236eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> &abilityRecord = *it; 237eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, 238eace7efcSopenharmony_ci "Find the ability by sessionId from lru, service:%{public}s, extension type %{public}d", 239eace7efcSopenharmony_ci abilityRecord->GetURI().c_str(), abilityRecord->GetAbilityInfo().extensionAbilityType); 240eace7efcSopenharmony_ci return abilityRecord; 241eace7efcSopenharmony_ci } else { 242eace7efcSopenharmony_ci it++; 243eace7efcSopenharmony_ci } 244eace7efcSopenharmony_ci } 245eace7efcSopenharmony_ci return nullptr; 246eace7efcSopenharmony_ci} 247eace7efcSopenharmony_ci 248eace7efcSopenharmony_cistd::shared_ptr<AbilityRecord> AbilityCacheManager::FindRecordByServiceKey(const std::string &serviceKey) 249eace7efcSopenharmony_ci{ 250eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 251eace7efcSopenharmony_ci auto it = devRecLru_.begin(); 252eace7efcSopenharmony_ci while (it != devRecLru_.end()) { 253eace7efcSopenharmony_ci std::string curServiceKey = (*it)->GetURI(); 254eace7efcSopenharmony_ci if (FRS_BUNDLE_NAME == (*it)->GetAbilityInfo().bundleName) { 255eace7efcSopenharmony_ci curServiceKey = curServiceKey + std::to_string((*it)->GetWant().GetIntParam(FRS_APP_INDEX, 0)); 256eace7efcSopenharmony_ci } 257eace7efcSopenharmony_ci if (curServiceKey.compare(serviceKey) == 0) { 258eace7efcSopenharmony_ci std::shared_ptr<AbilityRecord> &abilityRecord = *it; 259eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::ABILITYMGR, 260eace7efcSopenharmony_ci "Find the ability by serviceKey from lru, service:%{public}s, extension type %{public}d", 261eace7efcSopenharmony_ci abilityRecord->GetURI().c_str(), abilityRecord->GetAbilityInfo().extensionAbilityType); 262eace7efcSopenharmony_ci return abilityRecord; 263eace7efcSopenharmony_ci } else { 264eace7efcSopenharmony_ci it++; 265eace7efcSopenharmony_ci } 266eace7efcSopenharmony_ci } 267eace7efcSopenharmony_ci return nullptr; 268eace7efcSopenharmony_ci} 269eace7efcSopenharmony_ci 270eace7efcSopenharmony_civoid AbilityCacheManager::RemoveLauncherDeathRecipient() 271eace7efcSopenharmony_ci{ 272eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 273eace7efcSopenharmony_ci auto it = devRecLru_.begin(); 274eace7efcSopenharmony_ci while (it != devRecLru_.end()) { 275eace7efcSopenharmony_ci auto targetExtension = *it; 276eace7efcSopenharmony_ci if (targetExtension != nullptr && targetExtension->GetAbilityInfo().type == AbilityType::EXTENSION && 277eace7efcSopenharmony_ci ((targetExtension->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME && 278eace7efcSopenharmony_ci targetExtension->GetAbilityInfo().bundleName == AbilityConfig::LAUNCHER_BUNDLE_NAME) || 279eace7efcSopenharmony_ci targetExtension->IsSceneBoard())) { 280eace7efcSopenharmony_ci targetExtension->RemoveAbilityDeathRecipient(); 281eace7efcSopenharmony_ci return; 282eace7efcSopenharmony_ci } 283eace7efcSopenharmony_ci it++; 284eace7efcSopenharmony_ci } 285eace7efcSopenharmony_ci} 286eace7efcSopenharmony_ci 287eace7efcSopenharmony_civoid AbilityCacheManager::SignRestartAppFlag(int32_t uid) 288eace7efcSopenharmony_ci{ 289eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 290eace7efcSopenharmony_ci auto it = devRecLru_.begin(); 291eace7efcSopenharmony_ci while (it != devRecLru_.end()) { 292eace7efcSopenharmony_ci auto abilityRecord = *it; 293eace7efcSopenharmony_ci if (abilityRecord != nullptr && abilityRecord->GetUid() == uid) { 294eace7efcSopenharmony_ci abilityRecord->SetRestartAppFlag(true); 295eace7efcSopenharmony_ci } 296eace7efcSopenharmony_ci it++; 297eace7efcSopenharmony_ci } 298eace7efcSopenharmony_ci} 299eace7efcSopenharmony_ci 300eace7efcSopenharmony_civoid AbilityCacheManager::DeleteInvalidServiceRecord(const std::string &bundleName) 301eace7efcSopenharmony_ci{ 302eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 303eace7efcSopenharmony_ci auto it = devRecLru_.begin(); 304eace7efcSopenharmony_ci while (it != devRecLru_.end()) { 305eace7efcSopenharmony_ci auto abilityRecord = *it; 306eace7efcSopenharmony_ci if (abilityRecord != nullptr && abilityRecord->GetApplicationInfo().bundleName == bundleName) { 307eace7efcSopenharmony_ci RemoveAbilityRecInProcList(abilityRecord); 308eace7efcSopenharmony_ci RemoveAbilityRecInDevList(abilityRecord); 309eace7efcSopenharmony_ci } 310eace7efcSopenharmony_ci it++; 311eace7efcSopenharmony_ci } 312eace7efcSopenharmony_ci} 313eace7efcSopenharmony_ci} // namespace AAFwk 314eace7efcSopenharmony_ci} // namespace OHOS