1 /*
2 * Copyright (c) 2022-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 #include "bundle_mgr_client_impl.h"
16
17 #include <cerrno>
18 #include <fstream>
19 #include <unistd.h>
20
21 #include "app_log_wrapper.h"
22 #include "app_log_tag_wrapper.h"
23 #include "bundle_constants.h"
24 #include "bundle_mgr_interface.h"
25 #include "bundle_mgr_proxy.h"
26 #include "bundle_mgr_service_death_recipient.h"
27 #include "iservice_registry.h"
28 #include "nlohmann/json.hpp"
29 #include "system_ability_definition.h"
30
31 #ifdef GLOBAL_RESMGR_ENABLE
32 using namespace OHOS::Global::Resource;
33 #endif
34
35 namespace OHOS {
36 namespace AppExecFwk {
37 namespace {
38 const char* BUNDLE_MAP_CODE_PATH = "/data/storage/el1/bundle";
39 const char* DATA_APP_PATH = "/data/app";
40 #ifdef GLOBAL_RESMGR_ENABLE
41 constexpr const char* PROFILE_FILE_PREFIX = "$profile:";
42 #endif
43 const char* PATH_SEPARATOR = "/";
44 } // namespace
45
BundleMgrClientImpl()46 BundleMgrClientImpl::BundleMgrClientImpl()
47 {
48 APP_LOGD("create bundleMgrClientImpl");
49 }
50
~BundleMgrClientImpl()51 BundleMgrClientImpl::~BundleMgrClientImpl()
52 {
53 APP_LOGD("destroy bundleMgrClientImpl");
54 std::unique_lock<std::shared_mutex> lock(mutex_);
55 if (bundleMgr_ != nullptr && deathRecipient_ != nullptr) {
56 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
57 }
58 }
59
GetNameForUid(const int uid,std::string & name)60 ErrCode BundleMgrClientImpl::GetNameForUid(const int uid, std::string &name)
61 {
62 if (Connect() != ERR_OK) {
63 APP_LOGE("connect fail");
64 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
65 }
66 std::shared_lock<std::shared_mutex> lock(mutex_);
67 if (bundleMgr_ == nullptr) {
68 APP_LOGE("bundleMgr_ nullptr");
69 return ERR_APPEXECFWK_NULL_PTR;
70 }
71 return bundleMgr_->GetNameForUid(uid, name);
72 }
73
GetBundleInfo(const std::string & bundleName,const BundleFlag flag,BundleInfo & bundleInfo,int32_t userId)74 bool BundleMgrClientImpl::GetBundleInfo(const std::string &bundleName, const BundleFlag flag, BundleInfo &bundleInfo,
75 int32_t userId)
76 {
77 LOG_D(BMS_TAG_QUERY, "GetBundleInfo begin");
78
79 ErrCode result = Connect();
80 if (result != ERR_OK) {
81 LOG_E(BMS_TAG_QUERY, "connect fail");
82 return false;
83 }
84
85 std::shared_lock<std::shared_mutex> lock(mutex_);
86 if (bundleMgr_ == nullptr) {
87 APP_LOGE("bundleMgr_ nullptr");
88 return false;
89 }
90 return bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, userId);
91 }
92
GetBundlePackInfo(const std::string & bundleName,const BundlePackFlag flag,BundlePackInfo & bundlePackInfo,int32_t userId)93 ErrCode BundleMgrClientImpl::GetBundlePackInfo(
94 const std::string &bundleName, const BundlePackFlag flag, BundlePackInfo &bundlePackInfo, int32_t userId)
95 {
96 APP_LOGD("enter");
97 ErrCode result = Connect();
98 if (result != ERR_OK) {
99 APP_LOGE("connect fail");
100 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
101 }
102 std::shared_lock<std::shared_mutex> lock(mutex_);
103 if (bundleMgr_ == nullptr) {
104 APP_LOGE("bundleMgr_ nullptr");
105 return ERR_APPEXECFWK_NULL_PTR;
106 }
107 return bundleMgr_->GetBundlePackInfo(bundleName, flag, bundlePackInfo, userId);
108 }
109
CreateBundleDataDir(int32_t userId)110 ErrCode BundleMgrClientImpl::CreateBundleDataDir(int32_t userId)
111 {
112 APP_LOGD("enter");
113 ErrCode result = Connect();
114 if (result != ERR_OK) {
115 APP_LOGE("connect fail");
116 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
117 }
118 std::shared_lock<std::shared_mutex> lock(mutex_);
119 if (bundleMgr_ == nullptr) {
120 APP_LOGE("bundleMgr_ nullptr");
121 return ERR_APPEXECFWK_NULL_PTR;
122 }
123 return bundleMgr_->CreateBundleDataDir(userId);
124 }
125
CreateBundleDataDirWithEl(int32_t userId,DataDirEl dirEl)126 ErrCode BundleMgrClientImpl::CreateBundleDataDirWithEl(int32_t userId, DataDirEl dirEl)
127 {
128 APP_LOGD("enter");
129 ErrCode result = Connect();
130 if (result != ERR_OK) {
131 APP_LOGE("connect fail");
132 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
133 }
134 std::shared_lock<std::shared_mutex> lock(mutex_);
135 if (bundleMgr_ == nullptr) {
136 APP_LOGE("bundleMgr_ nullptr");
137 return ERR_APPEXECFWK_NULL_PTR;
138 }
139 return bundleMgr_->CreateBundleDataDirWithEl(userId, dirEl);
140 }
141
GetHapModuleInfo(const std::string & bundleName,const std::string & hapName,HapModuleInfo & hapModuleInfo)142 bool BundleMgrClientImpl::GetHapModuleInfo(const std::string &bundleName, const std::string &hapName,
143 HapModuleInfo &hapModuleInfo)
144 {
145 ErrCode result = Connect();
146 if (result != ERR_OK) {
147 APP_LOGE("connect fail");
148 return false;
149 }
150
151 AbilityInfo info;
152 info.bundleName = bundleName;
153 info.package = hapName;
154 std::shared_lock<std::shared_mutex> lock(mutex_);
155 if (bundleMgr_ == nullptr) {
156 APP_LOGE("bundleMgr_ nullptr");
157 return false;
158 }
159 return bundleMgr_->GetHapModuleInfo(info, hapModuleInfo);
160 }
161
GetResConfigFile(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos,bool includeSysRes) const162 bool BundleMgrClientImpl::GetResConfigFile(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
163 std::vector<std::string> &profileInfos, bool includeSysRes) const
164 {
165 bool isCompressed = !hapModuleInfo.hapPath.empty();
166 std::string resourcePath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
167 if (!GetResProfileByMetadata(
168 hapModuleInfo.metadata, metadataName, resourcePath, isCompressed, includeSysRes, profileInfos)) {
169 APP_LOGE("GetResProfileByMetadata failed");
170 return false;
171 }
172 if (profileInfos.empty()) {
173 APP_LOGE("no valid file can be obtained");
174 return false;
175 }
176 APP_LOGD("The size of the profile info is : %{public}zu", profileInfos.size());
177 return true;
178 }
179
GetResConfigFile(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos,bool includeSysRes) const180 bool BundleMgrClientImpl::GetResConfigFile(const ExtensionAbilityInfo &extensionInfo, const std::string &metadataName,
181 std::vector<std::string> &profileInfos, bool includeSysRes) const
182 {
183 bool isCompressed = !extensionInfo.hapPath.empty();
184 std::string resourcePath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
185 if (!GetResProfileByMetadata(
186 extensionInfo.metadata, metadataName, resourcePath, isCompressed, includeSysRes, profileInfos)) {
187 APP_LOGE("GetResProfileByMetadata failed");
188 return false;
189 }
190 if (profileInfos.empty()) {
191 APP_LOGE("no valid file can be obtained");
192 return false;
193 }
194 APP_LOGD("The size of the profile info is : %{public}zu", profileInfos.size());
195 return true;
196 }
197
GetResConfigFile(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos,bool includeSysRes) const198 bool BundleMgrClientImpl::GetResConfigFile(const AbilityInfo &abilityInfo, const std::string &metadataName,
199 std::vector<std::string> &profileInfos, bool includeSysRes) const
200 {
201 bool isCompressed = !abilityInfo.hapPath.empty();
202 std::string resourcePath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
203 if (!GetResProfileByMetadata(
204 abilityInfo.metadata, metadataName, resourcePath, isCompressed, includeSysRes, profileInfos)) {
205 APP_LOGE("GetResProfileByMetadata failed");
206 return false;
207 }
208 if (profileInfos.empty()) {
209 APP_LOGE("no valid file can be obtained");
210 return false;
211 }
212 return true;
213 }
214
GetProfileFromExtension(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos,bool includeSysRes) const215 bool BundleMgrClientImpl::GetProfileFromExtension(const ExtensionAbilityInfo &extensionInfo,
216 const std::string &metadataName, std::vector<std::string> &profileInfos, bool includeSysRes) const
217 {
218 APP_LOGD("get extension config file from extension dir begin");
219 bool isCompressed = !extensionInfo.hapPath.empty();
220 std::string resPath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
221 if (!ConvertResourcePath(extensionInfo.bundleName, resPath, isCompressed)) {
222 APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
223 return false;
224 }
225 ExtensionAbilityInfo innerExtension = extensionInfo;
226 if (isCompressed) {
227 innerExtension.hapPath = resPath;
228 } else {
229 innerExtension.resourcePath = resPath;
230 }
231 return GetResConfigFile(innerExtension, metadataName, profileInfos, includeSysRes);
232 }
233
GetProfileFromAbility(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos,bool includeSysRes) const234 bool BundleMgrClientImpl::GetProfileFromAbility(const AbilityInfo &abilityInfo, const std::string &metadataName,
235 std::vector<std::string> &profileInfos, bool includeSysRes) const
236 {
237 APP_LOGD("get ability config file from ability begin");
238 bool isCompressed = !abilityInfo.hapPath.empty();
239 std::string resPath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
240 if (!ConvertResourcePath(abilityInfo.bundleName, resPath, isCompressed)) {
241 APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
242 return false;
243 }
244 AbilityInfo innerAbilityInfo = abilityInfo;
245 if (isCompressed) {
246 innerAbilityInfo.hapPath = resPath;
247 } else {
248 innerAbilityInfo.resourcePath = resPath;
249 }
250 return GetResConfigFile(innerAbilityInfo, metadataName, profileInfos, includeSysRes);
251 }
252
GetProfileFromHap(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos,bool includeSysRes) const253 bool BundleMgrClientImpl::GetProfileFromHap(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
254 std::vector<std::string> &profileInfos, bool includeSysRes) const
255 {
256 APP_LOGD("get hap module config file from hap begin");
257 bool isCompressed = !hapModuleInfo.hapPath.empty();
258 std::string resPath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
259 if (!ConvertResourcePath(hapModuleInfo.bundleName, resPath, isCompressed)) {
260 APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
261 return false;
262 }
263 HapModuleInfo innerHapModuleInfo = hapModuleInfo;
264 if (isCompressed) {
265 innerHapModuleInfo.hapPath = resPath;
266 } else {
267 innerHapModuleInfo.resourcePath = resPath;
268 }
269 return GetResConfigFile(innerHapModuleInfo, metadataName, profileInfos, includeSysRes);
270 }
271
ConvertResourcePath(const std::string & bundleName,std::string & resPath,bool isCompressed) const272 bool BundleMgrClientImpl::ConvertResourcePath(
273 const std::string &bundleName, std::string &resPath, bool isCompressed) const
274 {
275 if (resPath.empty()) {
276 APP_LOGE("res path is empty");
277 return false;
278 }
279 if (isCompressed && (resPath.find(DATA_APP_PATH) != 0)) {
280 APP_LOGD("no need to convert to sandbox path");
281 return true;
282 }
283 std::string innerStr = std::string(Constants::BUNDLE_CODE_DIR) + std::string(PATH_SEPARATOR) + bundleName;
284 if (resPath.find(innerStr) == std::string::npos) {
285 APP_LOGE("res path is incorrect");
286 return false;
287 }
288 resPath.replace(0, innerStr.length(), BUNDLE_MAP_CODE_PATH);
289 return true;
290 }
291
GetResProfileByMetadata(const std::vector<Metadata> & metadata,const std::string & metadataName,const std::string & resourcePath,bool isCompressed,bool includeSysRes,std::vector<std::string> & profileInfos) const292 bool BundleMgrClientImpl::GetResProfileByMetadata(const std::vector<Metadata> &metadata,
293 const std::string &metadataName, const std ::string &resourcePath, bool isCompressed,
294 bool includeSysRes, std::vector<std::string> &profileInfos) const
295 {
296 #ifdef GLOBAL_RESMGR_ENABLE
297 if (metadata.empty()) {
298 APP_LOGE("GetResProfileByMetadata failed due to empty metadata");
299 return false;
300 }
301 if (resourcePath.empty()) {
302 APP_LOGE("GetResProfileByMetadata failed due to empty resourcePath");
303 return false;
304 }
305 std::shared_ptr<ResourceManager> resMgr = InitResMgr(resourcePath, includeSysRes);
306 if (resMgr == nullptr) {
307 APP_LOGE("GetResProfileByMetadata init resMgr failed");
308 return false;
309 }
310
311 if (metadataName.empty()) {
312 for_each(metadata.begin(), metadata.end(),
313 [this, &resMgr, isCompressed, &profileInfos](const Metadata& data)->void {
314 if (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos)) {
315 APP_LOGW("GetResFromResMgr failed");
316 }
317 });
318 } else {
319 for_each(metadata.begin(), metadata.end(),
320 [this, &resMgr, &metadataName, isCompressed, &profileInfos](const Metadata& data)->void {
321 if ((metadataName.compare(data.name) == 0)
322 && (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos))) {
323 APP_LOGW("GetResFromResMgr failed");
324 }
325 });
326 }
327
328 return true;
329 #else
330 APP_LOGW("GLOBAL_RESMGR_ENABLE is false");
331 return false;
332 #endif
333 }
334
335 #ifdef GLOBAL_RESMGR_ENABLE
InitResMgr(const std::string & resourcePath,bool includeSysRes) const336 std::shared_ptr<ResourceManager> BundleMgrClientImpl::InitResMgr(
337 const std::string &resourcePath, bool includeSysRes) const
338 {
339 APP_LOGD("InitResMgr begin");
340 if (resourcePath.empty()) {
341 APP_LOGE("InitResMgr failed due to invalid param");
342 return nullptr;
343 }
344 std::shared_ptr<ResourceManager> resMgr(CreateResourceManager(includeSysRes));
345 if (!resMgr) {
346 APP_LOGE("InitResMgr resMgr is nullptr");
347 return nullptr;
348 }
349
350 std::unique_ptr<ResConfig> resConfig(CreateResConfig());
351 if (!resConfig) {
352 APP_LOGE("InitResMgr resConfig is nullptr");
353 return nullptr;
354 }
355 resMgr->UpdateResConfig(*resConfig);
356
357 APP_LOGD("resourcePath is %{private}s", resourcePath.c_str());
358 if (!resourcePath.empty() && !resMgr->AddResource(resourcePath.c_str())) {
359 APP_LOGE("InitResMgr AddResource failed");
360 return nullptr;
361 }
362 return resMgr;
363 }
364
GetResFromResMgr(const std::string & resName,const std::shared_ptr<ResourceManager> & resMgr,bool isCompressed,std::vector<std::string> & profileInfos) const365 bool BundleMgrClientImpl::GetResFromResMgr(const std::string &resName, const std::shared_ptr<ResourceManager> &resMgr,
366 bool isCompressed, std::vector<std::string> &profileInfos) const
367 {
368 APP_LOGD("GetResFromResMgr begin");
369 if (resName.empty()) {
370 APP_LOGE("GetResFromResMgr res name is empty");
371 return false;
372 }
373
374 size_t pos = resName.rfind(PROFILE_FILE_PREFIX);
375 if ((pos == std::string::npos) || (pos == resName.length() - strlen(PROFILE_FILE_PREFIX))) {
376 APP_LOGE("GetResFromResMgr res name %{public}s invalid", resName.c_str());
377 return false;
378 }
379 std::string profileName = resName.substr(pos + strlen(PROFILE_FILE_PREFIX));
380 // hap is compressed status, get file content.
381 if (isCompressed) {
382 APP_LOGD("compressed status");
383 std::unique_ptr<uint8_t[]> fileContentPtr = nullptr;
384 size_t len = 0;
385 if (resMgr->GetProfileDataByName(profileName.c_str(), len, fileContentPtr) != SUCCESS) {
386 APP_LOGE("GetProfileDataByName failed");
387 return false;
388 }
389 if (fileContentPtr == nullptr || len == 0) {
390 APP_LOGE("invalid data");
391 return false;
392 }
393 std::string rawData(fileContentPtr.get(), fileContentPtr.get() + len);
394 nlohmann::json profileJson = nlohmann::json::parse(rawData, nullptr, false);
395 if (profileJson.is_discarded()) {
396 APP_LOGE("bad profile file");
397 return false;
398 }
399 profileInfos.emplace_back(profileJson.dump());
400 return true;
401 }
402 // hap is decompressed status, get file path then read file.
403 std::string resPath;
404 if (resMgr->GetProfileByName(profileName.c_str(), resPath) != SUCCESS) {
405 APP_LOGE("GetResFromResMgr profileName cannot be found");
406 return false;
407 }
408 APP_LOGD("GetResFromResMgr resPath is %{private}s", resPath.c_str());
409 std::string profile;
410 if (!TransformFileToJsonString(resPath, profile)) {
411 return false;
412 }
413 profileInfos.emplace_back(profile);
414 return true;
415 }
416 #endif
417
IsFileExisted(const std::string & filePath) const418 bool BundleMgrClientImpl::IsFileExisted(const std::string &filePath) const
419 {
420 if (filePath.empty()) {
421 APP_LOGE("the file is not existed due to empty file path");
422 return false;
423 }
424
425 if (access(filePath.c_str(), F_OK) != 0) {
426 APP_LOGE("not access file: %{private}s errno: %{public}d", filePath.c_str(), errno);
427 return false;
428 }
429 return true;
430 }
431
TransformFileToJsonString(const std::string & resPath,std::string & profile) const432 bool BundleMgrClientImpl::TransformFileToJsonString(const std::string &resPath, std::string &profile) const
433 {
434 if (!IsFileExisted(resPath)) {
435 APP_LOGE("the file is not existed");
436 return false;
437 }
438 std::fstream in;
439 char errBuf[256];
440 errBuf[0] = '\0';
441 in.open(resPath, std::ios_base::in | std::ios_base::binary);
442 if (!in.is_open()) {
443 strerror_r(errno, errBuf, sizeof(errBuf));
444 APP_LOGE("file open fail due to %{public}s errno:%{public}d", errBuf, errno);
445 return false;
446 }
447 in.seekg(0, std::ios::end);
448 int64_t size = in.tellg();
449 if (size <= 0) {
450 APP_LOGE("file empty err %{public}d", errno);
451 in.close();
452 return false;
453 }
454 in.seekg(0, std::ios::beg);
455 nlohmann::json profileJson = nlohmann::json::parse(in, nullptr, false);
456 if (profileJson.is_discarded()) {
457 APP_LOGE("bad profile file");
458 in.close();
459 return false;
460 }
461 profile = profileJson.dump();
462 in.close();
463 return true;
464 }
465
GetProfileFromSharedHap(const HapModuleInfo & hapModuleInfo,const ExtensionAbilityInfo & extensionInfo,std::vector<std::string> & profileInfos,bool includeSysRes) const466 bool BundleMgrClientImpl::GetProfileFromSharedHap(const HapModuleInfo &hapModuleInfo,
467 const ExtensionAbilityInfo &extensionInfo, std::vector<std::string> &profileInfos, bool includeSysRes) const
468 {
469 #ifdef GLOBAL_RESMGR_ENABLE
470 bool isCompressed = !hapModuleInfo.hapPath.empty();
471 std::string resourcePath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
472 if (resourcePath.empty()) {
473 APP_LOGE("GetProfileFromSharedHap failed due to empty resourcePath");
474 return false;
475 }
476 std::shared_ptr<ResourceManager> resMgr = InitResMgr(resourcePath, includeSysRes);
477 if (resMgr == nullptr) {
478 APP_LOGE("GetProfileFromSharedHap init resMgr failed");
479 return false;
480 }
481 for (const auto &meta : extensionInfo.metadata) {
482 GetResFromResMgr(meta.resource, resMgr, isCompressed, profileInfos);
483 }
484 return true;
485 #else
486 APP_LOGW("GLOBAL_RESMGR_ENABLE is false");
487 return false;
488 #endif
489 }
490
InstallSandboxApp(const std::string & bundleName,int32_t dlpType,int32_t userId,int32_t & appIndex)491 ErrCode BundleMgrClientImpl::InstallSandboxApp(const std::string &bundleName, int32_t dlpType, int32_t userId,
492 int32_t &appIndex)
493 {
494 APP_LOGD("InstallSandboxApp begin");
495 if (bundleName.empty()) {
496 APP_LOGE("InstallSandboxApp bundleName is empty");
497 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
498 }
499 ErrCode result = ConnectInstaller();
500 if (result != ERR_OK) {
501 APP_LOGE("connect fail");
502 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
503 }
504
505 std::shared_lock<std::shared_mutex> lock(mutex_);
506 if (bundleInstaller_ == nullptr) {
507 APP_LOGE("bundleInstaller_ nullptr");
508 return ERR_APPEXECFWK_NULL_PTR;
509 }
510 return bundleInstaller_->InstallSandboxApp(bundleName, dlpType, userId, appIndex);
511 }
512
UninstallSandboxApp(const std::string & bundleName,int32_t appIndex,int32_t userId)513 ErrCode BundleMgrClientImpl::UninstallSandboxApp(const std::string &bundleName, int32_t appIndex, int32_t userId)
514 {
515 APP_LOGD("UninstallSandboxApp begin");
516 if (bundleName.empty() || appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX) {
517 APP_LOGE("UninstallSandboxApp params are invalid");
518 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
519 }
520 ErrCode result = ConnectInstaller();
521 if (result != ERR_OK) {
522 APP_LOGE("connect fail");
523 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
524 }
525
526 std::shared_lock<std::shared_mutex> lock(mutex_);
527 if (bundleInstaller_ == nullptr) {
528 APP_LOGE("bundleInstaller_ nullptr");
529 return ERR_APPEXECFWK_NULL_PTR;
530 }
531 return bundleInstaller_->UninstallSandboxApp(bundleName, appIndex, userId);
532 }
533
GetSandboxBundleInfo(const std::string & bundleName,int32_t appIndex,int32_t userId,BundleInfo & info)534 ErrCode BundleMgrClientImpl::GetSandboxBundleInfo(
535 const std::string &bundleName, int32_t appIndex, int32_t userId, BundleInfo &info)
536 {
537 APP_LOGD("GetSandboxBundleInfo begin");
538 if (bundleName.empty() || appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX) {
539 APP_LOGE("UninstallSandboxApp params are invalid");
540 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
541 }
542
543 ErrCode result = Connect();
544 if (result != ERR_OK) {
545 APP_LOGE("connect fail");
546 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
547 }
548 std::shared_lock<std::shared_mutex> lock(mutex_);
549 if (bundleMgr_ == nullptr) {
550 APP_LOGE("bundleMgr_ nullptr");
551 return ERR_APPEXECFWK_NULL_PTR;
552 }
553 return bundleMgr_->GetSandboxBundleInfo(bundleName, appIndex, userId, info);
554 }
555
GetSandboxAbilityInfo(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,AbilityInfo & abilityInfo)556 ErrCode BundleMgrClientImpl::GetSandboxAbilityInfo(const Want &want, int32_t appIndex, int32_t flags, int32_t userId,
557 AbilityInfo &abilityInfo)
558 {
559 APP_LOGD("GetSandboxAbilityInfo begin");
560 if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX || appIndex > Constants::MAX_SANDBOX_APP_INDEX) {
561 APP_LOGE("GetSandboxAbilityInfo params are invalid");
562 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
563 }
564 ErrCode result = Connect();
565 if (result != ERR_OK) {
566 APP_LOGE("connect fail");
567 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
568 }
569
570 std::shared_lock<std::shared_mutex> lock(mutex_);
571 if (bundleMgr_ == nullptr) {
572 APP_LOGE("bundleMgr_ nullptr");
573 return ERR_APPEXECFWK_NULL_PTR;
574 }
575 return bundleMgr_->GetSandboxAbilityInfo(want, appIndex, flags, userId, abilityInfo);
576 }
577
GetSandboxExtAbilityInfos(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,std::vector<ExtensionAbilityInfo> & extensionInfos)578 ErrCode BundleMgrClientImpl::GetSandboxExtAbilityInfos(const Want &want, int32_t appIndex, int32_t flags,
579 int32_t userId, std::vector<ExtensionAbilityInfo> &extensionInfos)
580 {
581 APP_LOGD("GetSandboxExtensionAbilityInfos begin");
582 if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX || appIndex > Constants::MAX_SANDBOX_APP_INDEX) {
583 APP_LOGE("appIndex is invalid,: %{public}d,", appIndex);
584 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
585 }
586 ErrCode result = Connect();
587 if (result != ERR_OK) {
588 APP_LOGE("connect fail: %{public}d", result);
589 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
590 }
591
592 std::shared_lock<std::shared_mutex> lock(mutex_);
593 if (bundleMgr_ == nullptr) {
594 APP_LOGE("bundleMgr_ nullptr");
595 return ERR_APPEXECFWK_NULL_PTR;
596 }
597 return bundleMgr_->GetSandboxExtAbilityInfos(want, appIndex, flags, userId, extensionInfos);
598 }
599
GetSandboxHapModuleInfo(const AbilityInfo & abilityInfo,int32_t appIndex,int32_t userId,HapModuleInfo & hapModuleInfo)600 ErrCode BundleMgrClientImpl::GetSandboxHapModuleInfo(const AbilityInfo &abilityInfo, int32_t appIndex, int32_t userId,
601 HapModuleInfo &hapModuleInfo)
602 {
603 APP_LOGD("GetSandboxHapModuleInfo begin");
604 if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX || appIndex > Constants::MAX_SANDBOX_APP_INDEX) {
605 APP_LOGE("GetSandboxHapModuleInfo params are invalid");
606 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
607 }
608 ErrCode result = Connect();
609 if (result != ERR_OK) {
610 APP_LOGE("connect fail");
611 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
612 }
613
614 std::shared_lock<std::shared_mutex> lock(mutex_);
615 if (bundleMgr_ == nullptr) {
616 APP_LOGE("bundleMgr_ nullptr");
617 return ERR_APPEXECFWK_NULL_PTR;
618 }
619 return bundleMgr_->GetSandboxHapModuleInfo(abilityInfo, appIndex, userId, hapModuleInfo);
620 }
621
GetDirByBundleNameAndAppIndex(const std::string & bundleName,const int32_t appIndex,std::string & dataDir)622 ErrCode BundleMgrClientImpl::GetDirByBundleNameAndAppIndex(const std::string &bundleName, const int32_t appIndex,
623 std::string &dataDir)
624 {
625 APP_LOGD("GetDir begin");
626 ErrCode result = Connect();
627 if (result != ERR_OK) {
628 APP_LOGE("connect fail");
629 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
630 }
631 std::shared_lock<std::shared_mutex> lock(mutex_);
632 if (bundleMgr_ == nullptr) {
633 APP_LOGE("bundleMgr_ nullptr");
634 return ERR_APPEXECFWK_NULL_PTR;
635 }
636 return bundleMgr_->GetDirByBundleNameAndAppIndex(bundleName, appIndex, dataDir);
637 }
638
GetAllBundleDirs(int32_t userId,std::vector<BundleDir> & bundleDirs)639 ErrCode BundleMgrClientImpl::GetAllBundleDirs(int32_t userId, std::vector<BundleDir> &bundleDirs)
640 {
641 APP_LOGD("GetAllBundleDirs begin");
642 ErrCode result = Connect();
643 if (result != ERR_OK) {
644 APP_LOGE("connect fail");
645 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
646 }
647 std::shared_lock<std::shared_mutex> lock(mutex_);
648 if (bundleMgr_ == nullptr) {
649 APP_LOGE("bundleMgr_ nullptr");
650 return ERR_APPEXECFWK_NULL_PTR;
651 }
652 return bundleMgr_->GetAllBundleDirs(userId, bundleDirs);
653 }
654
Connect()655 ErrCode BundleMgrClientImpl::Connect()
656 {
657 APP_LOGD("connect begin");
658 std::unique_lock<std::shared_mutex> lock(mutex_);
659 if (bundleMgr_ == nullptr) {
660 sptr<ISystemAbilityManager> systemAbilityManager =
661 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
662 if (systemAbilityManager == nullptr) {
663 APP_LOGE("failed to get system ability manager");
664 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
665 }
666
667 sptr<IRemoteObject> remoteObject_ = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
668 if (remoteObject_ == nullptr || (bundleMgr_ = iface_cast<IBundleMgr>(remoteObject_)) == nullptr) {
669 APP_LOGE_NOFUNC("get bms sa failed");
670 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
671 }
672 std::weak_ptr<BundleMgrClientImpl> weakPtr = shared_from_this();
673 auto deathCallback = [weakPtr](const wptr<IRemoteObject>& object) {
674 auto sharedPtr = weakPtr.lock();
675 if (sharedPtr != nullptr) {
676 sharedPtr->OnDeath();
677 }
678 };
679 deathRecipient_ = new (std::nothrow) BundleMgrServiceDeathRecipient(deathCallback);
680 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
681 }
682 APP_LOGD("connect end");
683 return ERR_OK;
684 }
685
ConnectInstaller()686 ErrCode BundleMgrClientImpl::ConnectInstaller()
687 {
688 APP_LOGD("ConnectInstaller begin");
689 std::unique_lock<std::shared_mutex> lock(mutex_);
690 if (bundleMgr_ == nullptr) {
691 sptr<ISystemAbilityManager> systemAbilityManager =
692 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
693 if (systemAbilityManager == nullptr) {
694 APP_LOGE("failed to get system ability manager");
695 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
696 }
697
698 sptr<IRemoteObject> remoteObject_ = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
699 if (remoteObject_ == nullptr || (bundleMgr_ = iface_cast<IBundleMgr>(remoteObject_)) == nullptr) {
700 APP_LOGE_NOFUNC("get bms sa failed");
701 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
702 }
703 std::weak_ptr<BundleMgrClientImpl> weakPtr = shared_from_this();
704 auto deathCallback = [weakPtr](const wptr<IRemoteObject>& object) {
705 auto sharedPtr = weakPtr.lock();
706 if (sharedPtr != nullptr) {
707 sharedPtr->OnDeath();
708 }
709 };
710 deathRecipient_ = new (std::nothrow) BundleMgrServiceDeathRecipient(deathCallback);
711 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
712 }
713
714 if (bundleInstaller_ == nullptr) {
715 bundleInstaller_ = bundleMgr_->GetBundleInstaller();
716 if ((bundleInstaller_ == nullptr) || (bundleInstaller_->AsObject() == nullptr)) {
717 APP_LOGE("get installer failed");
718 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
719 }
720 }
721 APP_LOGD("ConnectInstaller end");
722 return ERR_OK;
723 }
724
OnDeath()725 void BundleMgrClientImpl::OnDeath()
726 {
727 APP_LOGD("BundleManagerService dead");
728 std::unique_lock<std::shared_mutex> lock(mutex_);
729 bundleMgr_ = nullptr;
730 bundleInstaller_ = nullptr;
731 }
732 } // namespace AppExecFwk
733 } // namespace OHOS