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