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