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