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