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_host_impl.h"
17 
18 #include "bms_extension_client.h"
19 #include "bundle_permission_mgr.h"
20 #include "bundle_resource_manager.h"
21 #include "bundle_mgr_service.h"
22 #include "xcollie_helper.h"
23 #include "scope_guard.h"
24 
25 namespace OHOS {
26 namespace AppExecFwk {
27 const std::string FUNCATION_GET_BUNDLE_RESOURCE_INFO = "BundleResourceHostImpl::GetBundleResourceInfo";
28 
GetBundleResourceInfo(const std::string & bundleName,const uint32_t flags,BundleResourceInfo & bundleResourceInfo,const int32_t appIndex)29 ErrCode BundleResourceHostImpl::GetBundleResourceInfo(const std::string &bundleName, const uint32_t flags,
30     BundleResourceInfo &bundleResourceInfo, const int32_t appIndex)
31 {
32     APP_LOGD("start, bundleName: %{public}s, flags: %{public}u", bundleName.c_str(), flags);
33     int32_t timerId = XCollieHelper::SetRecoveryTimer(FUNCATION_GET_BUNDLE_RESOURCE_INFO);
34     ScopeGuard cancelTimerIdGuard([timerId] { XCollieHelper::CancelTimer(timerId); });
35     if (!BundlePermissionMgr::IsSystemApp()) {
36         APP_LOGE("non-system app calling system api");
37         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
38     }
39     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES)) {
40         APP_LOGE("verify permission failed");
41         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
42     }
43     if ((appIndex < 0) || (appIndex > ServiceConstants::CLONE_APP_INDEX_MAX)) {
44         APP_LOGE("get bundle resource Fail, bundleName: %{public}s appIndex: %{public}d not in valid range",
45             bundleName.c_str(), appIndex);
46         return ERR_APPEXECFWK_CLONE_INSTALL_INVALID_APP_INDEX;
47     }
48     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
49     if (manager == nullptr) {
50         APP_LOGE("manager nullptr, bundleName %{public}s", bundleName.c_str());
51         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
52     }
53     if (!manager->GetBundleResourceInfo(bundleName, flags, bundleResourceInfo, appIndex)) {
54         APP_LOGE_NOFUNC("get resource failed -n %{public}s -f %{public}u", bundleName.c_str(), flags);
55         return CheckBundleNameValid(bundleName, appIndex);
56     }
57     return ERR_OK;
58 }
59 
GetLauncherAbilityResourceInfo(const std::string & bundleName,const uint32_t flags,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfo,const int32_t appIndex)60 ErrCode BundleResourceHostImpl::GetLauncherAbilityResourceInfo(const std::string &bundleName, const uint32_t flags,
61     std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfo, const int32_t appIndex)
62 {
63     APP_LOGD("start, bundleName: %{public}s, flags: %{public}u", bundleName.c_str(), flags);
64     if (!BundlePermissionMgr::IsSystemApp()) {
65         APP_LOGE("non-system app calling system api");
66         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
67     }
68     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES)) {
69         APP_LOGE("verify permission failed");
70         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
71     }
72     if ((appIndex < 0) || (appIndex > ServiceConstants::CLONE_APP_INDEX_MAX)) {
73         APP_LOGE("get bundle resource Fail, bundleName: %{public}s appIndex: %{public}d not in valid range",
74             bundleName.c_str(), appIndex);
75         return ERR_APPEXECFWK_CLONE_INSTALL_INVALID_APP_INDEX;
76     }
77     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
78     if (manager == nullptr) {
79         APP_LOGE("manager nullptr, bundleName %{public}s", bundleName.c_str());
80         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
81     }
82     if (!manager->GetLauncherAbilityResourceInfo(bundleName, flags, launcherAbilityResourceInfo, appIndex)) {
83         APP_LOGE_NOFUNC("get resource failed -n %{public}s -f %{public}u", bundleName.c_str(), flags);
84         return CheckBundleNameValid(bundleName, appIndex);
85     }
86     return ERR_OK;
87 }
88 
GetAllBundleResourceInfo(const uint32_t flags,std::vector<BundleResourceInfo> & bundleResourceInfos)89 ErrCode BundleResourceHostImpl::GetAllBundleResourceInfo(const uint32_t flags,
90     std::vector<BundleResourceInfo> &bundleResourceInfos)
91 {
92     APP_LOGD("start");
93     if (!BundlePermissionMgr::IsSystemApp()) {
94         APP_LOGE("non-system app calling system api");
95         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
96     }
97     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES)) {
98         APP_LOGE("verify permission failed");
99         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
100     }
101     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST)) {
102         APP_LOGE("verify permission failed");
103         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
104     }
105     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
106     if (manager == nullptr) {
107         APP_LOGE("manager is nullptr");
108         BundlePermissionMgr::AddPermissionUsedRecord(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST, 0, 1);
109         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
110     }
111     if (!manager->GetAllBundleResourceInfo(flags, bundleResourceInfos)) {
112         APP_LOGE("get all resource failed, flags:%{public}u", flags);
113         BundlePermissionMgr::AddPermissionUsedRecord(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST, 0, 1);
114         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
115     }
116     auto bmsExtensionClient = std::make_shared<BmsExtensionClient>();
117     ErrCode ret = bmsExtensionClient->GetAllBundleResourceInfo(flags, bundleResourceInfos);
118     if (ret != ERR_OK) {
119         APP_LOGE("get all resource from ext failed, flags:%{public}u", flags);
120     } else {
121         if ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) ==
122             static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) {
123             APP_LOGD("need sort by label");
124             std::sort(bundleResourceInfos.begin(), bundleResourceInfos.end(),
125                 [](const BundleResourceInfo &resourceA, const BundleResourceInfo &resourceB) {
126                     return resourceA.label < resourceB.label;
127                 });
128         }
129     }
130     BundlePermissionMgr::AddPermissionUsedRecord(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST, 1, 0);
131     return ERR_OK;
132 }
133 
GetAllLauncherAbilityResourceInfo(const uint32_t flags,std::vector<LauncherAbilityResourceInfo> & launcherAbilityResourceInfos)134 ErrCode BundleResourceHostImpl::GetAllLauncherAbilityResourceInfo(const uint32_t flags,
135     std::vector<LauncherAbilityResourceInfo> &launcherAbilityResourceInfos)
136 {
137     APP_LOGD("start");
138     if (!BundlePermissionMgr::IsSystemApp()) {
139         APP_LOGE("non-system app calling system api");
140         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
141     }
142     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES)) {
143         APP_LOGE("verify permission failed");
144         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
145     }
146     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST)) {
147         APP_LOGE("verify permission failed");
148         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
149     }
150 
151     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
152     if (manager == nullptr) {
153         APP_LOGE("manager is nullptr");
154         BundlePermissionMgr::AddPermissionUsedRecord(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST, 0, 1);
155         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
156     }
157     if (!manager->GetAllLauncherAbilityResourceInfo(flags, launcherAbilityResourceInfos)) {
158         APP_LOGE("get all resource failed, flags:%{public}u", flags);
159         BundlePermissionMgr::AddPermissionUsedRecord(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST, 0, 1);
160         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
161     }
162     auto bmsExtensionClient = std::make_shared<BmsExtensionClient>();
163     ErrCode ret = bmsExtensionClient->GetAllLauncherAbilityResourceInfo(flags, launcherAbilityResourceInfos);
164     if (ret != ERR_OK) {
165         APP_LOGE("get all resource from ext failed, flags:%{public}u", flags);
166     } else {
167         if ((flags & static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) ==
168             static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL)) {
169             APP_LOGD("need sort by label");
170             std::sort(launcherAbilityResourceInfos.begin(), launcherAbilityResourceInfos.end(),
171                 [](const LauncherAbilityResourceInfo &resourceA, const LauncherAbilityResourceInfo &resourceB) {
172                     return resourceA.label < resourceB.label;
173                 });
174         }
175     }
176     BundlePermissionMgr::AddPermissionUsedRecord(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST, 1, 0);
177     return ERR_OK;
178 }
179 
AddResourceInfoByBundleName(const std::string & bundleName,const int32_t userId)180 ErrCode BundleResourceHostImpl::AddResourceInfoByBundleName(const std::string &bundleName, const int32_t userId)
181 {
182     APP_LOGD("start, bundleName:%{public}s userId:%{private}d", bundleName.c_str(), userId);
183     if (bundleName.empty()) {
184         APP_LOGE("bundleName is empty.");
185         return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
186     }
187     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
188     if (dataMgr == nullptr) {
189         APP_LOGE("dataMgr is nullptr");
190         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
191     }
192     if (!dataMgr->HasUserId(userId)) {
193         APP_LOGE("user id invalid");
194         return ERR_BUNDLE_MANAGER_INVALID_USER_ID;
195     }
196     if (!BundlePermissionMgr::IsSystemApp()) {
197         APP_LOGE("non-system app calling system api");
198         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
199     }
200     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES)) {
201         APP_LOGE("verify permission failed");
202         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
203     }
204     if (!DelayedSingleton<BundleMgrService>::GetInstance()->IsBrokerServiceStarted()) {
205         APP_LOGE("broker is not started");
206         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
207     }
208 
209     auto bmsExtensionClient = std::make_shared<BmsExtensionClient>();
210     ErrCode ret = bmsExtensionClient->AddResourceInfoByBundleName(bundleName, userId);
211     if (ret != ERR_OK) {
212         APP_LOGE("bms extension client api add resource info by bundle name error:%{public}d", ret);
213     }
214     return ret;
215 }
216 
AddResourceInfoByAbility(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const int32_t userId)217 ErrCode BundleResourceHostImpl::AddResourceInfoByAbility(const std::string &bundleName, const std::string &moduleName,
218     const std::string &abilityName, const int32_t userId)
219 {
220     APP_LOGD("start, bundleName:%{public}s moduleName:%{public}s abilityName:%{public}s userId:%{private}d",
221         bundleName.c_str(), moduleName.c_str(), abilityName.c_str(), userId);
222     if (bundleName.empty()) {
223         APP_LOGE("bundleName is empty.");
224         return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
225     }
226     if (moduleName.empty()) {
227         APP_LOGE("moduleName is empty.");
228         return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
229     }
230     if (abilityName.empty()) {
231         APP_LOGE("abilityName is empty.");
232         return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
233     }
234     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
235     if (dataMgr == nullptr) {
236         APP_LOGE("dataMgr is nullptr");
237         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
238     }
239     if (!dataMgr->HasUserId(userId)) {
240         APP_LOGE("user id invalid");
241         return ERR_BUNDLE_MANAGER_INVALID_USER_ID;
242     }
243     if (!BundlePermissionMgr::IsSystemApp()) {
244         APP_LOGE("non-system app calling system api");
245         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
246     }
247     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES)) {
248         APP_LOGE("verify permission failed");
249         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
250     }
251     if (!DelayedSingleton<BundleMgrService>::GetInstance()->IsBrokerServiceStarted()) {
252         APP_LOGE("broker is not started");
253         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
254     }
255 
256     auto bmsExtensionClient = std::make_shared<BmsExtensionClient>();
257     ErrCode ret = bmsExtensionClient->AddResourceInfoByAbility(bundleName, moduleName, abilityName, userId);
258     if (ret != ERR_OK) {
259         APP_LOGE("bms extension client api add resource info by ability name error:%{public}d", ret);
260     }
261     return ret;
262 }
263 
DeleteResourceInfo(const std::string & key)264 ErrCode BundleResourceHostImpl::DeleteResourceInfo(const std::string &key)
265 {
266     APP_LOGD("start, key:%{private}s", key.c_str());
267     if (key.empty()) {
268         APP_LOGE("key is empty.");
269         return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
270     }
271     if (!BundlePermissionMgr::IsSystemApp()) {
272         APP_LOGE("non-system app calling system api");
273         return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
274     }
275     if (!BundlePermissionMgr::VerifyCallingPermissionForAll(ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES)) {
276         APP_LOGE("verify permission failed");
277         return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
278     }
279     if (!DelayedSingleton<BundleMgrService>::GetInstance()->IsBrokerServiceStarted()) {
280         APP_LOGE("broker is not started");
281         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
282     }
283 
284     auto bmsExtensionClient = std::make_shared<BmsExtensionClient>();
285     ErrCode ret = bmsExtensionClient->DeleteResourceInfo(key);
286     if (ret != ERR_OK) {
287         APP_LOGE("bms extension client api delete by key error:%{public}d", ret);
288     }
289     return ret;
290 }
291 
CheckBundleNameValid(const std::string & bundleName,int32_t appIndex)292 ErrCode BundleResourceHostImpl::CheckBundleNameValid(const std::string &bundleName, int32_t appIndex)
293 {
294     if (appIndex == 0) {
295         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
296     }
297     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
298     if (manager == nullptr) {
299         APP_LOGE("manager nullptr, bundleName %{public}s", bundleName.c_str());
300         return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
301     }
302     BundleResourceInfo bundleResourceInfo;
303     if (!manager->GetBundleResourceInfo(bundleName,
304         static_cast<uint32_t>(ResourceFlag::GET_RESOURCE_INFO_WITH_LABEL), bundleResourceInfo)) {
305         return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
306     }
307     APP_LOGE("get failed, bundleName:%{public}s appIndex:%{public}d", bundleName.c_str(), appIndex);
308     return ERR_APPEXECFWK_CLONE_INSTALL_INVALID_APP_INDEX;
309 }
310 } // AppExecFwk
311 } // OHOS
312