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_parser.h"
17
18 #include "bundle_resource_configuration.h"
19 #include "bundle_resource_image_info.h"
20 #include "bundle_resource_drawable.h"
21 #include "bundle_util.h"
22 #include "json_util.h"
23
24 #ifdef BUNDLE_FRAMEWORK_GRAPHICS
25 #include "image_source.h"
26 #include "pixel_map.h"
27 #endif
28
29 namespace OHOS {
30 namespace AppExecFwk {
31 namespace {
32 const char* TYPE_JSON = "json";
33 const char* TYPE_PNG = "png";
34 const char* FOREGROUND = "foreground";
35 const char* BACKGROUND = "background";
36 const char CHAR_COLON = ':';
37 #ifdef BUNDLE_FRAMEWORK_GRAPHICS
38 const std::string OHOS_CLONE_APP_BADGE_RESOURCE = "clone_app_badge_";
39 const int32_t BADGE_SIZE = 62;
40 #endif
41 constexpr const char* COM_OHOS_CONTACTS_ENTRY_ABILITY = "com.ohos.contacts.EntryAbility";
42 constexpr const char* COM_OHOS_CONTACTS_ENTRY = "entry";
43 constexpr const char* SYSTEM_THEME_PATH = "/data/service/el1/public/themes/";
44 constexpr const char* ENTRY_ABILITY_THEME_ICONS_A =
45 "/a/app/icons/com.ohos.contacts/entry/com.ohos.contacts.EntryAbility";
46 constexpr const char* ENTRY_ABILITY_THEME_ICONS_B =
47 "/b/app/icons/com.ohos.contacts/entry/com.ohos.contacts.EntryAbility";
48 constexpr const char* THEME_ICONS_A_FLAG = "/a/app/flag";
49 constexpr const char* THEME_ICONS_B_FLAG = "/b/app/flag";
50 constexpr const char* COM_OHOS_CONTACTS = "com.ohos.contacts";
51
52 struct LayeredImage {
53 std::string foreground;
54 std::string background;
55 };
56
from_json(const nlohmann::json & jsonObject,LayeredImage & layeredImage)57 void from_json(const nlohmann::json &jsonObject, LayeredImage &layeredImage)
58 {
59 int32_t parseResult = 0;
60 const auto &jsonObjectEnd = jsonObject.end();
61 GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, FOREGROUND, layeredImage.foreground,
62 JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
63
64 GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, BACKGROUND, layeredImage.background,
65 JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
66 }
67
68 #ifdef BUNDLE_FRAMEWORK_GRAPHICS
GetBadgeResource(const std::string & resourceName,std::shared_ptr<Media::PixelMap> & badgePixelMap)69 bool GetBadgeResource(const std::string &resourceName, std::shared_ptr<Media::PixelMap> &badgePixelMap)
70 {
71 std::shared_ptr<Global::Resource::ResourceManager> resMgr(Global::Resource::CreateResourceManager());
72 if (resMgr == nullptr) {
73 APP_LOGE("resMgr is nullptr");
74 return false;
75 }
76 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
77 if (resConfig == nullptr) {
78 APP_LOGE("resConfig is nullptr");
79 return false;
80 }
81 resMgr->UpdateResConfig(*resConfig);
82
83 std::unique_ptr<uint8_t[]> badgeResourceData;
84 size_t badgeResourceDataLength = 0;
85 auto ret = resMgr->GetMediaDataByName(resourceName.c_str(), badgeResourceDataLength, badgeResourceData);
86 if (ret != Global::Resource::RState::SUCCESS) {
87 APP_LOGE("get (%{public}s) failed, errorCode:%{public}d", resourceName.c_str(), static_cast<int32_t>(ret));
88 return false;
89 }
90
91 Media::SourceOptions opts;
92 uint32_t errorCode = 0;
93 std::unique_ptr<Media::ImageSource> imageSource =
94 Media::ImageSource::CreateImageSource(badgeResourceData.get(), badgeResourceDataLength, opts, errorCode);
95 Media::DecodeOptions decodeOpts;
96 decodeOpts.desiredPixelFormat = Media::PixelFormat::BGRA_8888;
97 decodeOpts.desiredSize.width = BADGE_SIZE;
98 decodeOpts.desiredSize.height = BADGE_SIZE;
99 if (imageSource) {
100 auto pixelMapPtr = imageSource->CreatePixelMap(decodeOpts, errorCode);
101 badgePixelMap = std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
102 }
103 if (errorCode != 0 || (badgePixelMap == nullptr)) {
104 APP_LOGE("get badge failed, errorCode:%{public}u", errorCode);
105 return false;
106 }
107 return true;
108 }
109 #endif
110 }
111
BundleResourceParser()112 BundleResourceParser::BundleResourceParser()
113 {
114 }
115
~BundleResourceParser()116 BundleResourceParser::~BundleResourceParser()
117 {
118 }
119
ParseResourceInfo(const int32_t userId,ResourceInfo & resourceInfo)120 bool BundleResourceParser::ParseResourceInfo(const int32_t userId, ResourceInfo &resourceInfo)
121 {
122 return ParseResourceInfoWithSameHap(userId, resourceInfo);
123 }
124
ParseResourceInfos(const int32_t userId,std::vector<ResourceInfo> & resourceInfos)125 bool BundleResourceParser::ParseResourceInfos(const int32_t userId, std::vector<ResourceInfo> &resourceInfos)
126 {
127 APP_LOGD("start");
128 if (resourceInfos.empty()) {
129 APP_LOGE("resourceInfos is empty");
130 return false;
131 }
132 // same module need parse together
133 std::map<std::string, std::shared_ptr<Global::Resource::ResourceManager>> resourceManagerMap;
134 size_t size = resourceInfos.size();
135 for (size_t index = 0; index < size; ++index) {
136 if (!resourceInfos[index].iconNeedParse_ && !resourceInfos[index].labelNeedParse_) {
137 APP_LOGI("%{public}s no need parse", resourceInfos[index].bundleName_.c_str());
138 continue;
139 }
140 if ((index > 0) && !IsNeedToParseResourceInfo(resourceInfos[index], resourceInfos[0])) {
141 continue;
142 }
143 auto resourceManager = resourceManagerMap[resourceInfos[index].moduleName_];
144 if (resourceManager == nullptr) {
145 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
146 if (resConfig == nullptr) {
147 APP_LOGE("resConfig is nullptr");
148 continue;
149 }
150 resourceManager =
151 std::shared_ptr<Global::Resource::ResourceManager>(Global::Resource::CreateResourceManager(
152 resourceInfos[index].bundleName_, resourceInfos[index].moduleName_,
153 resourceInfos[index].hapPath_, resourceInfos[index].overlayHapPaths_, *resConfig, 0, userId));
154 resourceManagerMap[resourceInfos[index].moduleName_] = resourceManager;
155 if (!BundleResourceConfiguration::InitResourceGlobalConfig(
156 resourceInfos[index].hapPath_, resourceInfos[index].overlayHapPaths_, resourceManager,
157 resourceInfos[index].iconNeedParse_, resourceInfos[index].labelNeedParse_)) {
158 APP_LOGW("InitResourceGlobalConfig failed, key:%{public}s", resourceInfos[index].GetKey().c_str());
159 }
160 }
161
162 if (!ParseResourceInfoByResourceManager(resourceManager, resourceInfos[index])) {
163 APP_LOGW_NOFUNC("ParseResourceInfo failed, key:%{public}s", resourceInfos[index].GetKey().c_str());
164 }
165 }
166 if ((resourceInfos[0].labelNeedParse_ && resourceInfos[0].label_.empty()) ||
167 (resourceInfos[0].iconNeedParse_ && resourceInfos[0].icon_.empty())) {
168 APP_LOGE("bundleName:%{public}s moduleName:%{public}s prase resource failed",
169 resourceInfos[0].bundleName_.c_str(), resourceInfos[0].moduleName_.c_str());
170 return false;
171 }
172 ProcessSpecialBundleResource(userId, resourceInfos);
173 APP_LOGD("end");
174 return true;
175 }
176
IsNeedToParseResourceInfo(const ResourceInfo & newResourceInfo,const ResourceInfo & oldResourceInfo)177 bool BundleResourceParser::IsNeedToParseResourceInfo(
178 const ResourceInfo &newResourceInfo, const ResourceInfo &oldResourceInfo)
179 {
180 // same labelId and iconId no need to parse again
181 if (newResourceInfo.moduleName_ == oldResourceInfo.moduleName_) {
182 if ((newResourceInfo.labelId_ == oldResourceInfo.labelId_) &&
183 (newResourceInfo.iconId_ == oldResourceInfo.iconId_)) {
184 return false;
185 }
186 }
187 if ((newResourceInfo.labelId_ <= 0) && (newResourceInfo.iconId_ <= 0)) {
188 // no need to process icon and label
189 APP_LOGW("key:%{public}s label and icon both equal 0", newResourceInfo.GetKey().c_str());
190 return false;
191 }
192 return true;
193 }
194
ParseResourceInfoWithSameHap(const int32_t userId,ResourceInfo & resourceInfo)195 bool BundleResourceParser::ParseResourceInfoWithSameHap(const int32_t userId, ResourceInfo &resourceInfo)
196 {
197 if (resourceInfo.hapPath_.empty()) {
198 APP_LOGE("resourceInfo.hapPath_ is empty");
199 return false;
200 }
201 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
202 if (resConfig == nullptr) {
203 APP_LOGE("resConfig is nullptr");
204 return false;
205 }
206 std::shared_ptr<Global::Resource::ResourceManager> resourceManager =
207 std::shared_ptr<Global::Resource::ResourceManager>(Global::Resource::CreateResourceManager(
208 resourceInfo.bundleName_, resourceInfo.moduleName_,
209 resourceInfo.hapPath_, resourceInfo.overlayHapPaths_, *resConfig, 0, userId));
210 if (resourceManager == nullptr) {
211 APP_LOGE("resourceManager is nullptr");
212 return false;
213 }
214 if (!BundleResourceConfiguration::InitResourceGlobalConfig(resourceInfo.hapPath_, resourceManager)) {
215 APP_LOGE("InitResourceGlobalConfig failed, key:%{public}s", resourceInfo.GetKey().c_str());
216 return false;
217 }
218 if (!ParseResourceInfoByResourceManager(resourceManager, resourceInfo)) {
219 APP_LOGE_NOFUNC("ParseResourceInfo failed, key:%{public}s", resourceInfo.GetKey().c_str());
220 return false;
221 }
222 return true;
223 }
224
ParseLabelResourceByPath(const std::string & hapPath,const uint32_t labelId,std::string & label)225 bool BundleResourceParser::ParseLabelResourceByPath(
226 const std::string &hapPath, const uint32_t labelId, std::string &label)
227 {
228 if (hapPath.empty()) {
229 APP_LOGE("hapPath is empty");
230 return false;
231 }
232 // allow label resource parse failed, then label is bundleName
233 if (labelId <= 0) {
234 APP_LOGW("labelId is 0");
235 return true;
236 }
237 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
238 if (resourceManager == nullptr) {
239 APP_LOGE("resourceManager is nullptr");
240 return false;
241 }
242 if (!BundleResourceConfiguration::InitResourceGlobalConfig(hapPath, resourceManager)) {
243 APP_LOGE("InitResourceGlobalConfig failed, key:%{private}s", hapPath.c_str());
244 return false;
245 }
246 if (!ParseLabelResourceByResourceManager(resourceManager, labelId, label)) {
247 APP_LOGE("ParseLabelResource failed, label %{public}d", labelId);
248 return false;
249 }
250 return true;
251 }
252
ParseIconResourceByPath(const std::string & hapPath,const uint32_t iconId,ResourceInfo & resourceInfo)253 bool BundleResourceParser::ParseIconResourceByPath(const std::string &hapPath, const uint32_t iconId,
254 ResourceInfo &resourceInfo)
255 {
256 if (hapPath.empty()) {
257 APP_LOGE("hapPath is empty");
258 return false;
259 }
260 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
261 if (resourceManager == nullptr) {
262 APP_LOGE("resourceManager is nullptr");
263 return false;
264 }
265 if (!BundleResourceConfiguration::InitResourceGlobalConfig(hapPath, resourceManager)) {
266 APP_LOGE("InitResourceGlobalConfig failed, hapPath:%{private}s", hapPath.c_str());
267 return false;
268 }
269 resourceInfo.iconId_ = iconId;
270 if (!ParseIconResourceByResourceManager(resourceManager, resourceInfo)) {
271 APP_LOGE("failed, iconId %{public}d", iconId);
272 return false;
273 }
274 return true;
275 }
276
ParseResourceInfoByResourceManager(const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,ResourceInfo & resourceInfo)277 bool BundleResourceParser::ParseResourceInfoByResourceManager(
278 const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,
279 ResourceInfo &resourceInfo)
280 {
281 if (resourceManager == nullptr) {
282 APP_LOGE("resourceManager is nullptr");
283 return false;
284 }
285 bool ans = true;
286 if (resourceInfo.labelNeedParse_ && !ParseLabelResourceByResourceManager(
287 resourceManager, resourceInfo.labelId_, resourceInfo.label_)) {
288 APP_LOGE_NOFUNC("ParseLabelResource failed, key %{public}s", resourceInfo.GetKey().c_str());
289 ans = false;
290 }
291
292 if (resourceInfo.iconNeedParse_ && !ParseIconResourceByResourceManager(resourceManager, resourceInfo)) {
293 APP_LOGE_NOFUNC("ParseIconResource failed, key %{public}s", resourceInfo.GetKey().c_str());
294 ans = false;
295 }
296
297 return ans;
298 }
299
ParseLabelResourceByResourceManager(const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,const uint32_t labelId,std::string & label)300 bool BundleResourceParser::ParseLabelResourceByResourceManager(
301 const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,
302 const uint32_t labelId, std::string &label)
303 {
304 if (resourceManager == nullptr) {
305 APP_LOGE("resourceManager is nullptr");
306 return false;
307 }
308 if (labelId <= 0) {
309 APP_LOGW("ParseLabelResource labelId is 0 or less than 0, label is bundleName");
310 return false;
311 }
312 auto ret = resourceManager->GetStringById(labelId, label);
313 if (ret != OHOS::Global::Resource::RState::SUCCESS) {
314 APP_LOGE("GetStringById failed %{public}d, labelId %{public}d",
315 static_cast<int32_t>(ret), labelId);
316 return false;
317 }
318 return true;
319 }
320
ParseIconResourceByResourceManager(const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,ResourceInfo & resourceInfo)321 bool BundleResourceParser::ParseIconResourceByResourceManager(
322 const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,
323 ResourceInfo &resourceInfo)
324 {
325 if (resourceManager == nullptr) {
326 APP_LOGE("resourceManager is nullptr");
327 return false;
328 }
329 if (resourceInfo.iconId_ <= 0) {
330 APP_LOGE_NOFUNC("iconId is 0 or less than 0");
331 return false;
332 }
333 // Firstly, check if the bundle theme resource exists, density 0
334 BundleResourceDrawable drawable;
335 if (drawable.GetIconResourceByTheme(resourceInfo.iconId_, 0, resourceManager, resourceInfo) &&
336 !resourceInfo.foreground_.empty()) {
337 return true;
338 }
339 APP_LOGI_NOFUNC("%{public}s not exist theme", resourceInfo.GetKey().c_str());
340 // parse json
341 std::string type;
342 size_t len;
343 std::unique_ptr<uint8_t[]> jsonBuf;
344 Global::Resource::RState state = resourceManager->GetDrawableInfoById(resourceInfo.iconId_, type, len, jsonBuf, 0);
345 if (state != Global::Resource::SUCCESS) {
346 APP_LOGE("%{public}s failed to get id:%{public}d", resourceInfo.bundleName_.c_str(),
347 resourceInfo.iconId_);
348 return false;
349 }
350 transform(type.begin(), type.end(), type.begin(), ::tolower);
351 if (type == TYPE_PNG) {
352 resourceInfo.foreground_.resize(len);
353 for (size_t index = 0; index < len; ++index) {
354 resourceInfo.foreground_[index] = jsonBuf[index];
355 }
356 BundleResourceImageInfo bundleResourceImageInfo;
357 // encode base64
358 return bundleResourceImageInfo.ConvertToBase64(std::move(jsonBuf), len, resourceInfo.icon_);
359 }
360 APP_LOGI("%{public}s icon is not png, parse by drawable descriptor", resourceInfo.GetKey().c_str());
361 if (!drawable.GetIconResourceByHap(resourceInfo.iconId_, 0, resourceManager, resourceInfo)) {
362 APP_LOGE("key:%{public}s parse failed with hap iconId:%{public}d",
363 resourceInfo.GetKey().c_str(), resourceInfo.iconId_);
364 return false;
365 }
366 if (type == TYPE_JSON) {
367 return ParseForegroundAndBackgroundResource(resourceManager,
368 std::string(reinterpret_cast<char*>(jsonBuf.get()), len), 0, resourceInfo);
369 } else {
370 resourceInfo.foreground_.resize(len);
371 for (size_t index = 0; index < len; ++index) {
372 resourceInfo.foreground_[index] = jsonBuf[index];
373 }
374 }
375 return true;
376 }
377
ParseIconIdFromJson(const std::string & jsonBuff,uint32_t & foregroundId,uint32_t & backgroundId)378 bool BundleResourceParser::ParseIconIdFromJson(
379 const std::string &jsonBuff, uint32_t &foregroundId, uint32_t &backgroundId)
380 {
381 nlohmann::json jsonObject = nlohmann::json::parse(jsonBuff, nullptr, false);
382 if (jsonObject.is_discarded()) {
383 APP_LOGE("failed to parse jsonBuff %{public}s", jsonBuff.c_str());
384 return false;
385 }
386 const auto &jsonObjectStart = jsonObject.begin();
387 if ((jsonObjectStart == jsonObject.end()) || !jsonObjectStart.value().is_object()) {
388 APP_LOGE("not object, failed to parse jsonBuff %{public}s", jsonBuff.c_str());
389 return false;
390 }
391 LayeredImage layerImage = jsonObjectStart.value().get<LayeredImage>();
392 if (layerImage.foreground.empty() && layerImage.background.empty()) {
393 APP_LOGE("foreground background empty, buffer %{public}s", jsonBuff.c_str());
394 return false;
395 }
396 auto pos = layerImage.foreground.find(CHAR_COLON);
397 if (pos != std::string::npos) {
398 int32_t foregroundLength = static_cast<int32_t>(layerImage.foreground.length());
399 foregroundId = static_cast<uint32_t>(
400 atoi(layerImage.foreground.substr(pos + 1, foregroundLength - pos - 1).c_str()));
401 }
402 pos = layerImage.background.find(CHAR_COLON);
403 if (pos != std::string::npos) {
404 int32_t backgroundLength = static_cast<int32_t>(layerImage.background.length());
405 backgroundId = static_cast<uint32_t>(atoi(layerImage.background.substr(pos + 1,
406 backgroundLength - pos - 1).c_str()));
407 }
408 APP_LOGD("succeed, foregroundId:%{public}u, backgroundId:%{public}u", foregroundId, backgroundId);
409 return true;
410 }
411
GetMediaDataById(const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,const uint32_t iconId,const int32_t density,std::vector<uint8_t> & data)412 bool BundleResourceParser::GetMediaDataById(
413 const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,
414 const uint32_t iconId, const int32_t density, std::vector<uint8_t> &data)
415 {
416 if (resourceManager == nullptr) {
417 APP_LOGE("resourceManager is nullptr");
418 return false;
419 }
420 std::string type;
421 size_t len;
422 std::unique_ptr<uint8_t[]> jsonBuf;
423 Global::Resource::RState state = resourceManager->GetDrawableInfoById(iconId, type, len, jsonBuf, density);
424 if (state != Global::Resource::SUCCESS) {
425 APP_LOGE("Failed get drawable info, iconId %{public}u", iconId);
426 return false;
427 }
428 data.resize(len);
429 for (size_t index = 0; index < len; ++index) {
430 data[index] = jsonBuf[index];
431 }
432 return true;
433 }
434
ParseForegroundAndBackgroundResource(const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,const std::string & jsonBuff,const int32_t density,ResourceInfo & resourceInfo)435 bool BundleResourceParser::ParseForegroundAndBackgroundResource(
436 const std::shared_ptr<Global::Resource::ResourceManager> resourceManager,
437 const std::string &jsonBuff,
438 const int32_t density,
439 ResourceInfo &resourceInfo)
440 {
441 APP_LOGI("key:%{public}s start parse layered-image", resourceInfo.GetKey().c_str());
442 if (resourceManager == nullptr) {
443 APP_LOGE("resourceManager is nullptr");
444 return false;
445 }
446 uint32_t foregroundId = 0;
447 uint32_t backgroundId = 0;
448 if (!ParseIconIdFromJson(jsonBuff, foregroundId, backgroundId)) {
449 APP_LOGE("parse from json failed, iconId:%{public}d,buffer:%{public}s", resourceInfo.iconId_, jsonBuff.c_str());
450 return false;
451 }
452 // parse foreground
453 bool ans = true;
454 if (!GetMediaDataById(resourceManager, foregroundId, density, resourceInfo.foreground_)) {
455 APP_LOGE("parse foreground failed iconId %{public}u", foregroundId);
456 ans = false;
457 }
458 // parse background
459 if (!GetMediaDataById(resourceManager, backgroundId, density, resourceInfo.background_)) {
460 APP_LOGE("parse background failed iconId:%{public}u", backgroundId);
461 ans = false;
462 }
463 APP_LOGD("foreground size:%{public}zu background size:%{public}zu",
464 resourceInfo.foreground_.size(), resourceInfo.background_.size());
465 return ans;
466 }
467
ParserCloneResourceInfo(const int32_t appIndex,std::vector<ResourceInfo> & resourceInfos)468 bool BundleResourceParser::ParserCloneResourceInfo(
469 const int32_t appIndex, std::vector<ResourceInfo> &resourceInfos)
470 {
471 #ifdef BUNDLE_FRAMEWORK_GRAPHICS
472 // 1. get badge resource media
473 std::string resourceName = OHOS_CLONE_APP_BADGE_RESOURCE + std::to_string(appIndex);
474 APP_LOGI("parse clone info appIndex:%{public}d resourceName:%{public}s start", appIndex, resourceName.c_str());
475 std::shared_ptr<Media::PixelMap> badgePixelMap;
476 if (!GetBadgeResource(resourceName, badgePixelMap) || (badgePixelMap == nullptr)) {
477 APP_LOGE("resourceName:%{public}s get failed", resourceName.c_str());
478 return false;
479 }
480 bool ans = true;
481 // 2. base64 to pixelMap
482 for (auto &resourceInfo : resourceInfos) {
483 uint32_t errorCode = 0;
484 Media::SourceOptions opts;
485 std::unique_ptr<Media::ImageSource> imageSource =
486 Media::ImageSource::CreateImageSource(resourceInfo.icon_, opts, errorCode); // base64 to image
487 Media::DecodeOptions decodeOpts;
488 decodeOpts.desiredPixelFormat = Media::PixelFormat::BGRA_8888;
489 std::shared_ptr<Media::PixelMap> baseIconResource;
490 if (imageSource) {
491 auto pixelMapPtr = imageSource->CreatePixelMap(decodeOpts, errorCode);
492 baseIconResource = std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
493 }
494 if ((errorCode != 0) || (baseIconResource == nullptr)) {
495 APP_LOGW("get base icon resource failed, key:%{public}s", resourceInfo.GetKey().c_str());
496 ans = false;
497 continue;
498 }
499 // base icon and badge icon resource
500 BundleResourceDrawable drawable;
501 if (!drawable.GetBadgedIconResource(baseIconResource, badgePixelMap, resourceInfo)) {
502 APP_LOGE("get badge failed, key:%{public}s", resourceInfo.GetKey().c_str());
503 ans = false;
504 }
505 }
506 APP_LOGI("parse clone resource info appIndex:%{public}d end", appIndex);
507 return ans;
508 #else
509 APP_LOGI("not support pixel map");
510 return false;
511 #endif
512 }
513
ProcessSpecialBundleResource(const int32_t userId,std::vector<ResourceInfo> & resourceInfos)514 void BundleResourceParser::ProcessSpecialBundleResource(const int32_t userId, std::vector<ResourceInfo> &resourceInfos)
515 {
516 if (resourceInfos.empty()) {
517 APP_LOGW("resourceInfos empty");
518 return;
519 }
520 if ((resourceInfos[0].GetKey() == COM_OHOS_CONTACTS)) {
521 bool isContactsEntryAbilityExistTheme = false;
522 if (BundleUtil::IsExistFileNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_A_FLAG) &&
523 BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + ENTRY_ABILITY_THEME_ICONS_A)) {
524 isContactsEntryAbilityExistTheme = true;
525 }
526 if (!isContactsEntryAbilityExistTheme &&
527 BundleUtil::IsExistFileNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_B_FLAG) &&
528 BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + ENTRY_ABILITY_THEME_ICONS_B)) {
529 isContactsEntryAbilityExistTheme = true;
530 }
531 if (!isContactsEntryAbilityExistTheme) {
532 APP_LOGI("%{public}s not exist entry ability theme", resourceInfos[0].GetKey().c_str());
533 return;
534 }
535 for (const auto &resourceInfo : resourceInfos) {
536 if ((resourceInfo.moduleName_ == COM_OHOS_CONTACTS_ENTRY) &&
537 (resourceInfo.abilityName_ == COM_OHOS_CONTACTS_ENTRY_ABILITY) &&
538 !resourceInfo.icon_.empty()) {
539 APP_LOGI("%{public}s exist entry ability theme", resourceInfos[0].GetKey().c_str());
540 resourceInfos[0].icon_ = resourceInfo.icon_;
541 resourceInfos[0].foreground_ = resourceInfo.foreground_;
542 resourceInfos[0].background_ = resourceInfo.background_;
543 return;
544 }
545 }
546 }
547 }
548 } // AppExecFwk
549 } // OHOS