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