1 /*
2 * Copyright (c) 2022 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 "bundle_constants.h"
23 #include "bundle_mgr_interface.h"
24 #include "bundle_mgr_proxy.h"
25 #include "bundle_mgr_service_death_recipient.h"
26 #include "iservice_registry.h"
27 #include "nlohmann/json.hpp"
28 #include "system_ability_definition.h"
29
30 #ifdef GLOBAL_RESMGR_ENABLE
31 using namespace OHOS::Global::Resource;
32 #endif
33
34 namespace OHOS {
35 namespace AppExecFwk {
36 namespace {
37 const std::string BUNDLE_MAP_CODE_PATH = "/data/storage/el1/bundle";
38 const std::string DATA_APP_PATH = "/data/app";
39 constexpr const char* PROFILE_FILE_PREFIX = "$profile:";
40 } // namespace
41
BundleMgrClientImpl()42 BundleMgrClientImpl::BundleMgrClientImpl()
43 {
44 APP_LOGD("create bundleMgrClientImpl");
45 }
46
~BundleMgrClientImpl()47 BundleMgrClientImpl::~BundleMgrClientImpl()
48 {
49 APP_LOGD("destroy bundleMgrClientImpl");
50 if (bundleMgr_ != nullptr && deathRecipient_ != nullptr) {
51 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
52 }
53 }
54
GetNameForUid(const int uid,std::string & name)55 ErrCode BundleMgrClientImpl::GetNameForUid(const int uid, std::string &name)
56 {
57 if (Connect() != ERR_OK) {
58 APP_LOGE("failed to connect");
59 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
60 }
61 return bundleMgr_->GetNameForUid(uid, name);
62 }
63
GetBundleInfo(const std::string & bundleName,const BundleFlag flag,BundleInfo & bundleInfo,int32_t userId)64 bool BundleMgrClientImpl::GetBundleInfo(const std::string &bundleName, const BundleFlag flag, BundleInfo &bundleInfo,
65 int32_t userId)
66 {
67 APP_LOGD("GetBundleInfo begin");
68
69 ErrCode result = Connect();
70 if (result != ERR_OK) {
71 APP_LOGE("failed to connect");
72 return false;
73 }
74
75 return bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, userId);
76 }
77
GetBundlePackInfo(const std::string & bundleName,const BundlePackFlag flag,BundlePackInfo & bundlePackInfo,int32_t userId)78 ErrCode BundleMgrClientImpl::GetBundlePackInfo(
79 const std::string &bundleName, const BundlePackFlag flag, BundlePackInfo &bundlePackInfo, int32_t userId)
80 {
81 APP_LOGD("enter");
82 ErrCode result = Connect();
83 if (result != ERR_OK) {
84 APP_LOGE("failed to connect");
85 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
86 }
87 return bundleMgr_->GetBundlePackInfo(bundleName, flag, bundlePackInfo, userId);
88 }
89
CreateBundleDataDir(int32_t userId)90 ErrCode BundleMgrClientImpl::CreateBundleDataDir(int32_t userId)
91 {
92 APP_LOGD("enter");
93 ErrCode result = Connect();
94 if (result != ERR_OK) {
95 APP_LOGE("failed to connect");
96 return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
97 }
98 return bundleMgr_->CreateBundleDataDir(userId);
99 }
100
GetHapModuleInfo(const std::string & bundleName,const std::string & hapName,HapModuleInfo & hapModuleInfo)101 bool BundleMgrClientImpl::GetHapModuleInfo(const std::string &bundleName, const std::string &hapName,
102 HapModuleInfo &hapModuleInfo)
103 {
104 ErrCode result = Connect();
105 if (result != ERR_OK) {
106 APP_LOGE("failed to connect");
107 return false;
108 }
109
110 AbilityInfo info;
111 info.bundleName = bundleName;
112 info.package = hapName;
113 return bundleMgr_->GetHapModuleInfo(info, hapModuleInfo);
114 }
115
GetResConfigFile(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const116 bool BundleMgrClientImpl::GetResConfigFile(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
117 std::vector<std::string> &profileInfos) const
118 {
119 bool isCompressed = !hapModuleInfo.hapPath.empty();
120 std::string resourcePath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
121 if (!GetResProfileByMetadata(hapModuleInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
122 APP_LOGE("GetResProfileByMetadata failed");
123 return false;
124 }
125 if (profileInfos.empty()) {
126 APP_LOGE("no valid file can be obtained");
127 return false;
128 }
129 int32_t InfoSize = profileInfos.size();
130 APP_LOGD("The size of the profile info is : %{public}d", InfoSize);
131 return true;
132 }
133
GetResConfigFile(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const134 bool BundleMgrClientImpl::GetResConfigFile(const ExtensionAbilityInfo &extensionInfo, const std::string &metadataName,
135 std::vector<std::string> &profileInfos) const
136 {
137 bool isCompressed = !extensionInfo.hapPath.empty();
138 std::string resourcePath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
139 if (!GetResProfileByMetadata(extensionInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
140 APP_LOGE("GetResProfileByMetadata failed");
141 return false;
142 }
143 if (profileInfos.empty()) {
144 APP_LOGE("no valid file can be obtained");
145 return false;
146 }
147 int32_t InfoSize = profileInfos.size();
148 APP_LOGD("The size of the profile info is : %{public}d", InfoSize);
149 return true;
150 }
151
GetResConfigFile(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const152 bool BundleMgrClientImpl::GetResConfigFile(const AbilityInfo &abilityInfo, const std::string &metadataName,
153 std::vector<std::string> &profileInfos) const
154 {
155 bool isCompressed = !abilityInfo.hapPath.empty();
156 std::string resourcePath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
157 if (!GetResProfileByMetadata(abilityInfo.metadata, metadataName, resourcePath, isCompressed, profileInfos)) {
158 APP_LOGE("GetResProfileByMetadata failed");
159 return false;
160 }
161 if (profileInfos.empty()) {
162 APP_LOGE("no valid file can be obtained");
163 return false;
164 }
165 return true;
166 }
167
GetProfileFromExtension(const ExtensionAbilityInfo & extensionInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const168 bool BundleMgrClientImpl::GetProfileFromExtension(const ExtensionAbilityInfo &extensionInfo,
169 const std::string &metadataName, std::vector<std::string> &profileInfos) const
170 {
171 APP_LOGD("get extension config file from extension dir begin");
172 bool isCompressed = !extensionInfo.hapPath.empty();
173 std::string resPath = isCompressed ? extensionInfo.hapPath : extensionInfo.resourcePath;
174 if (!ConvertResourcePath(extensionInfo.bundleName, resPath, isCompressed)) {
175 APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
176 return false;
177 }
178 ExtensionAbilityInfo innerExtension = extensionInfo;
179 if (isCompressed) {
180 innerExtension.hapPath = resPath;
181 } else {
182 innerExtension.resourcePath = resPath;
183 }
184 return GetResConfigFile(innerExtension, metadataName, profileInfos);
185 }
186
GetProfileFromAbility(const AbilityInfo & abilityInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const187 bool BundleMgrClientImpl::GetProfileFromAbility(const AbilityInfo &abilityInfo, const std::string &metadataName,
188 std::vector<std::string> &profileInfos) const
189 {
190 APP_LOGD("get ability config file from ability begin");
191 bool isCompressed = !abilityInfo.hapPath.empty();
192 std::string resPath = isCompressed ? abilityInfo.hapPath : abilityInfo.resourcePath;
193 if (!ConvertResourcePath(abilityInfo.bundleName, resPath, isCompressed)) {
194 APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
195 return false;
196 }
197 AbilityInfo innerAbilityInfo = abilityInfo;
198 if (isCompressed) {
199 innerAbilityInfo.hapPath = resPath;
200 } else {
201 innerAbilityInfo.resourcePath = resPath;
202 }
203 return GetResConfigFile(innerAbilityInfo, metadataName, profileInfos);
204 }
205
GetProfileFromHap(const HapModuleInfo & hapModuleInfo,const std::string & metadataName,std::vector<std::string> & profileInfos) const206 bool BundleMgrClientImpl::GetProfileFromHap(const HapModuleInfo &hapModuleInfo, const std::string &metadataName,
207 std::vector<std::string> &profileInfos) const
208 {
209 APP_LOGD("get hap module config file from hap begin");
210 bool isCompressed = !hapModuleInfo.hapPath.empty();
211 std::string resPath = isCompressed ? hapModuleInfo.hapPath : hapModuleInfo.resourcePath;
212 if (!ConvertResourcePath(hapModuleInfo.bundleName, resPath, isCompressed)) {
213 APP_LOGE("ConvertResourcePath failed %{public}s", resPath.c_str());
214 return false;
215 }
216 HapModuleInfo innerHapModuleInfo = hapModuleInfo;
217 if (isCompressed) {
218 innerHapModuleInfo.hapPath = resPath;
219 } else {
220 innerHapModuleInfo.resourcePath = resPath;
221 }
222 return GetResConfigFile(innerHapModuleInfo, metadataName, profileInfos);
223 }
224
ConvertResourcePath(const std::string & bundleName,std::string & resPath,bool isCompressed) const225 bool BundleMgrClientImpl::ConvertResourcePath(
226 const std::string &bundleName, std::string &resPath, bool isCompressed) const
227 {
228 if (resPath.empty()) {
229 APP_LOGE("res path is empty");
230 return false;
231 }
232 if (isCompressed && (resPath.find(DATA_APP_PATH) != 0)) {
233 APP_LOGD("no need to convert to sandbox path");
234 return true;
235 }
236 std::string innerStr = Constants::BUNDLE_CODE_DIR + Constants::PATH_SEPARATOR + bundleName;
237 if (resPath.find(innerStr) == std::string::npos) {
238 APP_LOGE("res path is incorrect");
239 return false;
240 }
241 resPath.replace(0, innerStr.length(), BUNDLE_MAP_CODE_PATH);
242 return true;
243 }
244
GetResProfileByMetadata(const std::vector<Metadata> & metadata,const std::string & metadataName,const std::string & resourcePath,bool isCompressed,std::vector<std::string> & profileInfos) const245 bool BundleMgrClientImpl::GetResProfileByMetadata(const std::vector<Metadata> &metadata,
246 const std::string &metadataName, const std ::string &resourcePath, bool isCompressed,
247 std::vector<std::string> &profileInfos) const
248 {
249 #ifdef GLOBAL_RESMGR_ENABLE
250 if (metadata.empty()) {
251 APP_LOGE("GetResProfileByMetadata failed due to empty metadata");
252 return false;
253 }
254 if (resourcePath.empty()) {
255 APP_LOGE("GetResProfileByMetadata failed due to empty resourcePath");
256 return false;
257 }
258 std::shared_ptr<ResourceManager> resMgr = InitResMgr(resourcePath);
259 if (resMgr == nullptr) {
260 APP_LOGE("GetResProfileByMetadata init resMgr failed");
261 return false;
262 }
263
264 if (metadataName.empty()) {
265 for_each(metadata.begin(), metadata.end(),
266 [this, &resMgr, isCompressed, &profileInfos](const Metadata& data)->void {
267 if (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos)) {
268 APP_LOGW("GetResFromResMgr failed");
269 }
270 });
271 } else {
272 for_each(metadata.begin(), metadata.end(),
273 [this, &resMgr, &metadataName, isCompressed, &profileInfos](const Metadata& data)->void {
274 if ((metadataName.compare(data.name) == 0)
275 && (!GetResFromResMgr(data.resource, resMgr, isCompressed, profileInfos))) {
276 APP_LOGW("GetResFromResMgr failed");
277 }
278 });
279 }
280
281 return true;
282 #else
283 APP_LOGW("GLOBAL_RESMGR_ENABLE is false");
284 return false;
285 #endif
286 }
287
288 #ifdef GLOBAL_RESMGR_ENABLE
InitResMgr(const std::string & resourcePath) const289 std::shared_ptr<ResourceManager> BundleMgrClientImpl::InitResMgr(const std::string &resourcePath) const
290 {
291 APP_LOGD("InitResMgr begin");
292 if (resourcePath.empty()) {
293 APP_LOGE("InitResMgr failed due to invalid param");
294 return nullptr;
295 }
296 std::shared_ptr<ResourceManager> resMgr(CreateResourceManager());
297 if (!resMgr) {
298 APP_LOGE("InitResMgr resMgr is nullptr");
299 return nullptr;
300 }
301
302 std::unique_ptr<ResConfig> resConfig(CreateResConfig());
303 if (!resConfig) {
304 APP_LOGE("InitResMgr resConfig is nullptr");
305 return nullptr;
306 }
307 resMgr->UpdateResConfig(*resConfig);
308
309 APP_LOGD("resourcePath is %{private}s", resourcePath.c_str());
310 if (!resourcePath.empty() && !resMgr->AddResource(resourcePath.c_str())) {
311 APP_LOGE("InitResMgr AddResource failed");
312 return nullptr;
313 }
314 return resMgr;
315 }
316
GetResFromResMgr(const std::string & resName,const std::shared_ptr<ResourceManager> & resMgr,bool isCompressed,std::vector<std::string> & profileInfos) const317 bool BundleMgrClientImpl::GetResFromResMgr(const std::string &resName, const std::shared_ptr<ResourceManager> &resMgr,
318 bool isCompressed, std::vector<std::string> &profileInfos) const
319 {
320 APP_LOGD("GetResFromResMgr begin");
321 if (resName.empty()) {
322 APP_LOGE("GetResFromResMgr res name is empty");
323 return false;
324 }
325
326 size_t pos = resName.rfind(PROFILE_FILE_PREFIX);
327 if ((pos == std::string::npos) || (pos == resName.length() - strlen(PROFILE_FILE_PREFIX))) {
328 APP_LOGE("GetResFromResMgr res name %{public}s is invalid", resName.c_str());
329 return false;
330 }
331 std::string profileName = resName.substr(pos + strlen(PROFILE_FILE_PREFIX));
332 // hap is compressed status, get file content.
333 if (isCompressed) {
334 APP_LOGD("compressed status.");
335 std::unique_ptr<uint8_t[]> fileContentPtr = nullptr;
336 size_t len = 0;
337 if (resMgr->GetProfileDataByName(profileName.c_str(), len, fileContentPtr) != SUCCESS) {
338 APP_LOGE("GetProfileDataByName failed");
339 return false;
340 }
341 if (fileContentPtr == nullptr || len == 0) {
342 APP_LOGE("invalid data");
343 return false;
344 }
345 std::string rawData(fileContentPtr.get(), fileContentPtr.get() + len);
346 nlohmann::json profileJson = nlohmann::json::parse(rawData, nullptr, false);
347 if (profileJson.is_discarded()) {
348 APP_LOGE("bad profile file");
349 return false;
350 }
351 profileInfos.emplace_back(profileJson.dump());
352 return true;
353 }
354 // hap is decompressed status, get file path then read file.
355 std::string resPath;
356 if (resMgr->GetProfileByName(profileName.c_str(), resPath) != SUCCESS) {
357 APP_LOGE("GetResFromResMgr profileName cannot be found");
358 return false;
359 }
360 APP_LOGD("GetResFromResMgr resPath is %{private}s", resPath.c_str());
361 std::string profile;
362 if (!TransformFileToJsonString(resPath, profile)) {
363 return false;
364 }
365 profileInfos.emplace_back(profile);
366 return true;
367 }
368 #endif
369
IsFileExisted(const std::string & filePath) const370 bool BundleMgrClientImpl::IsFileExisted(const std::string &filePath) const
371 {
372 if (filePath.empty()) {
373 APP_LOGE("the file is not existed due to empty file path");
374 return false;
375 }
376
377 if (access(filePath.c_str(), F_OK) != 0) {
378 APP_LOGE("can not access the file: %{private}s", filePath.c_str());
379 return false;
380 }
381 return true;
382 }
383
TransformFileToJsonString(const std::string & resPath,std::string & profile) const384 bool BundleMgrClientImpl::TransformFileToJsonString(const std::string &resPath, std::string &profile) const
385 {
386 if (!IsFileExisted(resPath)) {
387 APP_LOGE("the file is not existed");
388 return false;
389 }
390 std::fstream in;
391 char errBuf[256];
392 errBuf[0] = '\0';
393 in.open(resPath, std::ios_base::in | std::ios_base::binary);
394 if (!in.is_open()) {
395 strerror_r(errno, errBuf, sizeof(errBuf));
396 APP_LOGE("the file cannot be open due to %{public}s", errBuf);
397 return false;
398 }
399 in.seekg(0, std::ios::end);
400 int64_t size = in.tellg();
401 if (size <= 0) {
402 APP_LOGE("the file is an empty file");
403 in.close();
404 return false;
405 }
406 in.seekg(0, std::ios::beg);
407 nlohmann::json profileJson = nlohmann::json::parse(in, nullptr, false);
408 if (profileJson.is_discarded()) {
409 APP_LOGE("bad profile file");
410 in.close();
411 return false;
412 }
413 profile = profileJson.dump();
414 in.close();
415 return true;
416 }
417
InstallSandboxApp(const std::string & bundleName,int32_t dlpType,int32_t userId,int32_t & appIndex)418 ErrCode BundleMgrClientImpl::InstallSandboxApp(const std::string &bundleName, int32_t dlpType, int32_t userId,
419 int32_t &appIndex)
420 {
421 APP_LOGD("InstallSandboxApp begin");
422 if (bundleName.empty()) {
423 APP_LOGE("InstallSandboxApp bundleName is empty");
424 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
425 }
426 ErrCode result = Connect();
427 if (result != ERR_OK) {
428 APP_LOGE("failed to connect");
429 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
430 }
431
432 return bundleInstaller_->InstallSandboxApp(bundleName, dlpType, userId, appIndex);
433 }
434
UninstallSandboxApp(const std::string & bundleName,int32_t appIndex,int32_t userId)435 ErrCode BundleMgrClientImpl::UninstallSandboxApp(const std::string &bundleName, int32_t appIndex, int32_t userId)
436 {
437 APP_LOGD("UninstallSandboxApp begin");
438 if (bundleName.empty() || appIndex <= Constants::INITIAL_APP_INDEX) {
439 APP_LOGE("UninstallSandboxApp params are invalid");
440 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
441 }
442 ErrCode result = Connect();
443 if (result != ERR_OK) {
444 APP_LOGE("failed to connect");
445 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
446 }
447
448 return bundleInstaller_->UninstallSandboxApp(bundleName, appIndex, userId);
449 }
450
GetSandboxBundleInfo(const std::string & bundleName,int32_t appIndex,int32_t userId,BundleInfo & info)451 ErrCode BundleMgrClientImpl::GetSandboxBundleInfo(
452 const std::string &bundleName, int32_t appIndex, int32_t userId, BundleInfo &info)
453 {
454 APP_LOGD("GetSandboxBundleInfo begin");
455 if (bundleName.empty() || appIndex <= Constants::INITIAL_APP_INDEX) {
456 APP_LOGE("UninstallSandboxApp params are invalid");
457 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
458 }
459
460 ErrCode result = Connect();
461 if (result != ERR_OK) {
462 APP_LOGE("failed to connect");
463 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
464 }
465 return bundleMgr_->GetSandboxBundleInfo(bundleName, appIndex, userId, info);
466 }
467
GetSandboxAbilityInfo(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,AbilityInfo & abilityInfo)468 ErrCode BundleMgrClientImpl::GetSandboxAbilityInfo(const Want &want, int32_t appIndex, int32_t flags, int32_t userId,
469 AbilityInfo &abilityInfo)
470 {
471 APP_LOGD("GetSandboxAbilityInfo begin");
472 if (appIndex <= Constants::INITIAL_APP_INDEX || appIndex > Constants::MAX_APP_INDEX) {
473 APP_LOGE("GetSandboxAbilityInfo params are invalid");
474 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
475 }
476 ErrCode result = Connect();
477 if (result != ERR_OK) {
478 APP_LOGE("failed to connect");
479 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
480 }
481
482 return bundleMgr_->GetSandboxAbilityInfo(want, appIndex, flags, userId, abilityInfo);
483 }
484
GetSandboxExtAbilityInfos(const Want & want,int32_t appIndex,int32_t flags,int32_t userId,std::vector<ExtensionAbilityInfo> & extensionInfos)485 ErrCode BundleMgrClientImpl::GetSandboxExtAbilityInfos(const Want &want, int32_t appIndex, int32_t flags,
486 int32_t userId, std::vector<ExtensionAbilityInfo> &extensionInfos)
487 {
488 APP_LOGD("GetSandboxExtensionAbilityInfos begin");
489 if (appIndex <= Constants::INITIAL_APP_INDEX || appIndex > Constants::MAX_APP_INDEX) {
490 APP_LOGE("GetSandboxExtensionAbilityInfos params are invalid");
491 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
492 }
493 ErrCode result = Connect();
494 if (result != ERR_OK) {
495 APP_LOGE("failed to connect");
496 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
497 }
498
499 return bundleMgr_->GetSandboxExtAbilityInfos(want, appIndex, flags, userId, extensionInfos);
500 }
501
GetSandboxHapModuleInfo(const AbilityInfo & abilityInfo,int32_t appIndex,int32_t userId,HapModuleInfo & hapModuleInfo)502 ErrCode BundleMgrClientImpl::GetSandboxHapModuleInfo(const AbilityInfo &abilityInfo, int32_t appIndex, int32_t userId,
503 HapModuleInfo &hapModuleInfo)
504 {
505 APP_LOGD("GetSandboxHapModuleInfo begin");
506 if (appIndex <= Constants::INITIAL_APP_INDEX || appIndex > Constants::MAX_APP_INDEX) {
507 APP_LOGE("GetSandboxHapModuleInfo params are invalid");
508 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
509 }
510 ErrCode result = Connect();
511 if (result != ERR_OK) {
512 APP_LOGE("failed to connect");
513 return ERR_APPEXECFWK_SANDBOX_INSTALL_INTERNAL_ERROR;
514 }
515
516 return bundleMgr_->GetSandboxHapModuleInfo(abilityInfo, appIndex, userId, hapModuleInfo);
517 }
518
Connect()519 ErrCode BundleMgrClientImpl::Connect()
520 {
521 APP_LOGD("connect begin");
522 std::lock_guard<std::mutex> lock(mutex_);
523 if (bundleMgr_ == nullptr) {
524 sptr<ISystemAbilityManager> systemAbilityManager =
525 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
526 if (systemAbilityManager == nullptr) {
527 APP_LOGE("failed to get system ability manager");
528 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
529 }
530
531 sptr<IRemoteObject> remoteObject_ = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
532 if (remoteObject_ == nullptr || (bundleMgr_ = iface_cast<IBundleMgr>(remoteObject_)) == nullptr) {
533 APP_LOGE("failed to get bundle mgr service remote object");
534 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
535 }
536 std::weak_ptr<BundleMgrClientImpl> weakPtr = shared_from_this();
537 auto deathCallback = [weakPtr](const wptr<IRemoteObject>& object) {
538 auto sharedPtr = weakPtr.lock();
539 if (sharedPtr != nullptr) {
540 sharedPtr->OnDeath();
541 }
542 };
543 deathRecipient_ = new (std::nothrow) BundleMgrServiceDeathRecipient(deathCallback);
544 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
545 }
546
547 if (bundleInstaller_ == nullptr) {
548 bundleInstaller_ = bundleMgr_->GetBundleInstaller();
549 if ((bundleInstaller_ == nullptr) || (bundleInstaller_->AsObject() == nullptr)) {
550 APP_LOGE("failed to get bundle installer proxy");
551 return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
552 }
553 }
554 APP_LOGD("connect end");
555 return ERR_OK;
556 }
557
OnDeath()558 void BundleMgrClientImpl::OnDeath()
559 {
560 APP_LOGD("BundleManagerService dead.");
561 std::lock_guard<std::mutex> lock(mutex_);
562 bundleMgr_ = nullptr;
563 bundleInstaller_ = nullptr;
564 }
565 } // namespace AppExecFwk
566 } // namespace OHOS