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