• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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