• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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