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_process.h"
17
18 #include <mutex>
19
20 #include "ability_info.h"
21 #include "account_helper.h"
22 #include "app_log_wrapper.h"
23 #include "bundle_constants.h"
24 #include "bundle_data_mgr.h"
25 #include "bundle_mgr_service.h"
26
27 namespace OHOS {
28 namespace AppExecFwk {
29 namespace {
30 std::mutex g_systemResLock;
31 constexpr const char* GLOBAL_RESOURCE_BUNDLE_NAME = "ohos.global.systemres";
32 const std::string INNER_UNDER_LINE = "_";
33 }
34 std::string BundleResourceProcess::systemResourceHap_ = "";
35 int32_t BundleResourceProcess::defaultIconId_ = 0;
36
GetLauncherAbilityResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId,std::vector<ResourceInfo> & resourceInfos)37 bool BundleResourceProcess::GetLauncherAbilityResourceInfo(const InnerBundleInfo &innerBundleInfo,
38 const int32_t userId,
39 std::vector<ResourceInfo> &resourceInfos)
40 {
41 if (innerBundleInfo.GetBundleName().empty()) {
42 APP_LOGE("bundleName is empty");
43 return false;
44 }
45
46 if (innerBundleInfo.GetApplicationBundleType() == BundleType::SHARED) {
47 APP_LOGD("bundleName:%{public}s is shared", innerBundleInfo.GetBundleName().c_str());
48 return false;
49 }
50
51 if (innerBundleInfo.GetBaseApplicationInfo().hideDesktopIcon) {
52 APP_LOGD("bundleName:%{public}s hide desktop icon", innerBundleInfo.GetBundleName().c_str());
53 return false;
54 }
55
56 if (innerBundleInfo.GetBaseBundleInfo().entryInstallationFree) {
57 APP_LOGD("bundleName:%{public}s is atomic service, hide desktop icon", innerBundleInfo.GetBundleName().c_str());
58 return false;
59 }
60
61 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
62 if (dataMgr == nullptr) {
63 return false;
64 }
65 OHOS::AAFwk::Want want;
66 want.SetAction(Want::ACTION_HOME);
67 want.AddEntity(Want::ENTITY_HOME);
68 std::vector<AbilityInfo> abilityInfos;
69 int64_t time = GetUpdateTime(innerBundleInfo, userId);
70 dataMgr->GetMatchLauncherAbilityInfos(want, innerBundleInfo, abilityInfos, time, userId);
71
72 if (abilityInfos.empty()) {
73 APP_LOGW("bundleName: %{public}s no launcher ability Info", innerBundleInfo.GetBundleName().c_str());
74 return false;
75 }
76
77 for (const auto &info : abilityInfos) {
78 if (!info.applicationInfo.enabled) {
79 continue;
80 }
81 if (!innerBundleInfo.IsAbilityEnabled(info, innerBundleInfo.GetResponseUserId(userId))) {
82 APP_LOGW("abilityName: %{public}s is disabled", info.name.c_str());
83 continue;
84 }
85 resourceInfos.push_back(ConvertToLauncherAbilityResourceInfo(info));
86 }
87 return true;
88 }
89
GetBundleResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId,ResourceInfo & resourceInfo)90 bool BundleResourceProcess::GetBundleResourceInfo(const InnerBundleInfo &innerBundleInfo,
91 const int32_t userId,
92 ResourceInfo &resourceInfo)
93 {
94 if (innerBundleInfo.GetBundleName().empty()) {
95 APP_LOGE("bundleName is empty");
96 return false;
97 }
98 if (innerBundleInfo.GetApplicationBundleType() == BundleType::SHARED) {
99 APP_LOGD("bundleName:%{public}s is shared", innerBundleInfo.GetBundleName().c_str());
100 return false;
101 }
102 resourceInfo = ConvertToBundleResourceInfo(innerBundleInfo, userId);
103
104 return true;
105 }
106
GetResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId,std::vector<ResourceInfo> & resourceInfo)107 bool BundleResourceProcess::GetResourceInfo(
108 const InnerBundleInfo &innerBundleInfo,
109 const int32_t userId,
110 std::vector<ResourceInfo> &resourceInfo)
111 {
112 if (userId != Constants::DEFAULT_USERID) {
113 int32_t currentUserId = AccountHelper::GetCurrentActiveUserId();
114 if ((currentUserId > 0) && (currentUserId != userId)) {
115 APP_LOGW("userId not same, userId: %{public}d, currentUserId :%{public}d", userId, currentUserId);
116 return false;
117 }
118 }
119
120 if (!IsBundleExist(innerBundleInfo, userId)) {
121 APP_LOGW("bundle %{public}s is not exist in userId: %{public}d",
122 innerBundleInfo.GetBundleName().c_str(), userId);
123 return false;
124 }
125
126 return InnerGetResourceInfo(innerBundleInfo, userId, resourceInfo);
127 }
128
GetAllResourceInfo(const int32_t userId,std::vector<ResourceInfo> & resourceInfos)129 bool BundleResourceProcess::GetAllResourceInfo(
130 const int32_t userId,
131 std::vector<ResourceInfo> &resourceInfos)
132 {
133 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
134 if (dataMgr == nullptr) {
135 APP_LOGE("dataMgr is nullptr");
136 return false;
137 }
138 auto userIds = dataMgr->GetAllUser();
139 if (userIds.find(userId) == userIds.end()) {
140 APP_LOGE("userId: %{public}d is not exist", userId);
141 return false;
142 }
143 const std::map<std::string, InnerBundleInfo> bundleInfos = dataMgr->GetAllInnerBundleInfos();
144 if (bundleInfos.empty()) {
145 APP_LOGE("bundleInfos is empty");
146 return false;
147 }
148
149 for (const auto &item : bundleInfos) {
150 if (item.second.IsDisabled()) {
151 APP_LOGD("bundle %{public}s is disabled", item.second.GetBundleName().c_str());
152 continue;
153 }
154 if (!IsBundleExist(item.second, userId)) {
155 APP_LOGD("bundle %{public}s is not exist in userId: %{public}d",
156 item.second.GetBundleName().c_str(), userId);
157 continue;
158 }
159 if (!item.second.GetApplicationEnabled(item.second.GetResponseUserId(userId))) {
160 APP_LOGD("bundle %{public}s is disabled in userId: %{public}d",
161 item.second.GetBundleName().c_str(), userId);
162 continue;
163 }
164 if (!InnerGetResourceInfo(item.second, userId, resourceInfos)) {
165 APP_LOGW("bundle %{public}s resourceInfo is empty", item.second.GetBundleName().c_str());
166 }
167 }
168 return true;
169 }
170
GetResourceInfoByBundleName(const std::string & bundleName,const int32_t userId,std::vector<ResourceInfo> & resourceInfo)171 bool BundleResourceProcess::GetResourceInfoByBundleName(
172 const std::string &bundleName,
173 const int32_t userId,
174 std::vector<ResourceInfo> &resourceInfo)
175 {
176 APP_LOGD("start, bundleName:%{public}s", bundleName.c_str());
177 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
178 if (dataMgr == nullptr) {
179 APP_LOGE("dataMgr is nullptr");
180 return false;
181 }
182 const std::map<std::string, InnerBundleInfo> bundleInfos = dataMgr->GetAllInnerBundleInfos();
183 auto item = bundleInfos.find(bundleName);
184 if (item == bundleInfos.end()) {
185 APP_LOGE("bundleName %{public}s is not exist", bundleName.c_str());
186 return false;
187 }
188
189 if (!IsBundleExist(item->second, userId)) {
190 APP_LOGW("bundle %{public}s is not exist in userId: %{public}d",
191 item->second.GetBundleName().c_str(), userId);
192 return false;
193 }
194
195 if (!item->second.GetApplicationEnabled(item->second.GetResponseUserId(userId))) {
196 APP_LOGW("bundle %{public}s is disabled in userId:%{public}d",
197 item->second.GetBundleName().c_str(), userId);
198 return false;
199 }
200
201 return InnerGetResourceInfo(item->second, userId, resourceInfo);
202 }
203
GetResourceInfoByAbilityName(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const int32_t userId,ResourceInfo & resourceInfo)204 bool BundleResourceProcess::GetResourceInfoByAbilityName(
205 const std::string &bundleName,
206 const std::string &moduleName,
207 const std::string &abilityName,
208 const int32_t userId,
209 ResourceInfo &resourceInfo)
210 {
211 APP_LOGD("start, bundleName:%{public}s, moduleName:%{public}s, abilityName:%{public}s",
212 bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
213 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
214 if (dataMgr == nullptr) {
215 APP_LOGE("dataMgr is nullptr");
216 return false;
217 }
218 const std::map<std::string, InnerBundleInfo> bundleInfos = dataMgr->GetAllInnerBundleInfos();
219 auto item = bundleInfos.find(bundleName);
220 if (item == bundleInfos.end()) {
221 APP_LOGE("bundleName %{public}s is not exist", bundleName.c_str());
222 return false;
223 }
224 if (!IsBundleExist(item->second, userId)) {
225 APP_LOGW("bundle %{public}s is not exist in userId: %{public}d",
226 item->second.GetBundleName().c_str(), userId);
227 return false;
228 }
229 if (item->second.IsDisabled()) {
230 APP_LOGD("bundle %{public}s is disabled", item->second.GetBundleName().c_str());
231 return false;
232 }
233 std::vector<ResourceInfo> resourceInfos;
234 if (GetLauncherAbilityResourceInfo(item->second, userId, resourceInfos)) {
235 for (const auto &info : resourceInfos) {
236 if ((info.moduleName_ == moduleName) && (info.abilityName_ == abilityName)) {
237 resourceInfo = info;
238 return true;
239 }
240 }
241 }
242 APP_LOGE("bundleName %{public}s, moduleName: %{public}s, abilityName:%{public}s is not exist",
243 bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
244 return false;
245 }
246
GetResourceInfoByColorModeChanged(const std::vector<std::string> & resourceNames,std::vector<ResourceInfo> & resourceInfos)247 bool BundleResourceProcess::GetResourceInfoByColorModeChanged(
248 const std::vector<std::string> &resourceNames,
249 std::vector<ResourceInfo> &resourceInfos)
250 {
251 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
252 if (dataMgr == nullptr) {
253 APP_LOGE("dataMgr is nullptr");
254 return false;
255 }
256 std::vector<std::string> bundleNames = dataMgr->GetAllBundleName();
257 std::vector<std::string> needAddResourceBundles;
258 for (const auto &bundleName : bundleNames) {
259 if (std::find(resourceNames.begin(), resourceNames.end(), bundleName) == resourceNames.end()) {
260 needAddResourceBundles.push_back(bundleName);
261 }
262 }
263 if (needAddResourceBundles.empty()) {
264 APP_LOGW("needAddResourceBundles is empty");
265 return true;
266 }
267
268 int32_t currentUserId = AccountHelper::GetCurrentActiveUserId();
269 if (currentUserId <= 0) {
270 currentUserId = Constants::START_USERID;
271 }
272 for (const auto &bundleName : needAddResourceBundles) {
273 if (!GetResourceInfoByBundleName(bundleName, currentUserId, resourceInfos)) {
274 APP_LOGW("bundleName: %{public}s GetResourceInfoByBundleName failed.", bundleName.c_str());
275 }
276 }
277 return true;
278 }
279
InnerGetResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId,std::vector<ResourceInfo> & resourceInfos)280 bool BundleResourceProcess::InnerGetResourceInfo(
281 const InnerBundleInfo &innerBundleInfo,
282 const int32_t userId,
283 std::vector<ResourceInfo> &resourceInfos)
284 {
285 APP_LOGD("start, bundleName:%{public}s", innerBundleInfo.GetBundleName().c_str());
286 ResourceInfo bundleResourceInfo;
287 if (GetBundleResourceInfo(innerBundleInfo, userId, bundleResourceInfo)) {
288 resourceInfos.push_back(bundleResourceInfo);
289 }
290
291 std::vector<ResourceInfo> launcherAbilityResourceInfos;
292 if (GetLauncherAbilityResourceInfo(innerBundleInfo, userId, launcherAbilityResourceInfos)) {
293 for (const auto &info : launcherAbilityResourceInfos) {
294 resourceInfos.push_back(info);
295 }
296 }
297 APP_LOGI("end, bundleName:%{public}s, resourceInfo.size:%{public}d", innerBundleInfo.GetBundleName().c_str(),
298 static_cast<int32_t>(resourceInfos.size()));
299 return !resourceInfos.empty();
300 }
301
IsBundleExist(const InnerBundleInfo & innerBundleInfo,const int32_t userId)302 bool BundleResourceProcess::IsBundleExist(const InnerBundleInfo &innerBundleInfo, const int32_t userId)
303 {
304 int32_t responseUserId = innerBundleInfo.GetResponseUserId(userId);
305 return responseUserId != Constants::INVALID_USERID;
306 }
307
GetUpdateTime(const InnerBundleInfo & innerBundleInfo,const int32_t userId)308 int64_t BundleResourceProcess::GetUpdateTime(const InnerBundleInfo &innerBundleInfo, const int32_t userId)
309 {
310 // get installTime from innerBundleUserInfo
311 std::string userIdKey = innerBundleInfo.GetBundleName() + INNER_UNDER_LINE + std::to_string(userId);
312 std::string userZeroKey = innerBundleInfo.GetBundleName() + INNER_UNDER_LINE + std::to_string(0);
313 auto iter = std::find_if(innerBundleInfo.GetInnerBundleUserInfos().begin(),
314 innerBundleInfo.GetInnerBundleUserInfos().end(),
315 [&userIdKey, &userZeroKey](const std::pair<std::string, InnerBundleUserInfo> &infoMap) {
316 return (infoMap.first == userIdKey || infoMap.first == userZeroKey);
317 });
318 int64_t installTime = 0;
319 if (iter != innerBundleInfo.GetInnerBundleUserInfos().end()) {
320 installTime = iter->second.installTime;
321 }
322 return installTime;
323 }
324
ConvertToLauncherAbilityResourceInfo(const AbilityInfo & info)325 ResourceInfo BundleResourceProcess::ConvertToLauncherAbilityResourceInfo(const AbilityInfo &info)
326 {
327 ResourceInfo resourceInfo;
328 resourceInfo.bundleName_ = info.bundleName;
329 resourceInfo.moduleName_ = info.moduleName;
330 resourceInfo.abilityName_ = info.name;
331 resourceInfo.labelId_ = info.labelId;
332 resourceInfo.label_ = info.label;
333 if (resourceInfo.label_.empty()) {
334 resourceInfo.label_ = info.bundleName;
335 }
336 resourceInfo.iconId_ = info.iconId;
337 resourceInfo.hapPath_ = info.hapPath;
338 resourceInfo.updateTime_ = info.installTime;
339 if (resourceInfo.abilityName_ == Constants::APP_DETAIL_ABILITY) {
340 if (!GetDefaultIconResource(resourceInfo.iconId_, resourceInfo.defaultIconHapPath_)) {
341 APP_LOGW("GetDefaultIconResource failed bundleName:%{public}s", resourceInfo.bundleName_.c_str());
342 }
343 }
344 return resourceInfo;
345 }
346
ConvertToBundleResourceInfo(const InnerBundleInfo & innerBundleInfo,const int32_t userId)347 ResourceInfo BundleResourceProcess::ConvertToBundleResourceInfo(
348 const InnerBundleInfo &innerBundleInfo,
349 const int32_t userId)
350 {
351 ResourceInfo resourceInfo;
352 resourceInfo.bundleName_ = innerBundleInfo.GetBundleName();
353 resourceInfo.labelId_ = innerBundleInfo.GetBaseApplicationInfo().labelResource.id;
354 resourceInfo.label_ = innerBundleInfo.GetBaseApplicationInfo().label;
355 if ((resourceInfo.labelId_ == 0) || resourceInfo.label_.empty()) {
356 resourceInfo.label_ = innerBundleInfo.GetBundleName();
357 }
358 resourceInfo.iconId_ = innerBundleInfo.GetBaseApplicationInfo().iconResource.id;
359 resourceInfo.updateTime_ = GetUpdateTime(innerBundleInfo, userId);
360 if (resourceInfo.iconId_ == 0) {
361 if (!GetDefaultIconResource(resourceInfo.iconId_, resourceInfo.defaultIconHapPath_)) {
362 APP_LOGW("GetDefaultIconResource failed bundleName:%{public}s", resourceInfo.bundleName_.c_str());
363 }
364 }
365 const auto &moduleName = innerBundleInfo.GetBaseApplicationInfo().labelResource.moduleName;
366 const auto &moduleInfos = innerBundleInfo.GetInnerModuleInfos();
367 for (const auto &iter : moduleInfos) {
368 if (iter.second.moduleName == moduleName) {
369 resourceInfo.hapPath_ = iter.second.hapPath;
370 break;
371 }
372 }
373 return resourceInfo;
374 }
375
GetDefaultIconResource(int32_t & iconId,std::string & hapPath)376 bool BundleResourceProcess::GetDefaultIconResource(int32_t &iconId, std::string &hapPath)
377 {
378 std::lock_guard<std::mutex> lock(g_systemResLock);
379 if (!systemResourceHap_.empty() && defaultIconId_ != 0) {
380 iconId = defaultIconId_;
381 hapPath = systemResourceHap_;
382 return true;
383 }
384 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
385 if (dataMgr == nullptr) {
386 return false;
387 }
388 BundleInfo info;
389 if (dataMgr->GetBundleInfoV9(GLOBAL_RESOURCE_BUNDLE_NAME,
390 static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
391 static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION),
392 info, Constants::START_USERID) != ERR_OK) {
393 APP_LOGE("GetDefaultIconResource failed to get ohos.global.systemres info");
394 return false;
395 }
396 if (!info.hapModuleInfos.empty()) {
397 iconId = info.applicationInfo.iconResource.id;
398 hapPath = info.hapModuleInfos[0].hapPath;
399 defaultIconId_ = iconId;
400 systemResourceHap_ = hapPath;
401 return true;
402 }
403 APP_LOGE("hapModuleInfos is empty");
404 return false;
405 }
406 } // AppExecFwk
407 } // OHOS
408