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