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