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