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