1 /*
2  * Copyright (c) 2023 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_manager.h"
17 
18 #include "bms_extension_client.h"
19 #include "bundle_common_event_mgr.h"
20 #include "bundle_util.h"
21 #include "bundle_resource_parser.h"
22 #include "bundle_resource_process.h"
23 #include "event_report.h"
24 #include "thread_pool.h"
25 
26 namespace OHOS {
27 namespace AppExecFwk {
28 namespace {
29 constexpr const char* GLOBAL_RESOURCE_BUNDLE_NAME = "ohos.global.systemres";
30 constexpr int32_t MAX_TASK_NUMBER = 2;
31 const std::string THREAD_POOL_NAME = "BundleResourceThreadPool";
32 constexpr int32_t CHECK_INTERVAL = 30; // 30ms
33 constexpr const char* FOUNDATION_PROCESS_NAME = "foundation";
34 constexpr int32_t SCENE_ID_UPDATE_RESOURCE = 1 << 1;
35 const std::string SYSTEM_THEME_PATH = "/data/service/el1/public/themes/";
36 const std::string THEME_ICONS_A = "/a/app/icons/";
37 const std::string THEME_ICONS_B = "/b/app/icons/";
38 const std::string INNER_UNDER_LINE = "_";
39 const std::string THEME_ICONS_A_FLAG = "/a/app/flag";
40 const std::string THEME_ICONS_B_FLAG = "/b/app/flag";
41 }
42 
BundleResourceManager()43 BundleResourceManager::BundleResourceManager()
44 {
45     bundleResourceRdb_ = std::make_shared<BundleResourceRdb>();
46 }
47 
~BundleResourceManager()48 BundleResourceManager::~BundleResourceManager()
49 {
50 }
51 
AddResourceInfoByBundleName(const std::string & bundleName,const int32_t userId)52 bool BundleResourceManager::AddResourceInfoByBundleName(const std::string &bundleName, const int32_t userId)
53 {
54     APP_LOGD("start, bundleName:%{public}s", bundleName.c_str());
55     std::vector<ResourceInfo> resourceInfos;
56     if (!BundleResourceProcess::GetResourceInfoByBundleName(bundleName, userId, resourceInfos)) {
57         APP_LOGE("bundleName %{public}s GetResourceInfoByBundleName failed", bundleName.c_str());
58         return false;
59     }
60     DeleteNotExistResourceInfo(bundleName, 0, resourceInfos);
61 
62     if (!AddResourceInfos(userId, resourceInfos)) {
63         APP_LOGE("error, bundleName:%{public}s", bundleName.c_str());
64         return false;
65     }
66     if (!resourceInfos.empty() && !resourceInfos[0].appIndexes_.empty()) {
67         for (const int32_t appIndex : resourceInfos[0].appIndexes_) {
68             DeleteNotExistResourceInfo(bundleName, appIndex, resourceInfos);
69             if (!AddCloneBundleResourceInfo(resourceInfos[0].bundleName_, appIndex)) {
70                 APP_LOGW("bundleName:%{public}s add clone resource failed", bundleName.c_str());
71             }
72         }
73     }
74     APP_LOGD("success, bundleName:%{public}s", bundleName.c_str());
75     return true;
76 }
77 
DeleteNotExistResourceInfo(const std::string & bundleName,const int32_t appIndex,const std::vector<ResourceInfo> & resourceInfos)78 void BundleResourceManager::DeleteNotExistResourceInfo(
79     const std::string &bundleName, const int32_t appIndex, const std::vector<ResourceInfo> &resourceInfos)
80 {
81     // get current rdb resource
82     std::vector<std::string> existResourceName;
83     if (bundleResourceRdb_->GetResourceNameByBundleName(bundleName, appIndex, existResourceName) &&
84         !existResourceName.empty()) {
85         for (const auto &key : existResourceName) {
86             auto it = std::find_if(resourceInfos.begin(), resourceInfos.end(),
87                 [&key](const ResourceInfo &info) {
88                 return info.GetKey() == key;
89             });
90             if (it == resourceInfos.end()) {
91                 bundleResourceRdb_->DeleteResourceInfo(key);
92             }
93         }
94     }
95 }
96 
AddResourceInfoByAbility(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const int32_t userId)97 bool BundleResourceManager::AddResourceInfoByAbility(const std::string &bundleName, const std::string &moduleName,
98     const std::string &abilityName, const int32_t userId)
99 {
100     APP_LOGD("start, bundleName:%{public}s", bundleName.c_str());
101     ResourceInfo resourceInfo;
102     if (!BundleResourceProcess::GetLauncherResourceInfoByAbilityName(bundleName, moduleName, abilityName,
103         userId, resourceInfo)) {
104         APP_LOGE("bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s failed",
105             bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
106         return false;
107     }
108     if (!AddResourceInfo(userId, resourceInfo)) {
109         APP_LOGE("error, bundleName %{public}s, moduleName %{public}s, abilityName %{public}s failed",
110             bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
111         return false;
112     }
113     APP_LOGD("success, bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s failed",
114         bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
115     return true;
116 }
117 
AddAllResourceInfo(const int32_t userId,const uint32_t type,const int32_t oldUserId)118 bool BundleResourceManager::AddAllResourceInfo(const int32_t userId, const uint32_t type, const int32_t oldUserId)
119 {
120     EventReport::SendCpuSceneEvent(FOUNDATION_PROCESS_NAME, SCENE_ID_UPDATE_RESOURCE);
121     ++currentTaskNum_;
122     uint32_t tempTaskNum = currentTaskNum_;
123     std::lock_guard<std::mutex> guard(mutex_);
124     APP_LOGI("bundle resource hold mutex");
125     std::map<std::string, std::vector<ResourceInfo>> resourceInfosMap;
126     if (!BundleResourceProcess::GetAllResourceInfo(userId, resourceInfosMap)) {
127         APP_LOGE("GetAllResourceInfo failed userId %{public}d", userId);
128         return false;
129     }
130     if (tempTaskNum != currentTaskNum_) {
131         APP_LOGI("need stop current task, new first");
132         return false;
133     }
134     if (!AddResourceInfosByMap(resourceInfosMap, tempTaskNum, type, userId, oldUserId)) {
135         APP_LOGE("add all resource info failed, userId:%{public}d", userId);
136         return false;
137     }
138     // process clone bundle resource info
139     for (const auto &item : resourceInfosMap) {
140         if (!item.second.empty() && !item.second[0].appIndexes_.empty()) {
141             APP_LOGI("start process bundle:%{public}s clone resource info", item.first.c_str());
142             for (const int32_t appIndex : item.second[0].appIndexes_) {
143                 UpdateCloneBundleResourceInfo(item.first, appIndex, type);
144             }
145         }
146     }
147     SendBundleResourcesChangedEvent(userId, type);
148     std::string systemState;
149     if (bundleResourceRdb_->GetCurrentSystemState(systemState)) {
150         APP_LOGI_NOFUNC("current resource rdb system state:%{public}s", systemState.c_str());
151     }
152     APP_LOGI_NOFUNC("add all resource end");
153     return true;
154 }
155 
DeleteAllResourceInfo()156 bool BundleResourceManager::DeleteAllResourceInfo()
157 {
158     return bundleResourceRdb_->DeleteAllResourceInfo();
159 }
160 
AddResourceInfo(const int32_t userId,ResourceInfo & resourceInfo)161 bool BundleResourceManager::AddResourceInfo(const int32_t userId, ResourceInfo &resourceInfo)
162 {
163     // need to parse label and icon
164     BundleResourceParser parser;
165     if (!parser.ParseResourceInfo(userId, resourceInfo)) {
166         APP_LOGW("key %{public}s ParseResourceInfo failed", resourceInfo.GetKey().c_str());
167         BundleResourceInfo bundleResourceInfo;
168         if (GetBundleResourceInfo(resourceInfo.bundleName_,
169             static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL), bundleResourceInfo)) {
170             // default ability label and icon
171             resourceInfo.label_ = resourceInfo.label_.empty() ? bundleResourceInfo.label : resourceInfo.label_;
172             resourceInfo.icon_ = resourceInfo.icon_.empty() ? bundleResourceInfo.icon : resourceInfo.icon_;
173             resourceInfo.foreground_ = resourceInfo.foreground_.empty() ? bundleResourceInfo.foreground :
174                 resourceInfo.foreground_;
175             resourceInfo.background_ = resourceInfo.background_.empty() ? bundleResourceInfo.background :
176                 resourceInfo.background_;
177         }
178         ProcessResourceInfoWhenParseFailed(resourceInfo);
179     }
180     return bundleResourceRdb_->AddResourceInfo(resourceInfo);
181 }
182 
AddResourceInfos(const int32_t userId,std::vector<ResourceInfo> & resourceInfos)183 bool BundleResourceManager::AddResourceInfos(const int32_t userId, std::vector<ResourceInfo> &resourceInfos)
184 {
185     if (resourceInfos.empty()) {
186         APP_LOGE("resourceInfos is empty");
187         return false;
188     }
189     // need to parse label and icon
190     BundleResourceParser parser;
191     if (!parser.ParseResourceInfos(userId, resourceInfos)) {
192         APP_LOGW_NOFUNC("key:%{public}s Parse failed, need to modify label and icon",
193             resourceInfos[0].GetKey().c_str());
194         ProcessResourceInfoWhenParseFailed(resourceInfos[0]);
195     }
196     return bundleResourceRdb_->AddResourceInfos(resourceInfos);
197 }
198 
InnerProcessResourceInfoByResourceUpdateType(std::map<std::string,std::vector<ResourceInfo>> & resourceInfosMap,const uint32_t type,const int32_t userId,const int32_t oldUserId)199 void BundleResourceManager::InnerProcessResourceInfoByResourceUpdateType(
200     std::map<std::string, std::vector<ResourceInfo>> &resourceInfosMap,
201     const uint32_t type, const int32_t userId, const int32_t oldUserId)
202 {
203     APP_LOGI("current resource update, code:%{public}u", type);
204     switch (type) {
205         case static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_LANGUE_CHANGE) : {
206             InnerProcessResourceInfoBySystemLanguageChanged(resourceInfosMap);
207             break;
208         }
209         case static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_THEME_CHANGE) : {
210             InnerProcessResourceInfoBySystemThemeChanged(resourceInfosMap, userId);
211             break;
212         }
213         case static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_USER_ID_CHANGE) : {
214             InnerProcessResourceInfoByUserIdChanged(resourceInfosMap, userId, oldUserId);
215             break;
216         }
217         default: {
218             break;
219         }
220     }
221 }
222 
InnerProcessResourceInfoBySystemLanguageChanged(std::map<std::string,std::vector<ResourceInfo>> & resourceInfosMap)223 void BundleResourceManager::InnerProcessResourceInfoBySystemLanguageChanged(
224     std::map<std::string, std::vector<ResourceInfo>> &resourceInfosMap)
225 {
226     for (auto iter = resourceInfosMap.begin(); iter != resourceInfosMap.end(); ++iter) {
227         for (auto &resourceInfo : iter->second) {
228             resourceInfo.iconNeedParse_ = false;
229         }
230     }
231 }
232 
InnerProcessResourceInfoBySystemThemeChanged(std::map<std::string,std::vector<ResourceInfo>> & resourceInfosMap,const int32_t userId)233 void BundleResourceManager::InnerProcessResourceInfoBySystemThemeChanged(
234     std::map<std::string, std::vector<ResourceInfo>> &resourceInfosMap,
235     const int32_t userId)
236 {
237     // judge whether the bundle theme exists
238     for (auto iter = resourceInfosMap.begin(); iter != resourceInfosMap.end();) {
239         if (!BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_A + iter->first) &&
240             !BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_B + iter->first)) {
241             iter = resourceInfosMap.erase(iter);
242         } else {
243             ++iter;
244         }
245     }
246     // process labelNeedParse_
247     for (auto iter = resourceInfosMap.begin(); iter != resourceInfosMap.end(); ++iter) {
248         ProcessResourceInfoNoNeedToParseOtherIcon(iter->second);
249     }
250 }
251 
InnerProcessResourceInfoByUserIdChanged(std::map<std::string,std::vector<ResourceInfo>> & resourceInfosMap,const int32_t userId,const int32_t oldUserId)252 void BundleResourceManager::InnerProcessResourceInfoByUserIdChanged(
253     std::map<std::string, std::vector<ResourceInfo>> &resourceInfosMap,
254     const int32_t userId, const int32_t oldUserId)
255 {
256     APP_LOGI("start process switch oldUserId:%{public}d to userId:%{public}d", oldUserId, userId);
257     for (auto iter = resourceInfosMap.begin(); iter != resourceInfosMap.end();) {
258         // first, check oldUserId whether exist theme, if exist then need parse again
259         bool isOldUserExistTheme = InnerProcessWhetherThemeExist(iter->first, oldUserId);
260         bool isNewUserExistTheme = InnerProcessWhetherThemeExist(iter->first, userId);
261         if (!isOldUserExistTheme && !isNewUserExistTheme) {
262             APP_LOGD("bundleName:%{public}s not exist theme", iter->first.c_str());
263             iter = resourceInfosMap.erase(iter);
264             continue;
265         }
266         APP_LOGI("bundleName:%{public}s oldUser:%{public}d or newUser:%{public}d exist theme",
267             iter->first.c_str(), oldUserId, userId);
268         if (isNewUserExistTheme) {
269             ProcessResourceInfoNoNeedToParseOtherIcon(iter->second);
270         } else {
271             for (auto &resource : iter->second) {
272                 resource.labelNeedParse_ = false;
273                 resource.label_ = Constants::EMPTY_STRING;
274             }
275         }
276         ++iter;
277     }
278 }
279 
DeleteNotExistResourceInfo(const std::map<std::string,std::vector<ResourceInfo>> & resourceInfosMap,const std::vector<std::string> & existResourceNames)280 void BundleResourceManager::DeleteNotExistResourceInfo(
281     const std::map<std::string, std::vector<ResourceInfo>> &resourceInfosMap,
282     const std::vector<std::string> &existResourceNames)
283 {
284     // delete not exist resource
285     for (const auto &name : existResourceNames) {
286         if (resourceInfosMap.find(name) == resourceInfosMap.end()) {
287             ResourceInfo resourceInfo;
288             resourceInfo.ParseKey(name);
289             // main bundle not exist
290             if (resourceInfo.appIndex_ == 0) {
291                 DeleteResourceInfo(name);
292                 continue;
293             }
294             auto iter = resourceInfosMap.find(resourceInfo.bundleName_);
295             // main bundle not exist
296             if ((iter == resourceInfosMap.end()) || (iter->second.empty())) {
297                 DeleteResourceInfo(name);
298                 continue;
299             }
300             // clone bundle appIndex not exist
301             if (std::find(iter->second[0].appIndexes_.begin(), iter->second[0].appIndexes_.end(),
302                 resourceInfo.appIndex_) == iter->second[0].appIndexes_.end()) {
303                 DeleteResourceInfo(name);
304             }
305         }
306     }
307 }
308 
InnerProcessWhetherThemeExist(const std::string & bundleName,const int32_t userId)309 bool BundleResourceManager::InnerProcessWhetherThemeExist(const std::string &bundleName, const int32_t userId)
310 {
311     if (BundleUtil::IsExistFileNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_A_FLAG)) {
312         return BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_A + bundleName);
313     }
314     return BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_B + bundleName);
315 }
316 
AddResourceInfosByMap(std::map<std::string,std::vector<ResourceInfo>> & resourceInfosMap,const uint32_t tempTaskNumber,const uint32_t type,const int32_t userId,const int32_t oldUserId)317 bool BundleResourceManager::AddResourceInfosByMap(
318     std::map<std::string, std::vector<ResourceInfo>> &resourceInfosMap,
319     const uint32_t tempTaskNumber,
320     const uint32_t type,
321     const int32_t userId,
322     const int32_t oldUserId)
323 {
324     if (resourceInfosMap.empty()) {
325         APP_LOGE("resourceInfosMap is empty");
326         return false;
327     }
328     InnerProcessResourceInfoByResourceUpdateType(resourceInfosMap, type, userId, oldUserId);
329     if (resourceInfosMap.empty()) {
330         APP_LOGI("resourceInfosMap is empty, no need to parse");
331         return true;
332     }
333     std::shared_ptr<ThreadPool> threadPool = std::make_shared<ThreadPool>(THREAD_POOL_NAME);
334     if (threadPool == nullptr) {
335         APP_LOGE("threadPool is nullptr");
336         return false;
337     }
338     threadPool->Start(MAX_TASK_NUMBER);
339     threadPool->SetMaxTaskNum(MAX_TASK_NUMBER);
340 
341     for (const auto &item : resourceInfosMap) {
342         if (tempTaskNumber != currentTaskNum_) {
343             APP_LOGI("need stop current task, new first");
344             threadPool->Stop();
345             return false;
346         }
347         std::string bundleName = item.first;
348         auto task = [userId, bundleName, &resourceInfosMap, this]() {
349             if (resourceInfosMap.find(bundleName) == resourceInfosMap.end()) {
350                 APP_LOGE("bundleName %{public}s not exist", bundleName.c_str());
351                 return;
352             }
353             std::vector<ResourceInfo> resourceInfos = resourceInfosMap[bundleName];
354             BundleResourceParser parser;
355             parser.ParseResourceInfos(userId, resourceInfos);
356             bundleResourceRdb_->UpdateResourceForSystemStateChanged(resourceInfos);
357         };
358         threadPool->AddTask(task);
359     }
360     while (threadPool->GetCurTaskNum() > 0) {
361         std::this_thread::sleep_for(std::chrono::milliseconds(CHECK_INTERVAL));
362     }
363     threadPool->Stop();
364     APP_LOGI("all task end resource size %{public}zu", resourceInfosMap.size());
365     return true;
366 }
367 
ProcessResourceInfo(const std::vector<ResourceInfo> & resourceInfos,ResourceInfo & resourceInfo)368 void BundleResourceManager::ProcessResourceInfo(
369     const std::vector<ResourceInfo> &resourceInfos, ResourceInfo &resourceInfo)
370 {
371     if (resourceInfo.label_.empty()) {
372         resourceInfo.label_ = resourceInfo.bundleName_;
373     }
374     if (resourceInfo.icon_.empty()) {
375         if (!resourceInfos.empty() && !resourceInfos[0].icon_.empty()) {
376             resourceInfo.icon_ = resourceInfos[0].icon_;
377             resourceInfo.foreground_ = resourceInfos[0].foreground_;
378             resourceInfo.background_ = resourceInfos[0].background_;
379         } else {
380             ProcessResourceInfoWhenParseFailed(resourceInfo);
381         }
382     }
383 }
384 
DeleteResourceInfo(const std::string & key)385 bool BundleResourceManager::DeleteResourceInfo(const std::string &key)
386 {
387     return bundleResourceRdb_->DeleteResourceInfo(key);
388 }
389 
GetAllResourceName(std::vector<std::string> & keyNames)390 bool BundleResourceManager::GetAllResourceName(std::vector<std::string> &keyNames)
391 {
392     return bundleResourceRdb_->GetAllResourceName(keyNames);
393 }
394 
GetBundleResourceInfo(const std::string & bundleName,const uint32_t flags,BundleResourceInfo & bundleResourceInfo,int32_t appIndex)395 bool BundleResourceManager::GetBundleResourceInfo(const std::string &bundleName, const uint32_t flags,
396     BundleResourceInfo &bundleResourceInfo, int32_t appIndex)
397 {
398     APP_LOGD("start, bundleName:%{public}s", bundleName.c_str());
399     uint32_t resourceFlags = CheckResourceFlags(flags);
400     if (bundleResourceRdb_->GetBundleResourceInfo(bundleName, resourceFlags, bundleResourceInfo, appIndex)) {
401         APP_LOGD("success, bundleName:%{public}s", bundleName.c_str());
402         return true;
403     }
404     auto bmsExtensionClient = std::make_shared<BmsExtensionClient>();
405     ErrCode ret = bmsExtensionClient->GetBundleResourceInfo(bundleName, resourceFlags, bundleResourceInfo, appIndex);
406     if (ret == ERR_OK) {
407         APP_LOGD("success, bundleName:%{public}s", bundleName.c_str());
408         return true;
409     }
410     APP_LOGE_NOFUNC("%{public}s not exist in resource rdb", bundleName.c_str());
411     return false;
412 }
413 
GetLauncherAbilityResourceInfo(const std::string & bundleName,const uint32_t flags,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfo,const int32_t appIndex)414 bool BundleResourceManager::GetLauncherAbilityResourceInfo(const std::string &bundleName, const uint32_t flags,
415     std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfo, const int32_t appIndex)
416 {
417     APP_LOGD("start, bundleName:%{public}s", bundleName.c_str());
418     uint32_t resourceFlags = CheckResourceFlags(flags);
419     if (bundleResourceRdb_->GetLauncherAbilityResourceInfo(bundleName, resourceFlags,
420         launcherAbilityResourceInfo, appIndex)) {
421         APP_LOGD("success, bundleName:%{public}s", bundleName.c_str());
422         return true;
423     }
424     auto bmsExtensionClient = std::make_shared<BmsExtensionClient>();
425     ErrCode ret = bmsExtensionClient->GetLauncherAbilityResourceInfo(bundleName, resourceFlags,
426         launcherAbilityResourceInfo, appIndex);
427     if (ret == ERR_OK) {
428         APP_LOGD("success, bundleName:%{public}s", bundleName.c_str());
429         return true;
430     }
431     APP_LOGE_NOFUNC("%{public}s not exist in resource rdb", bundleName.c_str());
432     return false;
433 }
434 
GetAllBundleResourceInfo(const uint32_t flags,std::vector<BundleResourceInfo> & bundleResourceInfos)435 bool BundleResourceManager::GetAllBundleResourceInfo(const uint32_t flags,
436     std::vector<BundleResourceInfo> &bundleResourceInfos)
437 {
438     APP_LOGD("start");
439     uint32_t resourceFlags = CheckResourceFlags(flags);
440     return bundleResourceRdb_->GetAllBundleResourceInfo(resourceFlags, bundleResourceInfos);
441 }
442 
GetAllLauncherAbilityResourceInfo(const uint32_t flags,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfos)443 bool BundleResourceManager::GetAllLauncherAbilityResourceInfo(const uint32_t flags,
444     std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfos)
445 {
446     APP_LOGD("start");
447     uint32_t resourceFlags = CheckResourceFlags(flags);
448     return bundleResourceRdb_->GetAllLauncherAbilityResourceInfo(resourceFlags, launcherAbilityResourceInfos);
449 }
450 
CheckResourceFlags(const uint32_t flags)451 uint32_t BundleResourceManager::CheckResourceFlags(const uint32_t flags)
452 {
453     APP_LOGD("flags:%{public}u", flags);
454     if (((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL)) ==
455         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL)) ||
456         ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL)) ==
457         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL)) ||
458         ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON)) ==
459         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON)) ||
460         ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR)) ==
461         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR))) {
462         return flags;
463     }
464     APP_LOGD("illegal flags");
465     return flags | static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL);
466 }
467 
ProcessResourceInfoWhenParseFailed(ResourceInfo & resourceInfo)468 void BundleResourceManager::ProcessResourceInfoWhenParseFailed(ResourceInfo &resourceInfo)
469 {
470     APP_LOGI("start, bundleName:%{public}s", resourceInfo.bundleName_.c_str());
471     if (resourceInfo.label_.empty()) {
472         resourceInfo.label_ = resourceInfo.bundleName_;
473     }
474     if (resourceInfo.bundleName_ == GLOBAL_RESOURCE_BUNDLE_NAME) {
475         APP_LOGE("%{public}s default resource parse failed", resourceInfo.bundleName_.c_str());
476         return;
477     }
478     if (resourceInfo.icon_.empty()) {
479         GetDefaultIcon(resourceInfo);
480     }
481 }
482 
SaveResourceInfos(std::vector<ResourceInfo> & resourceInfos)483 bool BundleResourceManager::SaveResourceInfos(std::vector<ResourceInfo> &resourceInfos)
484 {
485     if (resourceInfos.empty()) {
486         APP_LOGE("resourceInfos is empty");
487         return false;
488     }
489     return bundleResourceRdb_->AddResourceInfos(resourceInfos);
490 }
491 
GetDefaultIcon(ResourceInfo & resourceInfo)492 void BundleResourceManager::GetDefaultIcon(ResourceInfo &resourceInfo)
493 {
494     BundleResourceInfo bundleResourceInfo;
495     if (!GetBundleResourceInfo(GLOBAL_RESOURCE_BUNDLE_NAME,
496         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_ICON) |
497         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR),
498         bundleResourceInfo)) {
499         APP_LOGE("get default icon failed");
500         return;
501     }
502     resourceInfo.icon_ = bundleResourceInfo.icon;
503     resourceInfo.foreground_ = bundleResourceInfo.foreground;
504     resourceInfo.background_ = bundleResourceInfo.background;
505 }
506 
SendBundleResourcesChangedEvent(const int32_t userId,const uint32_t type)507 void BundleResourceManager::SendBundleResourcesChangedEvent(const int32_t userId, const uint32_t type)
508 {
509     APP_LOGI("send bundleResource event, userId:%{public}d type:%{public}u", userId, type);
510     std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
511     commonEventMgr->NotifyBundleResourcesChanged(userId, type);
512 }
513 
GetTargetBundleName(const std::string & bundleName,std::string & targetBundleName)514 void BundleResourceManager::GetTargetBundleName(const std::string &bundleName, std::string &targetBundleName)
515 {
516     APP_LOGD("start");
517     BundleResourceProcess::GetTargetBundleName(bundleName, targetBundleName);
518 }
519 
UpdateBundleIcon(const std::string & bundleName,ResourceInfo & resourceInfo)520 bool BundleResourceManager::UpdateBundleIcon(const std::string &bundleName, ResourceInfo &resourceInfo)
521 {
522     APP_LOGI("bundleName:%{public}s update icon", bundleName.c_str());
523     std::vector<ResourceInfo> resourceInfos;
524     BundleResourceInfo bundleResourceInfo;
525     if (!GetBundleResourceInfo(bundleName,
526         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL),
527         bundleResourceInfo)) {
528         APP_LOGW("GetBundleResourceInfo failed %{public}s", bundleName.c_str());
529     } else {
530         resourceInfo.bundleName_ = bundleResourceInfo.bundleName;
531         resourceInfo.moduleName_ = Constants::EMPTY_STRING;
532         resourceInfo.abilityName_ = Constants::EMPTY_STRING;
533         resourceInfo.label_ = bundleResourceInfo.label;
534         resourceInfos.emplace_back(resourceInfo);
535     }
536 
537     std::vector<LauncherAbilityResourceInfo> launcherAbilityResourceInfos;
538     if (!GetLauncherAbilityResourceInfo(bundleName,
539         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL),
540         launcherAbilityResourceInfos)) {
541         APP_LOGW("GetLauncherAbilityResourceInfo failed %{public}s",
542             bundleName.c_str());
543     } else {
544         for (const auto &launcherAbilityResourceInfo : launcherAbilityResourceInfos) {
545             resourceInfo.bundleName_ = launcherAbilityResourceInfo.bundleName;
546             resourceInfo.abilityName_ = launcherAbilityResourceInfo.abilityName;
547             resourceInfo.moduleName_ = launcherAbilityResourceInfo.moduleName;
548             resourceInfo.label_ = launcherAbilityResourceInfo.label;
549             resourceInfos.emplace_back(resourceInfo);
550         }
551     }
552     if (resourceInfos.empty()) {
553         APP_LOGI("%{public}s no default icon, build new", bundleName.c_str());
554         resourceInfo.bundleName_ = bundleName;
555         resourceInfo.moduleName_ = Constants::EMPTY_STRING;
556         resourceInfo.abilityName_ = Constants::EMPTY_STRING;
557         resourceInfo.label_ = bundleName;
558         resourceInfos.emplace_back(resourceInfo);
559     }
560 
561     APP_LOGI("UpdateBundleIcon %{public}s, size: %{public}zu", bundleName.c_str(), resourceInfos.size());
562     return SaveResourceInfos(resourceInfos);
563 }
564 
AddCloneBundleResourceInfo(const std::string & bundleName,const int32_t appIndex)565 bool BundleResourceManager::AddCloneBundleResourceInfo(
566     const std::string &bundleName,
567     const int32_t appIndex)
568 {
569     APP_LOGD("start add clone bundle resource info, bundleName:%{public}s appIndex:%{public}d",
570         bundleName.c_str(), appIndex);
571     // 1. get main bundle resource info
572     std::vector<ResourceInfo> resourceInfos;
573     if (!GetBundleResourceInfoForCloneBundle(bundleName, appIndex, resourceInfos)) {
574         APP_LOGE("add clone resource failed %{public}s appIndex:%{public}d",
575             bundleName.c_str(), appIndex);
576         return false;
577     }
578     // 2. need to process base icon and badge icon
579     // BundleResourceParser
580     BundleResourceParser parser;
581     if (!parser.ParserCloneResourceInfo(appIndex, resourceInfos)) {
582         APP_LOGE("%{public}s appIndex:%{public}d parse clone resource failed", bundleName.c_str(), appIndex);
583     }
584     // 3. save clone bundle resource info
585     if (!bundleResourceRdb_->AddResourceInfos(resourceInfos)) {
586         APP_LOGE("add resource failed %{public}s appIndex:%{public}d", bundleName.c_str(), appIndex);
587         return false;
588     }
589     APP_LOGD("end, add clone bundle resource succeed");
590     return true;
591 }
592 
DeleteCloneBundleResourceInfo(const std::string & bundleName,const int32_t appIndex)593 bool BundleResourceManager::DeleteCloneBundleResourceInfo(const std::string &bundleName,
594     const int32_t appIndex)
595 {
596     APP_LOGD("start delete clone bundle resource info, bundleName:%{public}s appIndex:%{public}d",
597         bundleName.c_str(), appIndex);
598     ResourceInfo info;
599     info.bundleName_ = bundleName;
600     info.appIndex_ = appIndex;
601     return bundleResourceRdb_->DeleteResourceInfo(info.GetKey());
602 }
603 
GetBundleResourceInfoForCloneBundle(const std::string & bundleName,const int32_t appIndex,std::vector<ResourceInfo> & resourceInfos)604 bool BundleResourceManager::GetBundleResourceInfoForCloneBundle(const std::string &bundleName,
605     const int32_t appIndex, std::vector<ResourceInfo> &resourceInfos)
606 {
607     // 1. get main bundle resource info
608     BundleResourceInfo bundleResourceInfo;
609     uint32_t flags = static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_ALL) |
610         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR);
611     if (!bundleResourceRdb_->GetBundleResourceInfo(bundleName, flags, bundleResourceInfo)) {
612         APP_LOGE("get resource failed %{public}s appIndex:%{public}d", bundleName.c_str(), appIndex);
613         return false;
614     }
615     bundleResourceInfo.appIndex = appIndex;
616     ResourceInfo bundleResource;
617     bundleResource.ConvertFromBundleResourceInfo(bundleResourceInfo);
618     resourceInfos.emplace_back(bundleResource);
619     // 2. get main launcher ability resource info
620     std::vector<LauncherAbilityResourceInfo> launcherAbilityResourceInfos;
621     if (!bundleResourceRdb_->GetLauncherAbilityResourceInfo(bundleName, flags, launcherAbilityResourceInfos)) {
622         APP_LOGW("get ability resource failed %{public}s appIndex:%{public}d",
623             bundleName.c_str(), appIndex);
624     }
625     for (auto &launcherAbility : launcherAbilityResourceInfos) {
626         launcherAbility.appIndex = appIndex;
627         ResourceInfo launcherResource;
628         launcherResource.ConvertFromLauncherAbilityResourceInfo(launcherAbility);
629         resourceInfos.emplace_back(launcherResource);
630     }
631     APP_LOGI("%{public}s appIndex:%{public}d add resource size:%{public}zu", bundleName.c_str(), appIndex,
632         resourceInfos.size());
633     return true;
634 }
635 
UpdateCloneBundleResourceInfo(const std::string & bundleName,const int32_t appIndex,const uint32_t type)636 bool BundleResourceManager::UpdateCloneBundleResourceInfo(
637     const std::string &bundleName,
638     const int32_t appIndex,
639     const uint32_t type)
640 {
641     APP_LOGD("start update clone bundle resource info, bundleName:%{public}s appIndex:%{public}d",
642         bundleName.c_str(), appIndex);
643     // 1. get main bundle resource info
644     std::vector<ResourceInfo> resourceInfos;
645     if (!GetBundleResourceInfoForCloneBundle(bundleName, appIndex, resourceInfos)) {
646         APP_LOGE("add clone bundle resource failed, bundleName:%{public}s appIndex:%{public}d",
647             bundleName.c_str(), appIndex);
648         return false;
649     }
650     // 2. need to process base icon and badge icon when userId or theme changed
651     if (((type & static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_THEME_CHANGE)) ==
652         static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_THEME_CHANGE)) ||
653         ((type & static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_USER_ID_CHANGE)) ==
654         static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_USER_ID_CHANGE))) {
655         BundleResourceParser parser;
656         if (!parser.ParserCloneResourceInfo(appIndex, resourceInfos)) {
657             APP_LOGE("bundleName:%{public}s appIndex:%{public}d parse clone resource failed",
658                 bundleName.c_str(), appIndex);
659         }
660     } else {
661         for (auto &resourceInfo : resourceInfos) {
662             resourceInfo.icon_ = Constants::EMPTY_STRING;
663         }
664     }
665     // 3. save clone bundle resource info
666     if (!bundleResourceRdb_->UpdateResourceForSystemStateChanged(resourceInfos)) {
667         APP_LOGE("add resource failed, bundleName:%{public}s appIndex:%{public}d", bundleName.c_str(), appIndex);
668         return false;
669     }
670     APP_LOGD("end, add clone bundle resource succeed");
671     return true;
672 }
673 
DeleteNotExistResourceInfo()674 bool BundleResourceManager::DeleteNotExistResourceInfo()
675 {
676     APP_LOGD("start delete not exist resource");
677     return bundleResourceRdb_->DeleteNotExistResourceInfo();
678 }
679 
ProcessResourceInfoNoNeedToParseOtherIcon(std::vector<ResourceInfo> & resourceInfos)680 void BundleResourceManager::ProcessResourceInfoNoNeedToParseOtherIcon(std::vector<ResourceInfo> &resourceInfos)
681 {
682     size_t size = resourceInfos.size();
683     for (size_t index = 0; index < size; ++index) {
684         // theme changed no need parse label
685         resourceInfos[index].labelNeedParse_ = false;
686         resourceInfos[index].label_ = Constants::EMPTY_STRING;
687         if ((index > 0) && ServiceConstants::ALLOW_MULTI_ICON_BUNDLE.find(resourceInfos[0].bundleName_) ==
688             ServiceConstants::ALLOW_MULTI_ICON_BUNDLE.end()) {
689             // only need parse once
690             resourceInfos[index].iconNeedParse_ = false;
691         }
692     }
693 }
694 } // AppExecFwk
695 } // OHOS
696