• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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("failed to connect");
64         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
65     }
66     std::shared_lock<std::shared_mutex> lock(mutex_);
67     return bundleMgr_->GetNameForUid(uid, name);
68 }
69 
GetBundleInfo(const std::string & bundleName,const BundleFlag flag,BundleInfo & bundleInfo,int32_t userId)70 bool BundleMgrClientImpl::GetBundleInfo(const std::string &bundleName, const BundleFlag flag, BundleInfo &bundleInfo,
71     int32_t userId)
72 {
73     LOG_D(BMS_TAG_QUERY, "GetBundleInfo begin");
74 
75     ErrCode result = Connect();
76     if (result != ERR_OK) {
77         LOG_E(BMS_TAG_QUERY, "failed to connect");
78         return false;
79     }
80 
81     std::shared_lock<std::shared_mutex> lock(mutex_);
82     return bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, userId);
83 }
84 
GetBundlePackInfo(const std::string & bundleName,const BundlePackFlag flag,BundlePackInfo & bundlePackInfo,int32_t userId)85 ErrCode BundleMgrClientImpl::GetBundlePackInfo(
86     const std::string &bundleName, const BundlePackFlag flag, BundlePackInfo &bundlePackInfo, int32_t userId)
87 {
88     APP_LOGD("enter");
89     ErrCode result = Connect();
90     if (result != ERR_OK) {
91         APP_LOGE("failed to connect");
92         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
93     }
94     std::shared_lock<std::shared_mutex> lock(mutex_);
95     return bundleMgr_->GetBundlePackInfo(bundleName, flag, bundlePackInfo, userId);
96 }
97 
CreateBundleDataDir(int32_t userId)98 ErrCode BundleMgrClientImpl::CreateBundleDataDir(int32_t userId)
99 {
100     APP_LOGD("enter");
101     ErrCode result = Connect();
102     if (result != ERR_OK) {
103         APP_LOGE("failed to connect");
104         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
105     }
106     std::shared_lock<std::shared_mutex> lock(mutex_);
107     return bundleMgr_->CreateBundleDataDir(userId);
108 }
109 
CreateBundleDataDirWithEl(int32_t userId,DataDirEl dirEl)110 ErrCode BundleMgrClientImpl::CreateBundleDataDirWithEl(int32_t userId, DataDirEl dirEl)
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     return bundleMgr_->CreateBundleDataDirWithEl(userId, dirEl);
120 }
121 
GetHapModuleInfo(const std::string & bundleName,const std::string & hapName,HapModuleInfo & hapModuleInfo)122 bool BundleMgrClientImpl::GetHapModuleInfo(const std::string &bundleName, const std::string &hapName,
123     HapModuleInfo &hapModuleInfo)
124 {
125     ErrCode result = Connect();
126     if (result != ERR_OK) {
127         APP_LOGE("failed to connect");
128         return false;
129     }
130 
131     AbilityInfo info;
132     info.bundleName = bundleName;
133     info.package = hapName;
134     std::shared_lock<std::shared_mutex> lock(mutex_);
135     return bundleMgr_->GetHapModuleInfo(info, hapModuleInfo);
136 }
137 
GetResConfigFile(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const138 bool BundleMgrClientImpl::GetResConfigFile(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
139     std::vector<std::string> &profileInfos) const
140 {
141     bool isCompressed = !hapModuleInfo.hapPath.empty();
142     std::string resourcePath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
143     if (!GetResProfileByMetadata(hapModuleInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
144         APP_LOGE("GetResProfileByMetadata failed");
145         return false;
146     }
147     if (profileInfos.empty()) {
148         APP_LOGE("no valid file can be obtained");
149         return false;
150     }
151     int32_t InfoSize = static_cast<int32_t>(profileInfos.size());
152     APP_LOGD("The size of the profile info is : %{public}d", InfoSize);
153     return true;
154 }
155 
GetResConfigFile(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const156 bool BundleMgrClientImpl::GetResConfigFile(const ExtensionAbilityInfo &extensionInfo, const std::string &metadataName,
157     std::vector<std::string> &profileInfos) const
158 {
159     bool isCompressed = !extensionInfo.hapPath.empty();
160     std::string resourcePath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
161     if (!GetResProfileByMetadata(extensionInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
162         APP_LOGE("GetResProfileByMetadata failed");
163         return false;
164     }
165     if (profileInfos.empty()) {
166         APP_LOGE("no valid file can be obtained");
167         return false;
168     }
169     int32_t InfoSize = static_cast<int32_t>(profileInfos.size());
170     APP_LOGD("The size of the profile info is : %{public}d", InfoSize);
171     return true;
172 }
173 
GetResConfigFile(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const174 bool BundleMgrClientImpl::GetResConfigFile(const AbilityInfo &abilityInfo, const std::string &metadataName,
175     std::vector<std::string> &profileInfos) const
176 {
177     bool isCompressed = !abilityInfo.hapPath.empty();
178     std::string resourcePath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
179     if (!GetResProfileByMetadata(abilityInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
180         APP_LOGE("GetResProfileByMetadata failed");
181         return false;
182     }
183     if (profileInfos.empty()) {
184         APP_LOGE("no valid file can be obtained");
185         return false;
186     }
187     return true;
188 }
189 
GetProfileFromExtension(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const190 bool BundleMgrClientImpl::GetProfileFromExtension(const ExtensionAbilityInfo &extensionInfo,
191     const std::string &metadataName, std::vector<std::string> &profileInfos) const
192 {
193     APP_LOGD("get extension config file from extension dir begin");
194     bool isCompressed = !extensionInfo.hapPath.empty();
195     std::string resPath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
196     if (!ConvertResourcePath(extensionInfo.bundleName, resPath, isCompressed)) {
197         APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
198         return false;
199     }
200     ExtensionAbilityInfo innerExtension = extensionInfo;
201     if (isCompressed) {
202         innerExtension.hapPath = resPath;
203     } else {
204         innerExtension.resourcePath = resPath;
205     }
206     return GetResConfigFile(innerExtension, metadataName, profileInfos);
207 }
208 
GetProfileFromAbility(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const209 bool BundleMgrClientImpl::GetProfileFromAbility(const AbilityInfo &abilityInfo, const std::string &metadataName,
210     std::vector<std::string> &profileInfos) const
211 {
212     APP_LOGD("get ability config file from ability begin");
213     bool isCompressed = !abilityInfo.hapPath.empty();
214     std::string resPath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
215     if (!ConvertResourcePath(abilityInfo.bundleName, resPath, isCompressed)) {
216         APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
217         return false;
218     }
219     AbilityInfo innerAbilityInfo = abilityInfo;
220     if (isCompressed) {
221         innerAbilityInfo.hapPath = resPath;
222     } else {
223         innerAbilityInfo.resourcePath = resPath;
224     }
225     return GetResConfigFile(innerAbilityInfo, metadataName, profileInfos);
226 }
227 
GetProfileFromHap(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const228 bool BundleMgrClientImpl::GetProfileFromHap(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
229     std::vector<std::string> &profileInfos) const
230 {
231     APP_LOGD("get hap module config file from hap begin");
232     bool isCompressed = !hapModuleInfo.hapPath.empty();
233     std::string resPath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
234     if (!ConvertResourcePath(hapModuleInfo.bundleName, resPath, isCompressed)) {
235         APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
236         return false;
237     }
238     HapModuleInfo innerHapModuleInfo = hapModuleInfo;
239     if (isCompressed) {
240         innerHapModuleInfo.hapPath = resPath;
241     } else {
242         innerHapModuleInfo.resourcePath = resPath;
243     }
244     return GetResConfigFile(innerHapModuleInfo, metadataName, profileInfos);
245 }
246 
ConvertResourcePath(const std::string & bundleName,std::string & resPath,bool isCompressed) const247 bool BundleMgrClientImpl::ConvertResourcePath(
248     const std::string &bundleName, std::string &resPath, bool isCompressed) const
249 {
250     if (resPath.empty()) {
251         APP_LOGE("res path is empty");
252         return false;
253     }
254     if (isCompressed && (resPath.find(DATA_APP_PATH) != 0)) {
255         APP_LOGD("no need to convert to sandbox path");
256         return true;
257     }
258     std::string innerStr = std::string(Constants::BUNDLE_CODE_DIR) + std::string(PATH_SEPARATOR) + bundleName;
259     if (resPath.find(innerStr) == std::string::npos) {
260         APP_LOGE("res path is incorrect");
261         return false;
262     }
263     resPath.replace(0, innerStr.length(), BUNDLE_MAP_CODE_PATH);
264     return true;
265 }
266 
GetResProfileByMetadata(const std::vector<Metadata> & metadata,const std::string & metadataName,const std::string & resourcePath,bool isCompressed,std::vector<std::string> & profileInfos) const267 bool BundleMgrClientImpl::GetResProfileByMetadata(const std::vector<Metadata> &metadata,
268     const std::string &metadataName, const std ::string &resourcePath, bool isCompressed,
269     std::vector<std::string> &profileInfos) const
270 {
271 #ifdef GLOBAL_RESMGR_ENABLE
272     if (metadata.empty()) {
273         APP_LOGE("GetResProfileByMetadata failed due to empty metadata");
274         return false;
275     }
276     if (resourcePath.empty()) {
277         APP_LOGE("GetResProfileByMetadata failed due to empty resourcePath");
278         return false;
279     }
280     std::shared_ptr<ResourceManager> resMgr = InitResMgr(resourcePath);
281     if (resMgr == nullptr) {
282         APP_LOGE("GetResProfileByMetadata init resMgr failed");
283         return false;
284     }
285 
286     if (metadataName.empty()) {
287         for_each(metadata.begin(), metadata.end(),
288             [this, &resMgr, isCompressed, &profileInfos](const Metadata& data)->void {
289             if (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos)) {
290                 APP_LOGW("GetResFromResMgr failed");
291             }
292         });
293     } else {
294         for_each(metadata.begin(), metadata.end(),
295             [this, &resMgr, &metadataName, isCompressed, &profileInfos](const Metadata& data)->void {
296             if ((metadataName.compare(data.name) == 0)
297                 && (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos))) {
298                 APP_LOGW("GetResFromResMgr failed");
299             }
300         });
301     }
302 
303     return true;
304 #else
305     APP_LOGW("GLOBAL_RESMGR_ENABLE is false");
306     return false;
307 #endif
308 }
309 
310 #ifdef GLOBAL_RESMGR_ENABLE
InitResMgr(const std::string & resourcePath) const311 std::shared_ptr<ResourceManager> BundleMgrClientImpl::InitResMgr(const std::string &resourcePath) const
312 {
313     APP_LOGD("InitResMgr begin");
314     if (resourcePath.empty()) {
315         APP_LOGE("InitResMgr failed due to invalid param");
316         return nullptr;
317     }
318     std::shared_ptr<ResourceManager> resMgr(CreateResourceManager());
319     if (!resMgr) {
320         APP_LOGE("InitResMgr resMgr is nullptr");
321         return nullptr;
322     }
323 
324     std::unique_ptr<ResConfig> resConfig(CreateResConfig());
325     if (!resConfig) {
326         APP_LOGE("InitResMgr resConfig is nullptr");
327         return nullptr;
328     }
329     resMgr->UpdateResConfig(*resConfig);
330 
331     APP_LOGD("resourcePath is %{private}s", resourcePath.c_str());
332     if (!resourcePath.empty() && !resMgr->AddResource(resourcePath.c_str())) {
333         APP_LOGE("InitResMgr AddResource failed");
334         return nullptr;
335     }
336     return resMgr;
337 }
338 
GetResFromResMgr(const std::string & resName,const std::shared_ptr<ResourceManager> & resMgr,bool isCompressed,std::vector<std::string> & profileInfos) const339 bool BundleMgrClientImpl::GetResFromResMgr(const std::string &resName, const std::shared_ptr<ResourceManager> &resMgr,
340     bool isCompressed, std::vector<std::string> &profileInfos) const
341 {
342     APP_LOGD("GetResFromResMgr begin");
343     if (resName.empty()) {
344         APP_LOGE("GetResFromResMgr res name is empty");
345         return false;
346     }
347 
348     size_t pos = resName.rfind(PROFILE_FILE_PREFIX);
349     if ((pos == std::string::npos) || (pos == resName.length() - strlen(PROFILE_FILE_PREFIX))) {
350         APP_LOGE("GetResFromResMgr res name %{public}s invalid", resName.c_str());
351         return false;
352     }
353     std::string profileName = resName.substr(pos + strlen(PROFILE_FILE_PREFIX));
354     // hap is compressed status, get file content.
355     if (isCompressed) {
356         APP_LOGD("compressed status");
357         std::unique_ptr<uint8_t[]> fileContentPtr = nullptr;
358         size_t len = 0;
359         if (resMgr->GetProfileDataByName(profileName.c_str(), len, fileContentPtr) != SUCCESS) {
360             APP_LOGE("GetProfileDataByName failed");
361             return false;
362         }
363         if (fileContentPtr == nullptr || len == 0) {
364             APP_LOGE("invalid data");
365             return false;
366         }
367         std::string rawData(fileContentPtr.get(), fileContentPtr.get() + len);
368         nlohmann::json profileJson = nlohmann::json::parse(rawData, nullptr, false);
369         if (profileJson.is_discarded()) {
370             APP_LOGE("bad profile file");
371             return false;
372         }
373         profileInfos.emplace_back(profileJson.dump());
374         return true;
375     }
376     // hap is decompressed status, get file path then read file.
377     std::string resPath;
378     if (resMgr->GetProfileByName(profileName.c_str(), resPath) != SUCCESS) {
379         APP_LOGE("GetResFromResMgr profileName cannot be found");
380         return false;
381     }
382     APP_LOGD("GetResFromResMgr resPath is %{private}s", resPath.c_str());
383     std::string profile;
384     if (!TransformFileToJsonString(resPath, profile)) {
385         return false;
386     }
387     profileInfos.emplace_back(profile);
388     return true;
389 }
390 #endif
391 
IsFileExisted(const std::string & filePath) const392 bool BundleMgrClientImpl::IsFileExisted(const std::string &filePath) const
393 {
394     if (filePath.empty()) {
395         APP_LOGE("the file is not existed due to empty file path");
396         return false;
397     }
398 
399     if (access(filePath.c_str(), F_OK) != 0) {
400         APP_LOGE("not access file: %{private}s errno: %{public}d", filePath.c_str(), errno);
401         return false;
402     }
403     return true;
404 }
405 
TransformFileToJsonString(const std::string & resPath,std::string & profile) const406 bool BundleMgrClientImpl::TransformFileToJsonString(const std::string &resPath, std::string &profile) const
407 {
408     if (!IsFileExisted(resPath)) {
409         APP_LOGE("the file is not existed");
410         return false;
411     }
412     std::fstream in;
413     char errBuf[256];
414     errBuf[0] = '\0';
415     in.open(resPath, std::ios_base::in | std::ios_base::binary);
416     if (!in.is_open()) {
417         strerror_r(errno, errBuf, sizeof(errBuf));
418         APP_LOGE("file open fail due to %{public}s errno:%{public}d", errBuf, errno);
419         return false;
420     }
421     in.seekg(0, std::ios::end);
422     int64_t size = in.tellg();
423     if (size <= 0) {
424         APP_LOGE("file empty err %{public}d", errno);
425         in.close();
426         return false;
427     }
428     in.seekg(0, std::ios::beg);
429     nlohmann::json profileJson = nlohmann::json::parse(in, nullptr, false);
430     if (profileJson.is_discarded()) {
431         APP_LOGE("bad profile file");
432         in.close();
433         return false;
434     }
435     profile = profileJson.dump();
436     in.close();
437     return true;
438 }
439 
InstallSandboxApp(const std::string & bundleName,int32_t dlpType,int32_t userId,int32_t & appIndex)440 ErrCode BundleMgrClientImpl::InstallSandboxApp(const std::string &bundleName, int32_t dlpType, int32_t userId,
441     int32_t &appIndex)
442 {
443     APP_LOGD("InstallSandboxApp begin");
444     if (bundleName.empty()) {
445         APP_LOGE("InstallSandboxApp bundleName is empty");
446         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
447     }
448     ErrCode result = Connect();
449     if (result != ERR_OK) {
450         APP_LOGE("failed to connect");
451         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
452     }
453 
454     std::shared_lock<std::shared_mutex> lock(mutex_);
455     return bundleInstaller_->InstallSandboxApp(bundleName, dlpType, userId, appIndex);
456 }
457 
UninstallSandboxApp(const std::string & bundleName,int32_t appIndex,int32_t userId)458 ErrCode BundleMgrClientImpl::UninstallSandboxApp(const std::string &bundleName, int32_t appIndex, int32_t userId)
459 {
460     APP_LOGD("UninstallSandboxApp begin");
461     if (bundleName.empty() || appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX) {
462         APP_LOGE("UninstallSandboxApp params are invalid");
463         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
464     }
465     ErrCode result = Connect();
466     if (result != ERR_OK) {
467         APP_LOGE("failed to connect");
468         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
469     }
470 
471     std::shared_lock<std::shared_mutex> lock(mutex_);
472     return bundleInstaller_->UninstallSandboxApp(bundleName, appIndex, userId);
473 }
474 
GetSandboxBundleInfo(const std::string & bundleName,int32_t appIndex,int32_t userId,BundleInfo & info)475 ErrCode BundleMgrClientImpl::GetSandboxBundleInfo(
476     const std::string &bundleName, int32_t appIndex, int32_t userId, BundleInfo &info)
477 {
478     APP_LOGD("GetSandboxBundleInfo begin");
479     if (bundleName.empty() || appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX) {
480         APP_LOGE("UninstallSandboxApp params are invalid");
481         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
482     }
483 
484     ErrCode result = Connect();
485     if (result != ERR_OK) {
486         APP_LOGE("failed to connect");
487         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
488     }
489     std::shared_lock<std::shared_mutex> lock(mutex_);
490     return bundleMgr_->GetSandboxBundleInfo(bundleName, appIndex, userId, info);
491 }
492 
GetSandboxAbilityInfo(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,AbilityInfo & abilityInfo)493 ErrCode BundleMgrClientImpl::GetSandboxAbilityInfo(const Want &want, int32_t appIndex, int32_t flags, int32_t userId,
494     AbilityInfo &abilityInfo)
495 {
496     APP_LOGD("GetSandboxAbilityInfo begin");
497     if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX || appIndex > Constants::MAX_SANDBOX_APP_INDEX) {
498         APP_LOGE("appIndex is invalid,: %{public}d,", appIndex);
499         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
500     }
501     ErrCode result = Connect();
502     if (result != ERR_OK) {
503         APP_LOGE("connect fail: %{public}d", result);
504         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
505     }
506 
507     std::shared_lock<std::shared_mutex> lock(mutex_);
508     return bundleMgr_->GetSandboxAbilityInfo(want, appIndex, flags, userId, abilityInfo);
509 }
510 
GetSandboxExtAbilityInfos(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,std::vector<ExtensionAbilityInfo> & extensionInfos)511 ErrCode BundleMgrClientImpl::GetSandboxExtAbilityInfos(const Want &want, int32_t appIndex, int32_t flags,
512     int32_t userId, std::vector<ExtensionAbilityInfo> &extensionInfos)
513 {
514     APP_LOGD("GetSandboxExtensionAbilityInfos begin");
515     if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX || appIndex > Constants::MAX_SANDBOX_APP_INDEX) {
516         APP_LOGE("GetSandboxExtensionAbilityInfos params are invalid");
517         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
518     }
519     ErrCode result = Connect();
520     if (result != ERR_OK) {
521         APP_LOGE("failed to connect");
522         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
523     }
524 
525     std::shared_lock<std::shared_mutex> lock(mutex_);
526     return bundleMgr_->GetSandboxExtAbilityInfos(want, appIndex, flags, userId, extensionInfos);
527 }
528 
GetSandboxHapModuleInfo(const AbilityInfo & abilityInfo,int32_t appIndex,int32_t userId,HapModuleInfo & hapModuleInfo)529 ErrCode BundleMgrClientImpl::GetSandboxHapModuleInfo(const AbilityInfo &abilityInfo, int32_t appIndex, int32_t userId,
530     HapModuleInfo &hapModuleInfo)
531 {
532     APP_LOGD("GetSandboxHapModuleInfo begin");
533     if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX || appIndex > Constants::MAX_SANDBOX_APP_INDEX) {
534         APP_LOGE("GetSandboxHapModuleInfo params are invalid");
535         return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
536     }
537     ErrCode result = Connect();
538     if (result != ERR_OK) {
539         APP_LOGE("failed to connect");
540         return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
541     }
542 
543     std::shared_lock<std::shared_mutex> lock(mutex_);
544     return bundleMgr_->GetSandboxHapModuleInfo(abilityInfo, appIndex, userId, hapModuleInfo);
545 }
546 
GetDirByBundleNameAndAppIndex(const std::string & bundleName,const int32_t appIndex,std::string & dataDir)547 ErrCode BundleMgrClientImpl::GetDirByBundleNameAndAppIndex(const std::string &bundleName, const int32_t appIndex,
548     std::string &dataDir)
549 {
550     APP_LOGD("GetDir begin");
551     Connect();
552     if (bundleMgr_ == nullptr) {
553         APP_LOGE("connect fail");
554         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
555     }
556     std::shared_lock<std::shared_mutex> lock(mutex_);
557     return bundleMgr_->GetDirByBundleNameAndAppIndex(bundleName, appIndex, dataDir);
558 }
559 
GetAllBundleDirs(int32_t userId,std::vector<BundleDir> & bundleDirs)560 ErrCode BundleMgrClientImpl::GetAllBundleDirs(int32_t userId, std::vector<BundleDir> &bundleDirs)
561 {
562     APP_LOGD("GetAllBundleDirs begin");
563     ErrCode result = Connect();
564     if (result != ERR_OK) {
565         APP_LOGE("connect fail");
566         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
567     }
568     std::shared_lock<std::shared_mutex> lock(mutex_);
569     return bundleMgr_->GetAllBundleDirs(userId, bundleDirs);
570 }
571 
Connect()572 ErrCode BundleMgrClientImpl::Connect()
573 {
574     APP_LOGD("connect begin");
575     std::unique_lock<std::shared_mutex> lock(mutex_);
576     if (bundleMgr_ == nullptr) {
577         sptr<ISystemAbilityManager> systemAbilityManager =
578             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
579         if (systemAbilityManager == nullptr) {
580             APP_LOGE("failed to get system ability manager");
581             return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
582         }
583 
584         sptr<IRemoteObject> remoteObject_ = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
585         if (remoteObject_ == nullptr || (bundleMgr_ = iface_cast<IBundleMgr>(remoteObject_)) == nullptr) {
586             APP_LOGE("failed to get bundle mgr service remote object");
587             return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
588         }
589         std::weak_ptr<BundleMgrClientImpl> weakPtr = shared_from_this();
590         auto deathCallback = [weakPtr](const wptr<IRemoteObject>& object) {
591             auto sharedPtr = weakPtr.lock();
592             if (sharedPtr != nullptr) {
593                 sharedPtr->OnDeath();
594             }
595         };
596         deathRecipient_ = new (std::nothrow) BundleMgrServiceDeathRecipient(deathCallback);
597         bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
598     }
599 
600     if (bundleInstaller_ == nullptr) {
601         bundleInstaller_ = bundleMgr_->GetBundleInstaller();
602         if ((bundleInstaller_ == nullptr) || (bundleInstaller_->AsObject() == nullptr)) {
603             APP_LOGE("failed to get bundle installer proxy");
604             return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
605         }
606     }
607     APP_LOGD("connect end");
608     return ERR_OK;
609 }
610 
OnDeath()611 void BundleMgrClientImpl::OnDeath()
612 {
613     APP_LOGD("BundleManagerService dead");
614     std::unique_lock<std::shared_mutex> lock(mutex_);
615     bundleMgr_ = nullptr;
616     bundleInstaller_ = nullptr;
617 }
618 }  // namespace AppExecFwk
619 }  // namespace OHOS