1 /*
2 * Copyright (c) 2025 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 "bundle_resource_icon_rdb.h"
17
18 #include "app_log_wrapper.h"
19 #include "bundle_constants.h"
20 #include "bundle_resource_constants.h"
21 #include "bundle_service_constants.h"
22 #include "bundle_util.h"
23 #include "hitrace_meter.h"
24 #include "scope_guard.h"
25 #include "string_ex.h"
26
27 namespace OHOS {
28 namespace AppExecFwk {
29 namespace {
30 constexpr int32_t INDEX_NAME = 0;
31 constexpr int32_t INDEX_USERID = 1;
32 constexpr int32_t INDEX_ICON_TYPE = 2;
33 constexpr int32_t INDEX_ICON = 3;
34 constexpr int32_t INDEX_FOREGROUND = 4;
35 constexpr int32_t INDEX_BACKGROUND = 5;
36 }
37
BundleResourceIconRdb()38 BundleResourceIconRdb::BundleResourceIconRdb()
39 {
40 APP_LOGI_NOFUNC("BundleResourceIconRdb create");
41 BmsRdbConfig bmsRdbConfig;
42 bmsRdbConfig.dbName = BundleResourceConstants::BUNDLE_RESOURCE_RDB_NAME;
43 bmsRdbConfig.dbPath = BundleResourceConstants::BUNDLE_RESOURCE_RDB_PATH;
44 bmsRdbConfig.tableName = BundleResourceConstants::BUNDLE_ICON_RESOURCE_RDB_TABLE_NAME;
45 bmsRdbConfig.createTableSql = std::string(
46 "CREATE TABLE IF NOT EXISTS "
47 + std::string(BundleResourceConstants::BUNDLE_ICON_RESOURCE_RDB_TABLE_NAME)
48 + "(NAME TEXT NOT NULL, USER_ID INTEGER, ICON_TYPE INTEGER, ICON TEXT, "
49 + "FOREGROUND BLOB, BACKGROUND BLOB, PRIMARY KEY (NAME, USER_ID, ICON_TYPE));");
50 rdbDataManager_ = std::make_shared<RdbDataManager>(bmsRdbConfig);
51 rdbDataManager_->CreateTable();
52 }
53
~BundleResourceIconRdb()54 BundleResourceIconRdb::~BundleResourceIconRdb()
55 {
56 }
57
AddResourceIconInfo(const int32_t userId,const IconResourceType type,const ResourceInfo & resourceInfo)58 bool BundleResourceIconRdb::AddResourceIconInfo(const int32_t userId, const IconResourceType type,
59 const ResourceInfo &resourceInfo)
60 {
61 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
62 if (resourceInfo.bundleName_.empty()) {
63 APP_LOGE("failed, bundleName is empty");
64 return false;
65 }
66 APP_LOGD("insert resource key:%{public}s", resourceInfo.GetKey().c_str());
67 NativeRdb::ValuesBucket valuesBucket;
68 valuesBucket.PutString(BundleResourceConstants::NAME, resourceInfo.GetKey());
69 valuesBucket.PutInt(BundleResourceConstants::USER_ID, userId);
70 valuesBucket.PutInt(BundleResourceConstants::ICON_TYPE, static_cast<int32_t>(type));
71 valuesBucket.PutString(BundleResourceConstants::ICON, resourceInfo.icon_);
72 // used for layered icons
73 valuesBucket.PutBlob(BundleResourceConstants::FOREGROUND, resourceInfo.foreground_);
74 valuesBucket.PutBlob(BundleResourceConstants::BACKGROUND, resourceInfo.background_);
75 APP_LOGD("key:%{public}s foreground: %{public}zu, background: %{public}zu", resourceInfo.GetKey().c_str(),
76 resourceInfo.foreground_.size(), resourceInfo.background_.size());
77
78 return rdbDataManager_->InsertData(valuesBucket);
79 }
80
AddResourceIconInfos(const int32_t userId,const IconResourceType type,const std::vector<ResourceInfo> & resourceInfos)81 bool BundleResourceIconRdb::AddResourceIconInfos(const int32_t userId, const IconResourceType type,
82 const std::vector<ResourceInfo> &resourceInfos)
83 {
84 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
85 if (resourceInfos.empty()) {
86 APP_LOGE("failed, resourceInfos is empty");
87 return false;
88 }
89 if (resourceInfos.size() == 1) {
90 return AddResourceIconInfo(userId, type, resourceInfos[0]);
91 }
92 bool ret = true;
93 std::vector<NativeRdb::ValuesBucket> valuesBuckets;
94 for (const auto &info : resourceInfos) {
95 if (info.bundleName_.empty()) {
96 APP_LOGE("failed, bundleName is empty");
97 ret = false;
98 continue;
99 }
100 NativeRdb::ValuesBucket valuesBucket;
101 valuesBucket.PutString(BundleResourceConstants::NAME, info.GetKey());
102 valuesBucket.PutInt(BundleResourceConstants::USER_ID, userId);
103 valuesBucket.PutInt(BundleResourceConstants::ICON_TYPE, static_cast<int32_t>(type));
104 valuesBucket.PutString(BundleResourceConstants::ICON, info.icon_);
105 // used for layered icons
106 valuesBucket.PutBlob(BundleResourceConstants::FOREGROUND, info.foreground_);
107 valuesBucket.PutBlob(BundleResourceConstants::BACKGROUND, info.background_);
108 APP_LOGD("key:%{public}s foreground: %{public}zu, background: %{public}zu", info.GetKey().c_str(),
109 info.foreground_.size(), info.background_.size());
110 valuesBuckets.emplace_back(valuesBucket);
111 }
112 int64_t insertNum = 0;
113 bool insertRet = rdbDataManager_->BatchInsert(insertNum, valuesBuckets);
114 if (!insertRet) {
115 APP_LOGE("BatchInsert failed");
116 return false;
117 }
118 if (valuesBuckets.size() != static_cast<uint64_t>(insertNum)) {
119 APP_LOGE("BatchInsert size not expected");
120 return false;
121 }
122 return ret;
123 }
124
DeleteResourceIconInfo(const std::string & bundleName,const int32_t userId,const int32_t appIndex,const IconResourceType type)125 bool BundleResourceIconRdb::DeleteResourceIconInfo(const std::string &bundleName,
126 const int32_t userId, const int32_t appIndex, const IconResourceType type)
127 {
128 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
129 if (bundleName.empty()) {
130 APP_LOGE("failed, bundleName is empty");
131 return false;
132 }
133 APP_LOGD("need delete resource info, -n %{public}s, -u %{public}d, -i %{public}d, -t %{public}d",
134 bundleName.c_str(), userId, appIndex, static_cast<int32_t>(type));
135 std::string key = bundleName;
136 if (appIndex > 0) {
137 key = std::to_string(appIndex) + BundleResourceConstants::UNDER_LINE + bundleName;
138 }
139 NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_ICON_RESOURCE_RDB_TABLE_NAME);
140 /**
141 * key:
142 * appIndex_bundleName
143 * appIndex_bundleName/moduleName/abilityName
144 */
145 absRdbPredicates.BeginWrap();
146 absRdbPredicates.EqualTo(BundleResourceConstants::NAME, key);
147 absRdbPredicates.Or();
148 absRdbPredicates.BeginsWith(BundleResourceConstants::NAME, key + BundleResourceConstants::SEPARATOR);
149 absRdbPredicates.EndWrap();
150
151 absRdbPredicates.EqualTo(BundleResourceConstants::USER_ID, userId);
152 if (type != IconResourceType::UNKNOWN) {
153 absRdbPredicates.EqualTo(BundleResourceConstants::ICON_TYPE, static_cast<int32_t>(type));
154 }
155 if (!rdbDataManager_->DeleteData(absRdbPredicates)) {
156 APP_LOGW("delete key:%{public}s failed", key.c_str());
157 return false;
158 }
159 return true;
160 }
161
DeleteResourceIconInfos(const std::string & bundleName,const int32_t userId,const IconResourceType type)162 bool BundleResourceIconRdb::DeleteResourceIconInfos(const std::string &bundleName,
163 const int32_t userId, const IconResourceType type)
164 {
165 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
166 if (bundleName.empty()) {
167 APP_LOGE("failed, bundleName is empty");
168 return false;
169 }
170 APP_LOGD("need delete resource info, -n %{public}s, -u %{public}d, -t %{public}d",
171 bundleName.c_str(), userId, static_cast<int32_t>(type));
172 NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_ICON_RESOURCE_RDB_TABLE_NAME);
173 /**
174 * key:
175 * bundleName
176 * bundleName/moduleName/abilityName
177 * appIndex_bundleName
178 * appIndex_bundleName/moduleName/abilityName
179 */
180 absRdbPredicates.BeginWrap();
181 absRdbPredicates.EqualTo(BundleResourceConstants::NAME, bundleName);
182 absRdbPredicates.Or();
183 absRdbPredicates.BeginsWith(BundleResourceConstants::NAME, bundleName + BundleResourceConstants::SEPARATOR);
184 for (int32_t index = ServiceConstants::CLONE_APP_INDEX_MIN;
185 index <= ServiceConstants::CLONE_APP_INDEX_MAX; ++index) {
186 absRdbPredicates.Or();
187 absRdbPredicates.EqualTo(BundleResourceConstants::NAME, std::to_string(index) +
188 BundleResourceConstants::UNDER_LINE + bundleName);
189 absRdbPredicates.Or();
190 absRdbPredicates.BeginsWith(BundleResourceConstants::NAME, std::to_string(index) +
191 BundleResourceConstants::UNDER_LINE + bundleName + BundleResourceConstants::SEPARATOR);
192 }
193 absRdbPredicates.EndWrap();
194
195 if (userId != Constants::UNSPECIFIED_USERID) {
196 absRdbPredicates.EqualTo(BundleResourceConstants::USER_ID, userId);
197 }
198 if (type != IconResourceType::UNKNOWN) {
199 absRdbPredicates.EqualTo(BundleResourceConstants::ICON_TYPE, static_cast<int32_t>(type));
200 }
201 if (!rdbDataManager_->DeleteData(absRdbPredicates)) {
202 APP_LOGW("delete bundleName:%{public}s failed", bundleName.c_str());
203 return false;
204 }
205 return true;
206 }
207
DeleteResourceIconInfos(const std::string & bundleName,const IconResourceType type)208 bool BundleResourceIconRdb::DeleteResourceIconInfos(const std::string &bundleName, const IconResourceType type)
209 {
210 return DeleteResourceIconInfos(bundleName, Constants::UNSPECIFIED_USERID, type);
211 }
212
GetAllResourceIconName(const int32_t userId,std::set<std::string> & resourceNames,const IconResourceType type)213 bool BundleResourceIconRdb::GetAllResourceIconName(const int32_t userId, std::set<std::string> &resourceNames,
214 const IconResourceType type)
215 {
216 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
217 NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_ICON_RESOURCE_RDB_TABLE_NAME);
218 absRdbPredicates.EqualTo(BundleResourceConstants::USER_ID, userId);
219 if (type != IconResourceType::UNKNOWN) {
220 absRdbPredicates.EqualTo(BundleResourceConstants::ICON_TYPE, static_cast<int32_t>(type));
221 }
222 auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
223 if (absSharedResultSet == nullptr) {
224 APP_LOGE("QueryByStep failed");
225 return false;
226 }
227 ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
228
229 auto ret = absSharedResultSet->GoToFirstRow();
230 if (ret != NativeRdb::E_OK) {
231 APP_LOGE("GoToFirstRow failed, ret %{public}d", ret);
232 return false;
233 }
234 do {
235 std::string name;
236 std::string resourceName;
237 ret = absSharedResultSet->GetString(BundleResourceConstants::INDEX_NAME, name);
238 if (ret != NativeRdb::E_OK) {
239 APP_LOGE("GetString name failed, ret %{public}d", ret);
240 return false;
241 }
242 ParseNameToResourceName(name, resourceName);
243 resourceNames.insert(resourceName);
244 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
245 APP_LOGI_NOFUNC("end");
246 return true;
247 }
248
ParseNameToResourceName(const std::string & name,std::string & resourceName)249 void BundleResourceIconRdb::ParseNameToResourceName(const std::string &name, std::string &resourceName)
250 {
251 resourceName = name;
252 // clone bundle no need to add
253 auto pos = name.find_first_of(BundleResourceConstants::UNDER_LINE);
254 if (pos != std::string::npos) {
255 int32_t appIndex = 0;
256 if (!OHOS::StrToInt(name.substr(0, pos), appIndex)) {
257 return;
258 }
259 resourceName = name.substr(pos + 1);
260 }
261 }
262
GetResourceIconInfos(const std::string & bundleName,const int32_t userId,const int32_t appIndex,const uint32_t resourceFlag,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfos,const IconResourceType type)263 bool BundleResourceIconRdb::GetResourceIconInfos(const std::string &bundleName,
264 const int32_t userId, const int32_t appIndex, const uint32_t resourceFlag,
265 std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfos,
266 const IconResourceType type)
267 {
268 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
269 APP_LOGI_NOFUNC("icon rdb get resource icon start -n %{public}s -i %{public}d", bundleName.c_str(), appIndex);
270 if (bundleName.empty()) {
271 APP_LOGE("bundleName is empty");
272 return false;
273 }
274 ResourceInfo resourceInfo;
275 resourceInfo.bundleName_ = bundleName;
276 resourceInfo.appIndex_ = appIndex;
277 NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_ICON_RESOURCE_RDB_TABLE_NAME);
278 // bundleName or bundleName/moduleName/abilityName
279 absRdbPredicates.BeginWrap();
280 absRdbPredicates.EqualTo(BundleResourceConstants::NAME, resourceInfo.GetKey());
281 absRdbPredicates.Or();
282 absRdbPredicates.BeginsWith(BundleResourceConstants::NAME, resourceInfo.GetKey() +
283 BundleResourceConstants::SEPARATOR);
284 absRdbPredicates.EndWrap();
285
286 absRdbPredicates.EqualTo(BundleResourceConstants::USER_ID, userId);
287 if (type != IconResourceType::UNKNOWN) {
288 absRdbPredicates.EqualTo(BundleResourceConstants::ICON_TYPE, static_cast<int32_t>(type));
289 }
290
291 auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
292 if (absSharedResultSet == nullptr) {
293 APP_LOGE("QueryByStep failed bundleName %{public}s failed", bundleName.c_str());
294 return false;
295 }
296 ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
297 auto ret = absSharedResultSet->GoToFirstRow();
298 if (ret != NativeRdb::E_OK) {
299 APP_LOGD("bundleName %{public}s GoToFirstRow failed, ret %{public}d", bundleName.c_str(), ret);
300 return false;
301 }
302
303 do {
304 LauncherAbilityResourceInfo resourceInfo;
305 IconResourceType type;
306 if (ConvertToLauncherAbilityResourceInfo(absSharedResultSet, resourceFlag, resourceInfo, type)) {
307 InnerProcessResourceIconInfos(resourceInfo, type, userId, launcherAbilityResourceInfos);
308 }
309 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
310
311 APP_LOGI_NOFUNC("icon rdb get resource icon end -n %{public}s -i %{public}d", bundleName.c_str(), appIndex);
312 return !launcherAbilityResourceInfos.empty();
313 }
314
GetAllResourceIconInfo(const int32_t userId,const uint32_t resourceFlag,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfos)315 bool BundleResourceIconRdb::GetAllResourceIconInfo(const int32_t userId, const uint32_t resourceFlag,
316 std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfos)
317 {
318 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
319 APP_LOGI("start get all launcher resource");
320 NativeRdb::AbsRdbPredicates absRdbPredicates(BundleResourceConstants::BUNDLE_ICON_RESOURCE_RDB_TABLE_NAME);
321 absRdbPredicates.EqualTo(BundleResourceConstants::USER_ID, userId);
322 auto absSharedResultSet = rdbDataManager_->QueryByStep(absRdbPredicates);
323 if (absSharedResultSet == nullptr) {
324 APP_LOGE("absSharedResultSet nullptr");
325 return false;
326 }
327
328 ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
329 auto ret = absSharedResultSet->GoToFirstRow();
330 if (ret != NativeRdb::E_OK) {
331 APP_LOGE("GoToFirstRow failed, ret %{public}d", ret);
332 return false;
333 }
334
335 do {
336 LauncherAbilityResourceInfo resourceInfo;
337 IconResourceType type;
338 if (ConvertToLauncherAbilityResourceInfo(absSharedResultSet, resourceFlag, resourceInfo, type)) {
339 InnerProcessResourceIconInfos(resourceInfo, type, userId, launcherAbilityResourceInfos);
340 }
341 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
342
343 APP_LOGI_NOFUNC("end get all launcher resource");
344 return !launcherAbilityResourceInfos.empty();
345 }
346
ConvertToLauncherAbilityResourceInfo(const std::shared_ptr<NativeRdb::ResultSet> & absSharedResultSet,const uint32_t resourceFlag,LauncherAbilityResourceInfo & launcherAbilityResourceInfo,IconResourceType & iconType)347 bool BundleResourceIconRdb::ConvertToLauncherAbilityResourceInfo(
348 const std::shared_ptr<NativeRdb::ResultSet> &absSharedResultSet,
349 const uint32_t resourceFlag,
350 LauncherAbilityResourceInfo &launcherAbilityResourceInfo,
351 IconResourceType &iconType)
352 {
353 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
354 if (absSharedResultSet == nullptr) {
355 APP_LOGE("absSharedResultSet is nullptr");
356 return false;
357 }
358 std::string key;
359 auto ret = absSharedResultSet->GetString(INDEX_NAME, key);
360 CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString name failed, ret: %{public}d");
361 ParseKey(key, launcherAbilityResourceInfo);
362
363 bool getIcon = ((resourceFlag & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON)) ==
364 static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON)) ||
365 ((resourceFlag & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL)) ==
366 static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL));
367 if (getIcon) {
368 ret = absSharedResultSet->GetString(INDEX_ICON, launcherAbilityResourceInfo.icon);
369 CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetString label icon, ret: %{public}d");
370 }
371
372 bool getDrawable = (resourceFlag & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR))
373 == static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR);
374 if (getDrawable) {
375 ret = absSharedResultSet->GetBlob(INDEX_FOREGROUND, launcherAbilityResourceInfo.foreground);
376 CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetBlob foreground, ret: %{public}d");
377
378 ret = absSharedResultSet->GetBlob(INDEX_BACKGROUND, launcherAbilityResourceInfo.background);
379 CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetBlob background, ret: %{public}d");
380 }
381 int32_t type = 0;
382 ret = absSharedResultSet->GetInt(INDEX_ICON_TYPE, type);
383 CHECK_RDB_RESULT_RETURN_IF_FAIL(ret, "GetInt iconType, ret: %{public}d");
384 iconType = static_cast<IconResourceType>(type);
385
386 return true;
387 }
388
ParseKey(const std::string & key,LauncherAbilityResourceInfo & launcherAbilityResourceInfo)389 void BundleResourceIconRdb::ParseKey(const std::string &key,
390 LauncherAbilityResourceInfo &launcherAbilityResourceInfo)
391 {
392 ResourceInfo info;
393 info.ParseKey(key);
394 launcherAbilityResourceInfo.bundleName = info.bundleName_;
395 launcherAbilityResourceInfo.moduleName = info.moduleName_;
396 launcherAbilityResourceInfo.abilityName = info.abilityName_;
397 launcherAbilityResourceInfo.appIndex = info.appIndex_;
398 }
399
GetIsOnlineTheme(const int32_t userId)400 bool BundleResourceIconRdb::GetIsOnlineTheme(const int32_t userId)
401 {
402 std::shared_lock<ffrt::shared_mutex> lock(isOnlineThemeMutex_);
403 auto iter = isOnlineThemeMap_.find(userId);
404 if (iter == isOnlineThemeMap_.end()) {
405 return false;
406 }
407 return iter->second;
408 }
409
SetIsOnlineTheme(const int32_t userId,bool isOnlineTheme)410 void BundleResourceIconRdb::SetIsOnlineTheme(const int32_t userId, bool isOnlineTheme)
411 {
412 std::unique_lock<ffrt::shared_mutex> lock(isOnlineThemeMutex_);
413 isOnlineThemeMap_[userId] = isOnlineTheme;
414 }
415
InnerProcessResourceIconInfos(const LauncherAbilityResourceInfo & resourceInfo,const IconResourceType type,const int32_t userId,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfos)416 void BundleResourceIconRdb::InnerProcessResourceIconInfos(const LauncherAbilityResourceInfo &resourceInfo,
417 const IconResourceType type, const int32_t userId,
418 std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfos)
419 {
420 if (!resourceInfo.abilityName.empty() && GetIsOnlineTheme(userId)) {
421 launcherAbilityResourceInfos.push_back(resourceInfo);
422 return;
423 }
424 auto iter = std::find_if(launcherAbilityResourceInfos.begin(), launcherAbilityResourceInfos.end(),
425 [resourceInfo](const LauncherAbilityResourceInfo info) {
426 return (resourceInfo.bundleName == info.bundleName) && (resourceInfo.appIndex == info.appIndex);
427 });
428 // not exist
429 if (iter == launcherAbilityResourceInfos.end()) {
430 launcherAbilityResourceInfos.push_back(resourceInfo);
431 return;
432 }
433 // if exist, need to process theme or dynamic icon
434 if (((type == IconResourceType::THEME_ICON) && GetIsOnlineTheme(userId)) ||
435 ((type == IconResourceType::DYNAMIC_ICON) && !GetIsOnlineTheme(userId))) {
436 for (auto iter = launcherAbilityResourceInfos.begin(); iter != launcherAbilityResourceInfos.end();) {
437 if ((iter->bundleName == resourceInfo.bundleName) && (iter->appIndex == resourceInfo.appIndex)) {
438 iter = launcherAbilityResourceInfos.erase(iter);
439 } else {
440 ++iter;
441 }
442 }
443 launcherAbilityResourceInfos.push_back(resourceInfo);
444 }
445 }
446 } // AppExecFwk
447 } // OHOS
448