1 /*
2 * Copyright (c) 2023-2025 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_process.h"
17
18 #include "account_helper.h"
19 #include "bundle_mgr_service.h"
20 #include "bundle_parser.h"
21 #include "bundle_resource_parser.h"
22 #include "json_util.h"
23
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 constexpr const char* INNER_UNDER_LINE = "_";
28 constexpr const char* SYSTEM_THEME_PATH = "/data/service/el1/public/themes/";
29 constexpr const char* THEME_ICONS_A = "/a/app/icons/";
30 constexpr const char* THEME_ICONS_B = "/b/app/icons/";
31 constexpr const char* THEME_ICONS_A_FLAG = "/a/app/flag";
32 constexpr const char* THEME_DESCRIPTION_FILE = "description.json";
33 constexpr const char* THEME_KEY_ORIGIN = "origin";
34 constexpr const char* THEME_KEY_THEME_TYPE_ONLINE = "online";
35 }
36
GetBundleResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId,ResourceInfo & resourceInfo)37 bool BundleResourceProcess::GetBundleResourceInfo(const InnerBundleInfo &innerBundleInfo,
38 const int32_t userId,
39 ResourceInfo &resourceInfo)
40 {
41 if (innerBundleInfo.GetBundleName().empty()) {
42 APP_LOGE("bundleName is empty");
43 return false;
44 }
45 if (innerBundleInfo.GetApplicationBundleType() == BundleType::SHARED) {
46 APP_LOGD("bundleName:%{public}s is shared", innerBundleInfo.GetBundleName().c_str());
47 return false;
48 }
49 resourceInfo = ConvertToBundleResourceInfo(innerBundleInfo);
50 // process overlay hap paths
51 GetOverlayModuleHapPaths(innerBundleInfo, resourceInfo.moduleName_, userId, resourceInfo.overlayHapPaths_);
52 return true;
53 }
54
GetAllResourceInfo(const int32_t userId,std::map<std::string,std::vector<ResourceInfo>> & resourceInfosMap)55 bool BundleResourceProcess::GetAllResourceInfo(
56 const int32_t userId,
57 std::map<std::string, std::vector<ResourceInfo>> &resourceInfosMap)
58 {
59 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
60 if (dataMgr == nullptr) {
61 APP_LOGE("dataMgr is nullptr");
62 return false;
63 }
64 if (!dataMgr->HasUserId(userId)) {
65 APP_LOGE("userId %{public}d not exist", userId);
66 return false;
67 }
68 std::vector<std::string> allBundleNames = dataMgr->GetAllBundleName();
69 if (allBundleNames.empty()) {
70 APP_LOGE("bundleInfos is empty");
71 return false;
72 }
73
74 for (const auto &bundleName : allBundleNames) {
75 InnerBundleInfo innerBundleInfo;
76 if (!dataMgr->FetchInnerBundleInfo(bundleName, innerBundleInfo)) {
77 APP_LOGE("bundleName %{public}s not exist", bundleName.c_str());
78 continue;
79 }
80 if (innerBundleInfo.GetApplicationBundleType() == BundleType::SHARED ||
81 ((innerBundleInfo.GetApplicationBundleType() == BundleType::APP_SERVICE_FWK)
82 && innerBundleInfo.IsHsp())) {
83 APP_LOGD("bundleName:%{public}s is shared or app service", bundleName.c_str());
84 continue;
85 }
86 std::vector<ResourceInfo> resourceInfos;
87 if (!InnerGetResourceInfo(innerBundleInfo, userId, resourceInfos) || resourceInfos.empty()) {
88 APP_LOGW("%{public}s resourceInfo empty", bundleName.c_str());
89 } else {
90 resourceInfosMap[bundleName] = resourceInfos;
91 }
92 }
93 APP_LOGI("resourceInfosMap size: %{public}zu", resourceInfosMap.size());
94 return true;
95 }
96
GetResourceInfoByBundleName(const std::string & bundleName,const int32_t userId,std::vector<ResourceInfo> & resourceInfo,const int32_t appIndex,bool needParseDynamic)97 bool BundleResourceProcess::GetResourceInfoByBundleName(
98 const std::string &bundleName,
99 const int32_t userId,
100 std::vector<ResourceInfo> &resourceInfo,
101 const int32_t appIndex,
102 bool needParseDynamic)
103 {
104 APP_LOGD("start, bundleName:%{public}s", bundleName.c_str());
105 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
106 if (dataMgr == nullptr) {
107 APP_LOGE("dataMgr is nullptr");
108 return false;
109 }
110 if (!dataMgr->HasUserId(userId)) {
111 APP_LOGE("userId %{public}d not exist", userId);
112 return false;
113 }
114 InnerBundleInfo innerBundleInfo;
115 if (!dataMgr->FetchInnerBundleInfo(bundleName, innerBundleInfo)) {
116 APP_LOGE("bundleName %{public}s not exist", bundleName.c_str());
117 return false;
118 }
119 if (innerBundleInfo.GetApplicationBundleType() == BundleType::SHARED ||
120 ((innerBundleInfo.GetApplicationBundleType() == BundleType::APP_SERVICE_FWK)
121 && innerBundleInfo.IsHsp())) {
122 APP_LOGW("bundleName:%{public}s is shared or app service", bundleName.c_str());
123 return false;
124 }
125
126 return InnerGetResourceInfo(innerBundleInfo, userId, resourceInfo, appIndex, needParseDynamic);
127 }
128
GetLauncherResourceInfoByAbilityName(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const int32_t userId,ResourceInfo & resourceInfo)129 bool BundleResourceProcess::GetLauncherResourceInfoByAbilityName(
130 const std::string &bundleName,
131 const std::string &moduleName,
132 const std::string &abilityName,
133 const int32_t userId,
134 ResourceInfo &resourceInfo)
135 {
136 APP_LOGD("start, bundleName:%{public}s, moduleName:%{public}s, abilityName:%{public}s",
137 bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
138 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
139 if (dataMgr == nullptr) {
140 APP_LOGE("dataMgr is nullptr");
141 return false;
142 }
143 if (!dataMgr->HasUserId(userId)) {
144 APP_LOGE("userId %{public}d not exist", userId);
145 return false;
146 }
147 InnerBundleInfo innerBundleInfo;
148 if (!dataMgr->FetchInnerBundleInfo(bundleName, innerBundleInfo)) {
149 APP_LOGE("bundleName %{public}s not exist", bundleName.c_str());
150 return false;
151 }
152
153 std::vector<ResourceInfo> resourceInfos;
154 if (GetAbilityResourceInfos(innerBundleInfo, userId, resourceInfos)) {
155 for (const auto &info : resourceInfos) {
156 if ((info.moduleName_ == moduleName) && (info.abilityName_ == abilityName)) {
157 resourceInfo = info;
158 return true;
159 }
160 }
161 }
162 APP_LOGE("bundleName %{public}s, moduleName %{public}s, abilityName %{public}s not exist",
163 bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
164 return false;
165 }
166
GetResourceInfoByColorModeChanged(const std::vector<std::string> & resourceNames,const int32_t userId,std::vector<ResourceInfo> & resourceInfos)167 bool BundleResourceProcess::GetResourceInfoByColorModeChanged(
168 const std::vector<std::string> &resourceNames,
169 const int32_t userId,
170 std::vector<ResourceInfo> &resourceInfos)
171 {
172 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
173 if (dataMgr == nullptr) {
174 APP_LOGE("dataMgr is nullptr");
175 return false;
176 }
177 const std::map<std::string, InnerBundleInfo> bundleInfos = dataMgr->GetAllInnerBundleInfos();
178 std::vector<std::string> bundleNames;
179 for (const auto &item : bundleInfos) {
180 bundleNames.emplace_back(item.first);
181 InnerBundleUserInfo innerBundleUserInfo;
182 if (item.second.GetInnerBundleUserInfo(userId, innerBundleUserInfo) &&
183 !innerBundleUserInfo.cloneInfos.empty()) {
184 // need process clone app resource
185 APP_LOGI("bundleName:%{public}s has clone info", item.first.c_str());
186 for (const auto &clone : innerBundleUserInfo.cloneInfos) {
187 bundleNames.emplace_back(std::to_string(clone.second.appIndex) + INNER_UNDER_LINE + item.first);
188 }
189 }
190 }
191 std::set<std::string> needAddResourceBundles;
192 for (const auto &bundleName : bundleNames) {
193 if (std::find(resourceNames.begin(), resourceNames.end(), bundleName) == resourceNames.end()) {
194 ResourceInfo info;
195 info.ParseKey(bundleName);
196 needAddResourceBundles.insert(info.bundleName_);
197 }
198 }
199 if (needAddResourceBundles.empty()) {
200 APP_LOGW("needAddResourceBundles is empty");
201 return true;
202 }
203
204 for (const auto &bundleName : needAddResourceBundles) {
205 if (!GetResourceInfoByBundleName(bundleName, userId, resourceInfos)) {
206 APP_LOGW("bundleName %{public}s GetResourceInfoByBundleName failed", bundleName.c_str());
207 }
208 }
209 return true;
210 }
211
ChangeDynamicIcon(std::vector<ResourceInfo> & resourceInfos,const ResourceInfo & resourceInfo)212 void BundleResourceProcess::ChangeDynamicIcon(
213 std::vector<ResourceInfo> &resourceInfos, const ResourceInfo &resourceInfo)
214 {
215 for (auto &info : resourceInfos) {
216 info.icon_ = resourceInfo.icon_;
217 info.foreground_ = resourceInfo.foreground_;
218 info.background_ = resourceInfo.background_;
219 info.iconNeedParse_ = false;
220 }
221 }
222
GetDynamicIcon(const InnerBundleInfo & innerBundleInfo,const int32_t userId,ResourceInfo & resourceInfo)223 bool BundleResourceProcess::GetDynamicIcon(
224 const InnerBundleInfo &innerBundleInfo, const int32_t userId, ResourceInfo &resourceInfo)
225 {
226 std::string curDynamicIconModule = innerBundleInfo.GetCurDynamicIconModule(userId, resourceInfo.appIndex_);
227 if (curDynamicIconModule.empty()) {
228 APP_LOGD("-n %{public}s no curDynamicIconModule, %{public}d", innerBundleInfo.GetBundleName().c_str(),
229 resourceInfo.appIndex_);
230 return false;
231 }
232 // need check theme
233 bool isOnlineTheme = false;
234 if (BundleResourceProcess::CheckThemeType(innerBundleInfo.GetBundleName(), userId, isOnlineTheme) &&
235 isOnlineTheme) {
236 APP_LOGW("-n %{public}s -u %{public}d exist dynamic icon, but online theme first",
237 innerBundleInfo.GetBundleName().c_str(), resourceInfo.appIndex_);
238 return false;
239 }
240 std::map<std::string, ExtendResourceInfo> extResourceInfos = innerBundleInfo.GetExtendResourceInfos();
241 auto iter = extResourceInfos.find(curDynamicIconModule);
242 if (iter == extResourceInfos.end()) {
243 APP_LOGE("-n %{public}s Module not exist %{public}s", innerBundleInfo.GetBundleName().c_str(),
244 curDynamicIconModule.c_str());
245 return false;
246 }
247 auto &extendResourceInfo = iter->second;
248 BundleResourceParser parser;
249 if (!parser.ParseIconResourceByPath(extendResourceInfo.filePath, extendResourceInfo.iconId, resourceInfo)) {
250 APP_LOGE("bundleName:%{public}s parse dynamicIcon failed, iconId:%{public}d",
251 innerBundleInfo.GetBundleName().c_str(), extendResourceInfo.iconId);
252 return false;
253 }
254 return true;
255 }
256
GetDynamicIconResourceInfo(const std::string & bundleName,const std::string & dynamicModuleName,ResourceInfo & resourceInfo)257 bool BundleResourceProcess::GetDynamicIconResourceInfo(const std::string &bundleName,
258 const std::string &dynamicModuleName, ResourceInfo &resourceInfo)
259 {
260 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
261 if (dataMgr == nullptr) {
262 APP_LOGE("dataMgr is nullptr");
263 return false;
264 }
265 ExtendResourceInfo extendResourceInfo;
266 if (dataMgr->GetExtendResourceInfo(bundleName, dynamicModuleName, extendResourceInfo) != ERR_OK) {
267 APP_LOGE("GetExtendResourceInfo failed -n %{public}s -m %{public}s",
268 bundleName.c_str(), dynamicModuleName.c_str());
269 return false;
270 }
271 BundleResourceParser parser;
272 if (!parser.ParseIconResourceByPath(extendResourceInfo.filePath, extendResourceInfo.iconId, resourceInfo)) {
273 APP_LOGE("-n %{public}s parse dynamicIcon failed, iconId:%{public}d",
274 bundleName.c_str(), extendResourceInfo.iconId);
275 return false;
276 }
277 return true;
278 }
279
InnerGetResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId,std::vector<ResourceInfo> & resourceInfos,const int32_t appIndex,bool needParseDynamic)280 bool BundleResourceProcess::InnerGetResourceInfo(
281 const InnerBundleInfo &innerBundleInfo,
282 const int32_t userId,
283 std::vector<ResourceInfo> &resourceInfos,
284 const int32_t appIndex,
285 bool needParseDynamic)
286 {
287 if (!OnGetResourceInfo(innerBundleInfo, userId, resourceInfos)) {
288 APP_LOGE("-n %{public}s -u %{public}d -i %{public}d no resource", innerBundleInfo.GetBundleName().c_str(),
289 userId, appIndex);
290 return false;
291 }
292 if (needParseDynamic) {
293 ResourceInfo dynamicResourceInfo;
294 dynamicResourceInfo.bundleName_ = innerBundleInfo.GetBundleName();
295 dynamicResourceInfo.appIndex_ = appIndex;
296 bool hasDynamicIcon = GetDynamicIcon(innerBundleInfo, userId, dynamicResourceInfo);
297 if (hasDynamicIcon) {
298 APP_LOGI("-n %{public}s -u %{public}d -i %{public}d has dynamicIcon",
299 innerBundleInfo.GetBundleName().c_str(), userId, appIndex);
300 ChangeDynamicIcon(resourceInfos, dynamicResourceInfo);
301 }
302 }
303 // for clone bundle
304 std::set<int32_t> appIndexes = innerBundleInfo.GetCloneBundleAppIndexes();
305 if (!appIndexes.empty()) {
306 APP_LOGI("bundleName:%{public}s contains clone bundle", innerBundleInfo.GetBundleName().c_str());
307 std::vector<int32_t> indexes(appIndexes.begin(), appIndexes.end());
308 for (auto &info : resourceInfos) {
309 info.appIndexes_ = indexes;
310 }
311 }
312 return true;
313 }
314
OnGetResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId,std::vector<ResourceInfo> & resourceInfos)315 bool BundleResourceProcess::OnGetResourceInfo(
316 const InnerBundleInfo &innerBundleInfo,
317 const int32_t userId,
318 std::vector<ResourceInfo> &resourceInfos)
319 {
320 std::string bundleName = innerBundleInfo.GetBundleName();
321 APP_LOGD("start, bundleName:%{public}s", bundleName.c_str());
322 // get bundle
323 ResourceInfo bundleResourceInfo;
324 if (!GetBundleResourceInfo(innerBundleInfo, userId, bundleResourceInfo)) {
325 APP_LOGW("%{public}s get resource failed", bundleName.c_str());
326 return false;
327 }
328 resourceInfos.push_back(bundleResourceInfo);
329
330 // get ability
331 std::vector<ResourceInfo> abilityResourceInfos;
332 if (GetAbilityResourceInfos(innerBundleInfo, userId, abilityResourceInfos)) {
333 for (const auto &info : abilityResourceInfos) {
334 resourceInfos.push_back(info);
335 }
336 }
337 APP_LOGI_NOFUNC("OnGetResourceInfo -n %{public}s size:%{public}d", bundleName.c_str(),
338 static_cast<int32_t>(resourceInfos.size()));
339 return !resourceInfos.empty();
340 }
341
ConvertToLauncherAbilityResourceInfo(const AbilityInfo & info)342 ResourceInfo BundleResourceProcess::ConvertToLauncherAbilityResourceInfo(const AbilityInfo &info)
343 {
344 ResourceInfo resourceInfo;
345 resourceInfo.bundleName_ = info.bundleName;
346 resourceInfo.moduleName_ = info.moduleName;
347 resourceInfo.abilityName_ = info.name;
348 resourceInfo.labelId_ = info.labelId;
349 resourceInfo.iconId_ = info.iconId;
350 resourceInfo.hapPath_ = info.hapPath;
351 resourceInfo.extensionAbilityType_ = -1;
352 return resourceInfo;
353 }
354
ConvertToBundleResourceInfo(const InnerBundleInfo & innerBundleInfo)355 ResourceInfo BundleResourceProcess::ConvertToBundleResourceInfo(const InnerBundleInfo &innerBundleInfo)
356 {
357 ApplicationInfo appInfo = innerBundleInfo.GetBaseApplicationInfo();
358 innerBundleInfo.AdaptMainLauncherResourceInfo(appInfo);
359 ResourceInfo resourceInfo;
360 resourceInfo.bundleName_ = innerBundleInfo.GetBundleName();
361 resourceInfo.labelId_ = appInfo.labelResource.id;
362 resourceInfo.iconId_ = appInfo.iconResource.id;
363 const auto &moduleName = appInfo.labelResource.moduleName;
364 const auto &moduleInfos = innerBundleInfo.GetInnerModuleInfos();
365 for (const auto &iter : moduleInfos) {
366 if (iter.second.moduleName == moduleName) {
367 resourceInfo.hapPath_ = iter.second.hapPath;
368 break;
369 }
370 }
371 resourceInfo.moduleName_ = moduleName;
372 resourceInfo.abilityName_ = std::string();
373 return resourceInfo;
374 }
375
ConvertToExtensionAbilityResourceInfo(const ExtensionAbilityInfo & info)376 ResourceInfo BundleResourceProcess::ConvertToExtensionAbilityResourceInfo(const ExtensionAbilityInfo &info)
377 {
378 ResourceInfo resourceInfo;
379 resourceInfo.bundleName_ = info.bundleName;
380 resourceInfo.moduleName_ = info.moduleName;
381 resourceInfo.abilityName_ = info.name;
382 resourceInfo.labelId_ = info.labelId;
383 resourceInfo.iconId_ = info.iconId;
384 resourceInfo.hapPath_ = info.hapPath;
385 resourceInfo.extensionAbilityType_ = static_cast<int32_t>(info.type);
386 return resourceInfo;
387 }
388
389
GetLauncherAbilityResourceInfos(const InnerBundleInfo & innerBundleInfo,const int32_t userId,std::vector<ResourceInfo> & resourceInfos)390 bool BundleResourceProcess::GetLauncherAbilityResourceInfos(
391 const InnerBundleInfo &innerBundleInfo,
392 const int32_t userId,
393 std::vector<ResourceInfo> &resourceInfos)
394 {
395 APP_LOGD("start get ability, bundleName:%{public}s", innerBundleInfo.GetBundleName().c_str());
396 if (!CheckIsNeedProcessAbilityResource(innerBundleInfo)) {
397 APP_LOGW("%{public}s no need add ability resource", innerBundleInfo.GetBundleName().c_str());
398 return false;
399 }
400
401 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
402 if (dataMgr == nullptr) {
403 APP_LOGE("dataMgr is nullptr");
404 return false;
405 }
406 OHOS::AAFwk::Want want;
407 want.SetAction(OHOS::AAFwk::Want::ACTION_HOME);
408 want.AddEntity(OHOS::AAFwk::Want::ENTITY_HOME);
409 std::vector<AbilityInfo> abilityInfos;
410 int64_t time = 0;
411 dataMgr->GetMatchLauncherAbilityInfos(want, innerBundleInfo, abilityInfos, time, userId);
412
413 if (abilityInfos.empty()) {
414 APP_LOGW("%{public}s no launcher ability Info", innerBundleInfo.GetBundleName().c_str());
415 return false;
416 }
417 for (const auto &info : abilityInfos) {
418 resourceInfos.push_back(ConvertToLauncherAbilityResourceInfo(info));
419 }
420 // process overlay hap paths
421 size_t size = resourceInfos.size();
422 for (size_t index = 0; index < size; ++index) {
423 if ((index > 0) && (resourceInfos[index].moduleName_ == resourceInfos[index - 1].moduleName_)) {
424 resourceInfos[index].overlayHapPaths_ = resourceInfos[index - 1].overlayHapPaths_;
425 continue;
426 }
427 GetOverlayModuleHapPaths(innerBundleInfo, resourceInfos[index].moduleName_,
428 userId, resourceInfos[index].overlayHapPaths_);
429 }
430
431 APP_LOGD("end get ability, size:%{public}zu, bundleName:%{public}s", resourceInfos.size(),
432 innerBundleInfo.GetBundleName().c_str());
433 return !resourceInfos.empty();
434 }
435
CheckIsNeedProcessAbilityResource(const InnerBundleInfo & innerBundleInfo)436 bool BundleResourceProcess::CheckIsNeedProcessAbilityResource(const InnerBundleInfo &innerBundleInfo)
437 {
438 if (innerBundleInfo.GetBundleName().empty()) {
439 APP_LOGE("bundleName is empty");
440 return false;
441 }
442 if (innerBundleInfo.GetApplicationBundleType() == BundleType::SHARED) {
443 APP_LOGD("bundleName:%{public}s is shared", innerBundleInfo.GetBundleName().c_str());
444 return false;
445 }
446 if (innerBundleInfo.GetBaseApplicationInfo().hideDesktopIcon) {
447 APP_LOGD("bundleName:%{public}s hide desktop icon", innerBundleInfo.GetBundleName().c_str());
448 return false;
449 }
450 if (innerBundleInfo.GetBaseBundleInfo().entryInstallationFree) {
451 APP_LOGD("bundleName:%{public}s is atomic service, hide desktop icon",
452 innerBundleInfo.GetBundleName().c_str());
453 return false;
454 }
455 return true;
456 }
457
GetOverlayModuleHapPaths(const InnerBundleInfo & innerBundleInfo,const std::string & moduleName,int32_t userId,std::vector<std::string> & overlayHapPaths)458 bool BundleResourceProcess::GetOverlayModuleHapPaths(
459 const InnerBundleInfo &innerBundleInfo,
460 const std::string &moduleName,
461 int32_t userId,
462 std::vector<std::string> &overlayHapPaths)
463 {
464 #ifdef BUNDLE_FRAMEWORK_OVERLAY_INSTALLATION
465 auto innerModuleInfo = innerBundleInfo.GetInnerModuleInfoByModuleName(moduleName);
466 if (innerModuleInfo == std::nullopt) {
467 APP_LOGE("moduleName %{public}s not exist", moduleName.c_str());
468 return false;
469 }
470 if (innerModuleInfo->overlayModuleInfo.empty()) {
471 APP_LOGD("moduleName:%{public}s has no overlay module", moduleName.c_str());
472 return false;
473 }
474 std::string bundleName = innerBundleInfo.GetBundleName();
475 APP_LOGI("bundleName %{public}s need add path", bundleName.c_str());
476 auto overlayModuleInfos = innerModuleInfo->overlayModuleInfo;
477 for (auto &info : overlayModuleInfos) {
478 if (info.bundleName == bundleName) {
479 innerBundleInfo.GetOverlayModuleState(info.moduleName, userId, info.state);
480 } else {
481 GetExternalOverlayHapState(info.bundleName, info.moduleName, userId, info.state);
482 }
483 }
484 // sort by priority
485 std::sort(overlayModuleInfos.begin(), overlayModuleInfos.end(),
486 [](const OverlayModuleInfo &lhs, const OverlayModuleInfo &rhs) -> bool {
487 return lhs.priority > rhs.priority;
488 });
489 for (const auto &info : overlayModuleInfos) {
490 if (info.state == OverlayState::OVERLAY_ENABLE) {
491 overlayHapPaths.emplace_back(info.hapPath);
492 }
493 }
494 if (overlayHapPaths.empty()) {
495 APP_LOGE("moduleName %{public}s overlay hap path empty", moduleName.c_str());
496 return false;
497 }
498 return true;
499 #endif
500 return true;
501 }
502
GetExternalOverlayHapState(const std::string & bundleName,const std::string & moduleName,const int32_t userId,int32_t & state)503 bool BundleResourceProcess::GetExternalOverlayHapState(const std::string &bundleName,
504 const std::string &moduleName, const int32_t userId, int32_t &state)
505 {
506 #ifdef BUNDLE_FRAMEWORK_OVERLAY_INSTALLATION
507 APP_LOGD("bundleName:%{public}s, moduleName:%{public}s get overlay state", bundleName.c_str(), moduleName.c_str());
508 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
509 if (dataMgr == nullptr) {
510 APP_LOGE("dataMgr is nullptr");
511 return false;
512 }
513 InnerBundleInfo bundleInfo;
514 if (!dataMgr->QueryOverlayInnerBundleInfo(bundleName, bundleInfo)) {
515 return false;
516 }
517 if (!bundleInfo.GetOverlayModuleState(moduleName, userId, state)) {
518 return false;
519 }
520 return true;
521 #endif
522 return true;
523 }
524
GetAbilityResourceInfos(const InnerBundleInfo & innerBundleInfo,const int32_t userId,std::vector<ResourceInfo> & resourceInfos)525 bool BundleResourceProcess::GetAbilityResourceInfos(
526 const InnerBundleInfo &innerBundleInfo,
527 const int32_t userId,
528 std::vector<ResourceInfo> &resourceInfos)
529 {
530 APP_LOGD("start get ability, bundleName:%{public}s", innerBundleInfo.GetBundleName().c_str());
531 if (innerBundleInfo.GetBundleName().empty()) {
532 APP_LOGE("bundleName is empty");
533 return false;
534 }
535 if (innerBundleInfo.GetApplicationBundleType() == BundleType::SHARED) {
536 APP_LOGW("bundleName:%{public}s is shared bundle, no ability", innerBundleInfo.GetBundleName().c_str());
537 return false;
538 }
539 std::map<std::string, InnerAbilityInfo> innerAbilityInfos = innerBundleInfo.GetInnerAbilityInfos();
540 for (const auto &item : innerAbilityInfos) {
541 AbilityInfo abilityInfo = InnerAbilityInfo::ConvertToAbilityInfo(item.second);
542 resourceInfos.emplace_back(ConvertToLauncherAbilityResourceInfo(abilityInfo));
543 }
544 std::map<std::string, InnerExtensionInfo> extensionAbilityInfos = innerBundleInfo.GetInnerExtensionInfos();
545 for (const auto &item : extensionAbilityInfos) {
546 if (item.second.type != ExtensionAbilityType::INPUTMETHOD &&
547 item.second.type != ExtensionAbilityType::SHARE &&
548 item.second.type != ExtensionAbilityType::ACTION) {
549 APP_LOGD("skip extension type %{public}d", item.second.type);
550 continue;
551 }
552 ExtensionAbilityInfo extensionInfo = InnerExtensionInfo::ConvertToExtensionInfo(item.second);
553 resourceInfos.emplace_back(ConvertToExtensionAbilityResourceInfo(extensionInfo));
554 }
555 // process overlay hap paths
556 size_t size = resourceInfos.size();
557 for (size_t index = 0; index < size; ++index) {
558 if ((index > 0) && (resourceInfos[index].moduleName_ == resourceInfos[index - 1].moduleName_)) {
559 resourceInfos[index].overlayHapPaths_ = resourceInfos[index - 1].overlayHapPaths_;
560 continue;
561 }
562 GetOverlayModuleHapPaths(innerBundleInfo, resourceInfos[index].moduleName_,
563 userId, resourceInfos[index].overlayHapPaths_);
564 }
565
566 APP_LOGD("end get ability, size:%{public}zu, bundleName:%{public}s", resourceInfos.size(),
567 innerBundleInfo.GetBundleName().c_str());
568 return !resourceInfos.empty();
569 }
570
GetTargetBundleName(const std::string & bundleName,std::string & targetBundleName)571 void BundleResourceProcess::GetTargetBundleName(const std::string &bundleName,
572 std::string &targetBundleName)
573 {
574 targetBundleName = bundleName;
575 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
576 if (dataMgr == nullptr) {
577 APP_LOGE("dataMgr is nullptr");
578 return;
579 }
580 InnerBundleInfo bundleInfo;
581 if (!dataMgr->QueryOverlayInnerBundleInfo(bundleName, bundleInfo)) {
582 return;
583 }
584 if (bundleInfo.GetOverlayType() == OverlayType::OVERLAY_EXTERNAL_BUNDLE) {
585 targetBundleName = bundleInfo.GetTargetBundleName();
586 }
587 }
588
GetAppIndexByBundleName(const std::string & bundleName)589 std::set<int32_t> BundleResourceProcess::GetAppIndexByBundleName(const std::string &bundleName)
590 {
591 std::set<int32_t> appIndexes;
592 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
593 if (dataMgr == nullptr) {
594 APP_LOGE("dataMgr is nullptr");
595 return appIndexes;
596 }
597 return dataMgr->GetCloneAppIndexes(bundleName);
598 }
599
GetCurDynamicIconModule(const std::string & bundleName,const int32_t userId,const int32_t appIndex)600 std::string BundleResourceProcess::GetCurDynamicIconModule(
601 const std::string &bundleName, const int32_t userId, const int32_t appIndex)
602 {
603 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
604 if (dataMgr == nullptr) {
605 APP_LOGE("dataMgr is nullptr");
606 return Constants::EMPTY_STRING;
607 }
608 return dataMgr->GetCurDynamicIconModule(bundleName, userId, appIndex);
609 }
610
GetExtendResourceInfo(const std::string & bundleName,const std::string & moduleName,ExtendResourceInfo & extendResourceInfo)611 bool BundleResourceProcess::GetExtendResourceInfo(const std::string &bundleName,
612 const std::string &moduleName, ExtendResourceInfo &extendResourceInfo)
613 {
614 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
615 if (dataMgr == nullptr) {
616 APP_LOGE("dataMgr is nullptr");
617 return false;
618 }
619
620 InnerBundleInfo info;
621 if (!dataMgr->FetchInnerBundleInfo(bundleName, info)) {
622 APP_LOGE("-n %{public}s not exist", bundleName.c_str());
623 return false;
624 }
625
626 std::map<std::string, ExtendResourceInfo> extendResourceInfos = info.GetExtendResourceInfos();
627 if (extendResourceInfos.empty()) {
628 APP_LOGE("%{public}s no extend Resources", bundleName.c_str());
629 return false;
630 }
631 auto iter = extendResourceInfos.find(moduleName);
632 if (iter == extendResourceInfos.end()) {
633 APP_LOGE("%{public}s no %{public}s extend Resources", bundleName.c_str(), moduleName.c_str());
634 return false;
635 }
636 extendResourceInfo = iter->second;
637 return true;
638 }
639
CheckThemeType(const std::string & bundleName,const int32_t userId,bool & isOnlineTheme)640 bool BundleResourceProcess::CheckThemeType(
641 const std::string &bundleName, const int32_t userId, bool &isOnlineTheme)
642 {
643 if (BundleUtil::IsExistFileNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_A_FLAG)) {
644 // flag exist in "/data/service/el1/public/themes/<userId>/a/app/flag"
645 if (BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_A + bundleName)) {
646 isOnlineTheme = IsOnlineTheme(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_A +
647 THEME_DESCRIPTION_FILE);
648 return true;
649 }
650 APP_LOGW("-n %{public}s -u %{public}d does not exist in theme a", bundleName.c_str(), userId);
651 return false;
652 }
653 // flag exist in "/data/service/el1/public/themes/<userId>/b/app/flag"
654 if (BundleUtil::IsExistDirNoLog(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_B + bundleName)) {
655 isOnlineTheme = IsOnlineTheme(SYSTEM_THEME_PATH + std::to_string(userId) + THEME_ICONS_B +
656 THEME_DESCRIPTION_FILE);
657 return true;
658 }
659 APP_LOGW("-n %{public}s -u %{public}d does not exist in theme b", bundleName.c_str(), userId);
660 return false;
661 }
662
IsOnlineTheme(const std::string & themePath)663 bool BundleResourceProcess::IsOnlineTheme(const std::string &themePath)
664 {
665 // read description.json
666 nlohmann::json jsonBuf;
667 if (!BundleParser::ReadFileIntoJson(themePath, jsonBuf)) {
668 APP_LOGW("themePath %{public}s read failed, errno %{public}d", themePath.c_str(), errno);
669 return false;
670 }
671 int32_t parseResult = ERR_OK;
672 std::string themeType;
673 const auto &jsonObjectEnd = jsonBuf.end();
674 BMSJsonUtil::GetStrValueIfFindKey(jsonBuf, jsonObjectEnd, THEME_KEY_ORIGIN, themeType, false, parseResult);
675 if (themeType == THEME_KEY_THEME_TYPE_ONLINE) {
676 APP_LOGI("online theme first");
677 return true;
678 }
679 return false;
680 }
681 } // AppExecFwk
682 } // OHOS
683