• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "bundle_constants.h"
23 #include "bundle_mgr_interface.h"
24 #include "bundle_mgr_proxy.h"
25 #include "bundle_mgr_service_death_recipient.h"
26 #include "iservice_registry.h"
27 #include "nlohmann/json.hpp"
28 #include "system_ability_definition.h"
29 
30 #ifdef GLOBAL_RESMGR_ENABLE
31 using namespace OHOS::Global::Resource;
32 #endif
33 
34 namespace OHOS {
35 namespace AppExecFwk {
36 namespace {
37 const std::string BUNDLE_MAP_CODE_PATH = "/data/storage/el1/bundle";
38 const std::string DATA_APP_PATH = "/data/app";
39 constexpr const char* PROFILE_FILE_PREFIX = "$profile:";
40 } // namespace
41 
BundleMgrClientImpl()42 BundleMgrClientImpl::BundleMgrClientImpl()
43 {
44     APP_LOGD("create bundleMgrClientImpl");
45 }
46 
~BundleMgrClientImpl()47 BundleMgrClientImpl::~BundleMgrClientImpl()
48 {
49     APP_LOGD("destroy bundleMgrClientImpl");
50     if (bundleMgr_ != nullptr && deathRecipient_ != nullptr) {
51         bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
52     }
53 }
54 
GetNameForUid(const int uid,std::string & name)55 ErrCode BundleMgrClientImpl::GetNameForUid(const int uid, std::string &name)
56 {
57     if (Connect() != ERR_OK) {
58         APP_LOGE("failed to connect");
59         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
60     }
61     return bundleMgr_->GetNameForUid(uid, name);
62 }
63 
GetBundleInfo(const std::string & bundleName,const BundleFlag flag,BundleInfo & bundleInfo,int32_t userId)64 bool BundleMgrClientImpl::GetBundleInfo(const std::string &bundleName, const BundleFlag flag, BundleInfo &bundleInfo,
65     int32_t userId)
66 {
67     APP_LOGD("GetBundleInfo begin");
68 
69     ErrCode result = Connect();
70     if (result != ERR_OK) {
71         APP_LOGE("failed to connect");
72         return false;
73     }
74 
75     return bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, userId);
76 }
77 
GetBundlePackInfo(const std::string & bundleName,const BundlePackFlag flag,BundlePackInfo & bundlePackInfo,int32_t userId)78 ErrCode BundleMgrClientImpl::GetBundlePackInfo(
79     const std::string &bundleName, const BundlePackFlag flag, BundlePackInfo &bundlePackInfo, int32_t userId)
80 {
81     APP_LOGD("enter");
82     ErrCode result = Connect();
83     if (result != ERR_OK) {
84         APP_LOGE("failed to connect");
85         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
86     }
87     return bundleMgr_->GetBundlePackInfo(bundleName, flag, bundlePackInfo, userId);
88 }
89 
CreateBundleDataDir(int32_t userId)90 ErrCode BundleMgrClientImpl::CreateBundleDataDir(int32_t userId)
91 {
92     APP_LOGD("enter");
93     ErrCode result = Connect();
94     if (result != ERR_OK) {
95         APP_LOGE("failed to connect");
96         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
97     }
98     return bundleMgr_->CreateBundleDataDir(userId);
99 }
100 
GetHapModuleInfo(const std::string & bundleName,const std::string & hapName,HapModuleInfo & hapModuleInfo)101 bool BundleMgrClientImpl::GetHapModuleInfo(const std::string &bundleName, const std::string &hapName,
102     HapModuleInfo &hapModuleInfo)
103 {
104     ErrCode result = Connect();
105     if (result != ERR_OK) {
106         APP_LOGE("failed to connect");
107         return false;
108     }
109 
110     AbilityInfo info;
111     info.bundleName = bundleName;
112     info.package = hapName;
113     return bundleMgr_->GetHapModuleInfo(info, hapModuleInfo);
114 }
115 
GetResConfigFile(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const116 bool BundleMgrClientImpl::GetResConfigFile(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
117     std::vector<std::string> &profileInfos) const
118 {
119     bool isCompressed = !hapModuleInfo.hapPath.empty();
120     std::string resourcePath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
121     if (!GetResProfileByMetadata(hapModuleInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
122         APP_LOGE("GetResProfileByMetadata failed");
123         return false;
124     }
125     if (profileInfos.empty()) {
126         APP_LOGE("no valid file can be obtained");
127         return false;
128     }
129     int32_t InfoSize = profileInfos.size();
130     APP_LOGD("The size of the profile info is : %{public}d", InfoSize);
131     return true;
132 }
133 
GetResConfigFile(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const134 bool BundleMgrClientImpl::GetResConfigFile(const ExtensionAbilityInfo &extensionInfo, const std::string &metadataName,
135     std::vector<std::string> &profileInfos) const
136 {
137     bool isCompressed = !extensionInfo.hapPath.empty();
138     std::string resourcePath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
139     if (!GetResProfileByMetadata(extensionInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
140         APP_LOGE("GetResProfileByMetadata failed");
141         return false;
142     }
143     if (profileInfos.empty()) {
144         APP_LOGE("no valid file can be obtained");
145         return false;
146     }
147     int32_t InfoSize = profileInfos.size();
148     APP_LOGD("The size of the profile info is : %{public}d", InfoSize);
149     return true;
150 }
151 
GetResConfigFile(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const152 bool BundleMgrClientImpl::GetResConfigFile(const AbilityInfo &abilityInfo, const std::string &metadataName,
153     std::vector<std::string> &profileInfos) const
154 {
155     bool isCompressed = !abilityInfo.hapPath.empty();
156     std::string resourcePath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
157     if (!GetResProfileByMetadata(abilityInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
158         APP_LOGE("GetResProfileByMetadata failed");
159         return false;
160     }
161     if (profileInfos.empty()) {
162         APP_LOGE("no valid file can be obtained");
163         return false;
164     }
165     return true;
166 }
167 
GetProfileFromExtension(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const168 bool BundleMgrClientImpl::GetProfileFromExtension(const ExtensionAbilityInfo &extensionInfo,
169     const std::string &metadataName, std::vector<std::string> &profileInfos) const
170 {
171     APP_LOGD("get extension config file from extension dir begin");
172     bool isCompressed = !extensionInfo.hapPath.empty();
173     std::string resPath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
174     if (!ConvertResourcePath(extensionInfo.bundleName, resPath, isCompressed)) {
175         APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
176         return false;
177     }
178     ExtensionAbilityInfo innerExtension = extensionInfo;
179     if (isCompressed) {
180         innerExtension.hapPath = resPath;
181     } else {
182         innerExtension.resourcePath = resPath;
183     }
184     return GetResConfigFile(innerExtension, metadataName, profileInfos);
185 }
186 
GetProfileFromAbility(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const187 bool BundleMgrClientImpl::GetProfileFromAbility(const AbilityInfo &abilityInfo, const std::string &metadataName,
188     std::vector<std::string> &profileInfos) const
189 {
190     APP_LOGD("get ability config file from ability begin");
191     bool isCompressed = !abilityInfo.hapPath.empty();
192     std::string resPath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
193     if (!ConvertResourcePath(abilityInfo.bundleName, resPath, isCompressed)) {
194         APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
195         return false;
196     }
197     AbilityInfo innerAbilityInfo = abilityInfo;
198     if (isCompressed) {
199         innerAbilityInfo.hapPath = resPath;
200     } else {
201         innerAbilityInfo.resourcePath = resPath;
202     }
203     return GetResConfigFile(innerAbilityInfo, metadataName, profileInfos);
204 }
205 
GetProfileFromHap(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const206 bool BundleMgrClientImpl::GetProfileFromHap(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
207     std::vector<std::string> &profileInfos) const
208 {
209     APP_LOGD("get hap module config file from hap begin");
210     bool isCompressed = !hapModuleInfo.hapPath.empty();
211     std::string resPath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
212     if (!ConvertResourcePath(hapModuleInfo.bundleName, resPath, isCompressed)) {
213         APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
214         return false;
215     }
216     HapModuleInfo innerHapModuleInfo = hapModuleInfo;
217     if (isCompressed) {
218         innerHapModuleInfo.hapPath = resPath;
219     } else {
220         innerHapModuleInfo.resourcePath = resPath;
221     }
222     return GetResConfigFile(innerHapModuleInfo, metadataName, profileInfos);
223 }
224 
ConvertResourcePath(const std::string & bundleName,std::string & resPath,bool isCompressed) const225 bool BundleMgrClientImpl::ConvertResourcePath(
226     const std::string &bundleName, std::string &resPath, bool isCompressed) const
227 {
228     if (resPath.empty()) {
229         APP_LOGE("res path is empty");
230         return false;
231     }
232     if (isCompressed && (resPath.find(DATA_APP_PATH) != 0)) {
233         APP_LOGD("no need to convert to sandbox path");
234         return true;
235     }
236     std::string innerStr = Constants::BUNDLE_CODE_DIR + Constants::PATH_SEPARATOR + bundleName;
237     if (resPath.find(innerStr) == std::string::npos) {
238         APP_LOGE("res path is incorrect");
239         return false;
240     }
241     resPath.replace(0, innerStr.length(), BUNDLE_MAP_CODE_PATH);
242     return true;
243 }
244 
GetResProfileByMetadata(const std::vector<Metadata> & metadata,const std::string & metadataName,const std::string & resourcePath,bool isCompressed,std::vector<std::string> & profileInfos) const245 bool BundleMgrClientImpl::GetResProfileByMetadata(const std::vector<Metadata> &metadata,
246     const std::string &metadataName, const std ::string &resourcePath, bool isCompressed,
247     std::vector<std::string> &profileInfos) const
248 {
249 #ifdef GLOBAL_RESMGR_ENABLE
250     if (metadata.empty()) {
251         APP_LOGE("GetResProfileByMetadata failed due to empty metadata");
252         return false;
253     }
254     if (resourcePath.empty()) {
255         APP_LOGE("GetResProfileByMetadata failed due to empty resourcePath");
256         return false;
257     }
258     std::shared_ptr<ResourceManager> resMgr = InitResMgr(resourcePath);
259     if (resMgr == nullptr) {
260         APP_LOGE("GetResProfileByMetadata init resMgr failed");
261         return false;
262     }
263 
264     if (metadataName.empty()) {
265         for_each(metadata.begin(), metadata.end(),
266             [this, &resMgr, isCompressed, &profileInfos](const Metadata& data)->void {
267             if (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos)) {
268                 APP_LOGW("GetResFromResMgr failed");
269             }
270         });
271     } else {
272         for_each(metadata.begin(), metadata.end(),
273             [this, &resMgr, &metadataName, isCompressed, &profileInfos](const Metadata& data)->void {
274             if ((metadataName.compare(data.name) == 0)
275                 && (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos))) {
276                 APP_LOGW("GetResFromResMgr failed");
277             }
278         });
279     }
280 
281     return true;
282 #else
283     APP_LOGW("GLOBAL_RESMGR_ENABLE is false");
284     return false;
285 #endif
286 }
287 
288 #ifdef GLOBAL_RESMGR_ENABLE
InitResMgr(const std::string & resourcePath) const289 std::shared_ptr<ResourceManager> BundleMgrClientImpl::InitResMgr(const std::string &resourcePath) const
290 {
291     APP_LOGD("InitResMgr begin");
292     if (resourcePath.empty()) {
293         APP_LOGE("InitResMgr failed due to invalid param");
294         return nullptr;
295     }
296     std::shared_ptr<ResourceManager> resMgr(CreateResourceManager());
297     if (!resMgr) {
298         APP_LOGE("InitResMgr resMgr is nullptr");
299         return nullptr;
300     }
301 
302     std::unique_ptr<ResConfig> resConfig(CreateResConfig());
303     if (!resConfig) {
304         APP_LOGE("InitResMgr resConfig is nullptr");
305         return nullptr;
306     }
307     resMgr->UpdateResConfig(*resConfig);
308 
309     APP_LOGD("resourcePath is %{private}s", resourcePath.c_str());
310     if (!resourcePath.empty() && !resMgr->AddResource(resourcePath.c_str())) {
311         APP_LOGE("InitResMgr AddResource failed");
312         return nullptr;
313     }
314     return resMgr;
315 }
316 
GetResFromResMgr(const std::string & resName,const std::shared_ptr<ResourceManager> & resMgr,bool isCompressed,std::vector<std::string> & profileInfos) const317 bool BundleMgrClientImpl::GetResFromResMgr(const std::string &resName, const std::shared_ptr<ResourceManager> &resMgr,
318     bool isCompressed, std::vector<std::string> &profileInfos) const
319 {
320     APP_LOGD("GetResFromResMgr begin");
321     if (resName.empty()) {
322         APP_LOGE("GetResFromResMgr res name is empty");
323         return false;
324     }
325 
326     size_t pos = resName.rfind(PROFILE_FILE_PREFIX);
327     if ((pos == std::string::npos) || (pos == resName.length() - strlen(PROFILE_FILE_PREFIX))) {
328         APP_LOGE("GetResFromResMgr res name %{public}s is invalid", resName.c_str());
329         return false;
330     }
331     std::string profileName = resName.substr(pos + strlen(PROFILE_FILE_PREFIX));
332     // hap is compressed status, get file content.
333     if (isCompressed) {
334         APP_LOGD("compressed status.");
335         std::unique_ptr<uint8_t[]> fileContentPtr = nullptr;
336         size_t len = 0;
337         if (resMgr->GetProfileDataByName(profileName.c_str(), len, fileContentPtr) != SUCCESS) {
338             APP_LOGE("GetProfileDataByName failed");
339             return false;
340         }
341         if (fileContentPtr == nullptr || len == 0) {
342             APP_LOGE("invalid data");
343             return false;
344         }
345         std::string rawData(fileContentPtr.get(), fileContentPtr.get() + len);
346         nlohmann::json profileJson = nlohmann::json::parse(rawData, nullptr, false);
347         if (profileJson.is_discarded()) {
348             APP_LOGE("bad profile file");
349             return false;
350         }
351         profileInfos.emplace_back(profileJson.dump());
352         return true;
353     }
354     // hap is decompressed status, get file path then read file.
355     std::string resPath;
356     if (resMgr->GetProfileByName(profileName.c_str(), resPath) != SUCCESS) {
357         APP_LOGE("GetResFromResMgr profileName cannot be found");
358         return false;
359     }
360     APP_LOGD("GetResFromResMgr resPath is %{private}s", resPath.c_str());
361     std::string profile;
362     if (!TransformFileToJsonString(resPath, profile)) {
363         return false;
364     }
365     profileInfos.emplace_back(profile);
366     return true;
367 }
368 #endif
369 
IsFileExisted(const std::string & filePath) const370 bool BundleMgrClientImpl::IsFileExisted(const std::string &filePath) const
371 {
372     if (filePath.empty()) {
373         APP_LOGE("the file is not existed due to empty file path");
374         return false;
375     }
376 
377     if (access(filePath.c_str(), F_OK) != 0) {
378         APP_LOGE("can not access the file: %{private}s", filePath.c_str());
379         return false;
380     }
381     return true;
382 }
383 
TransformFileToJsonString(const std::string & resPath,std::string & profile) const384 bool BundleMgrClientImpl::TransformFileToJsonString(const std::string &resPath, std::string &profile) const
385 {
386     if (!IsFileExisted(resPath)) {
387         APP_LOGE("the file is not existed");
388         return false;
389     }
390     std::fstream in;
391     char errBuf[256];
392     errBuf[0] = '\0';
393     in.open(resPath, std::ios_base::in | std::ios_base::binary);
394     if (!in.is_open()) {
395         strerror_r(errno, errBuf, sizeof(errBuf));
396         APP_LOGE("the file cannot be open due to  %{public}s", errBuf);
397         return false;
398     }
399     in.seekg(0, std::ios::end);
400     int64_t size = in.tellg();
401     if (size <= 0) {
402         APP_LOGE("the file is an empty file");
403         in.close();
404         return false;
405     }
406     in.seekg(0, std::ios::beg);
407     nlohmann::json profileJson = nlohmann::json::parse(in, nullptr, false);
408     if (profileJson.is_discarded()) {
409         APP_LOGE("bad profile file");
410         in.close();
411         return false;
412     }
413     profile = profileJson.dump();
414     in.close();
415     return true;
416 }
417 
InstallSandboxApp(const std::string & bundleName,int32_t dlpType,int32_t userId,int32_t & appIndex)418 ErrCode BundleMgrClientImpl::InstallSandboxApp(const std::string &bundleName, int32_t dlpType, int32_t userId,
419     int32_t &appIndex)
420 {
421     APP_LOGD("InstallSandboxApp begin");
422     if (bundleName.empty()) {
423         APP_LOGE("InstallSandboxApp bundleName is empty");
424         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
425     }
426     ErrCode result = Connect();
427     if (result != ERR_OK) {
428         APP_LOGE("failed to connect");
429         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
430     }
431 
432     return bundleInstaller_->InstallSandboxApp(bundleName, dlpType, userId, appIndex);
433 }
434 
UninstallSandboxApp(const std::string & bundleName,int32_t appIndex,int32_t userId)435 ErrCode BundleMgrClientImpl::UninstallSandboxApp(const std::string &bundleName, int32_t appIndex, int32_t userId)
436 {
437     APP_LOGD("UninstallSandboxApp begin");
438     if (bundleName.empty() || appIndex <= Constants::INITIAL_APP_INDEX) {
439         APP_LOGE("UninstallSandboxApp params are invalid");
440         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
441     }
442     ErrCode result = Connect();
443     if (result != ERR_OK) {
444         APP_LOGE("failed to connect");
445         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
446     }
447 
448     return bundleInstaller_->UninstallSandboxApp(bundleName, appIndex, userId);
449 }
450 
GetSandboxBundleInfo(const std::string & bundleName,int32_t appIndex,int32_t userId,BundleInfo & info)451 ErrCode BundleMgrClientImpl::GetSandboxBundleInfo(
452     const std::string &bundleName, int32_t appIndex, int32_t userId, BundleInfo &info)
453 {
454     APP_LOGD("GetSandboxBundleInfo begin");
455     if (bundleName.empty() || appIndex <= Constants::INITIAL_APP_INDEX) {
456         APP_LOGE("UninstallSandboxApp params are invalid");
457         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
458     }
459 
460     ErrCode result = Connect();
461     if (result != ERR_OK) {
462         APP_LOGE("failed to connect");
463         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
464     }
465     return bundleMgr_->GetSandboxBundleInfo(bundleName, appIndex, userId, info);
466 }
467 
GetSandboxAbilityInfo(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,AbilityInfo & abilityInfo)468 ErrCode BundleMgrClientImpl::GetSandboxAbilityInfo(const Want &want, int32_t appIndex, int32_t flags, int32_t userId,
469     AbilityInfo &abilityInfo)
470 {
471     APP_LOGD("GetSandboxAbilityInfo begin");
472     if (appIndex <= Constants::INITIAL_APP_INDEX || appIndex > Constants::MAX_APP_INDEX) {
473         APP_LOGE("GetSandboxAbilityInfo params are invalid");
474         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
475     }
476     ErrCode result = Connect();
477     if (result != ERR_OK) {
478         APP_LOGE("failed to connect");
479         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
480     }
481 
482     return bundleMgr_->GetSandboxAbilityInfo(want, appIndex, flags, userId, abilityInfo);
483 }
484 
GetSandboxExtAbilityInfos(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,std::vector<ExtensionAbilityInfo> & extensionInfos)485 ErrCode BundleMgrClientImpl::GetSandboxExtAbilityInfos(const Want &want, int32_t appIndex, int32_t flags,
486     int32_t userId, std::vector<ExtensionAbilityInfo> &extensionInfos)
487 {
488     APP_LOGD("GetSandboxExtensionAbilityInfos begin");
489     if (appIndex <= Constants::INITIAL_APP_INDEX || appIndex > Constants::MAX_APP_INDEX) {
490         APP_LOGE("GetSandboxExtensionAbilityInfos params are invalid");
491         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
492     }
493     ErrCode result = Connect();
494     if (result != ERR_OK) {
495         APP_LOGE("failed to connect");
496         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
497     }
498 
499     return bundleMgr_->GetSandboxExtAbilityInfos(want, appIndex, flags, userId, extensionInfos);
500 }
501 
GetSandboxHapModuleInfo(const AbilityInfo & abilityInfo,int32_t appIndex,int32_t userId,HapModuleInfo & hapModuleInfo)502 ErrCode BundleMgrClientImpl::GetSandboxHapModuleInfo(const AbilityInfo &abilityInfo, int32_t appIndex, int32_t userId,
503     HapModuleInfo &hapModuleInfo)
504 {
505     APP_LOGD("GetSandboxHapModuleInfo begin");
506     if (appIndex <= Constants::INITIAL_APP_INDEX || appIndex > Constants::MAX_APP_INDEX) {
507         APP_LOGE("GetSandboxHapModuleInfo params are invalid");
508         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
509     }
510     ErrCode result = Connect();
511     if (result != ERR_OK) {
512         APP_LOGE("failed to connect");
513         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
514     }
515 
516     return bundleMgr_->GetSandboxHapModuleInfo(abilityInfo, appIndex, userId, hapModuleInfo);
517 }
518 
Connect()519 ErrCode BundleMgrClientImpl::Connect()
520 {
521     APP_LOGD("connect begin");
522     std::lock_guard<std::mutex> lock(mutex_);
523     if (bundleMgr_ == nullptr) {
524         sptr<ISystemAbilityManager> systemAbilityManager =
525             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
526         if (systemAbilityManager == nullptr) {
527             APP_LOGE("failed to get system ability manager");
528             return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
529         }
530 
531         sptr<IRemoteObject> remoteObject_ = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
532         if (remoteObject_ == nullptr || (bundleMgr_ = iface_cast<IBundleMgr>(remoteObject_)) == nullptr) {
533             APP_LOGE("failed to get bundle mgr service remote object");
534             return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
535         }
536         std::weak_ptr<BundleMgrClientImpl> weakPtr = shared_from_this();
537         auto deathCallback = [weakPtr](const wptr<IRemoteObject>& object) {
538             auto sharedPtr = weakPtr.lock();
539             if (sharedPtr != nullptr) {
540                 sharedPtr->OnDeath();
541             }
542         };
543         deathRecipient_ = new (std::nothrow) BundleMgrServiceDeathRecipient(deathCallback);
544         bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
545     }
546 
547     if (bundleInstaller_ == nullptr) {
548         bundleInstaller_ = bundleMgr_->GetBundleInstaller();
549         if ((bundleInstaller_ == nullptr) || (bundleInstaller_->AsObject() == nullptr)) {
550             APP_LOGE("failed to get bundle installer proxy");
551             return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
552         }
553     }
554     APP_LOGD("connect end");
555     return ERR_OK;
556 }
557 
OnDeath()558 void BundleMgrClientImpl::OnDeath()
559 {
560     APP_LOGD("BundleManagerService dead.");
561     std::lock_guard<std::mutex> lock(mutex_);
562     bundleMgr_ = nullptr;
563     bundleInstaller_ = nullptr;
564 }
565 }  // namespace AppExecFwk
566 }  // namespace OHOS