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