• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 
16 #include "bundle_clone_installer.h"
17 
18 #include <sstream>
19 
20 #include "ability_manager_helper.h"
21 #include "account_helper.h"
22 #include "bms_extension_data_mgr.h"
23 #include "bundle_mgr_service.h"
24 #include "bundle_permission_mgr.h"
25 #include "bundle_resource_helper.h"
26 #include "bundle_service_constants.h"
27 #include "code_protect_bundle_info.h"
28 #include "datetime_ex.h"
29 #include "hitrace_meter.h"
30 #include "installd_client.h"
31 #include "inner_bundle_clone_common.h"
32 #include "parameters.h"
33 #include "perf_profile.h"
34 #include "scope_guard.h"
35 #include "ipc_skeleton.h"
36 
37 namespace OHOS {
38 namespace AppExecFwk {
39 using namespace OHOS::Security;
40 
41 std::mutex gCloneInstallerMutex;
42 
BundleCloneInstaller()43 BundleCloneInstaller::BundleCloneInstaller()
44 {
45     APP_LOGD("bundle clone installer instance is created");
46 }
47 
~BundleCloneInstaller()48 BundleCloneInstaller::~BundleCloneInstaller()
49 {
50     APP_LOGD("bundle clone installer instance is destroyed");
51 }
52 
InstallCloneApp(const std::string & bundleName,const int32_t userId,int32_t & appIndex)53 ErrCode BundleCloneInstaller::InstallCloneApp(const std::string &bundleName,
54     const int32_t userId, int32_t &appIndex)
55 {
56     HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
57     APP_LOGD("InstallCloneApp %{public}s begin", bundleName.c_str());
58 
59     PerfProfile::GetInstance().SetBundleInstallStartTime(GetTickCount());
60 
61     ErrCode result = ProcessCloneBundleInstall(bundleName, userId, appIndex);
62     NotifyBundleEvents installRes = {
63         .type = NotifyType::INSTALL,
64         .resultCode = result,
65         .accessTokenId = accessTokenId_,
66         .uid = uid_,
67         .appIndex = appIndex,
68         .bundleName = bundleName,
69         .appId = appId_,
70         .appIdentifier = appIdentifier_,
71         .crossAppSharedConfig = isBundleCrossAppSharedConfig_
72     };
73     std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
74     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
75     commonEventMgr->NotifyBundleStatus(installRes, dataMgr);
76 
77     SendBundleSystemEvent(bundleName, BundleEventType::INSTALL, userId, appIndex,
78         false, false, InstallScene::NORMAL, result);
79 
80     ResetInstallProperties();
81     PerfProfile::GetInstance().SetBundleInstallEndTime(GetTickCount());
82     return result;
83 }
84 
UninstallCloneApp(const std::string & bundleName,const int32_t userId,const int32_t appIndex,bool sync)85 ErrCode BundleCloneInstaller::UninstallCloneApp(
86     const std::string &bundleName, const int32_t userId, const int32_t appIndex, bool sync)
87 {
88     HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
89     APP_LOGD("UninstallCloneApp %{public}s _ %{public}d begin", bundleName.c_str(), appIndex);
90 
91     PerfProfile::GetInstance().SetBundleUninstallStartTime(GetTickCount());
92 
93     ErrCode result = ProcessCloneBundleUninstall(bundleName, userId, appIndex, sync);
94     NotifyBundleEvents installRes = {
95         .type = NotifyType::UNINSTALL_BUNDLE,
96         .resultCode = result,
97         .accessTokenId = accessTokenId_,
98         .bundleName = bundleName,
99         .uid = uid_,
100         .appIndex = appIndex,
101         .appId = appId_,
102         .appIdentifier = appIdentifier_,
103         .developerId = GetDeveloperId(bundleName),
104         .assetAccessGroups = GetAssetAccessGroups(bundleName),
105         .crossAppSharedConfig = isBundleCrossAppSharedConfig_
106     };
107     std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
108     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
109     commonEventMgr->NotifyBundleStatus(installRes, dataMgr);
110 
111     SendBundleSystemEvent(bundleName, BundleEventType::UNINSTALL, userId, appIndex,
112         false, false, InstallScene::NORMAL, result);
113 
114     ResetInstallProperties();
115 
116     PerfProfile::GetInstance().SetBundleUninstallEndTime(GetTickCount());
117     return result;
118 }
119 
UninstallAllCloneApps(const std::string & bundleName,bool sync,int32_t userId)120 ErrCode BundleCloneInstaller::UninstallAllCloneApps(const std::string &bundleName, bool sync, int32_t userId)
121 {
122     // All clone will be uninstalled when the original application is updated or uninstalled
123     APP_LOGI_NOFUNC("UninstallAllCloneApps begin");
124     if (bundleName.empty()) {
125         APP_LOGE("UninstallAllCloneApps failed due to empty bundle name");
126         return ERR_APPEXECFWK_CLONE_UNINSTALL_INVALID_BUNDLE_NAME;
127     }
128     if (GetDataMgr() != ERR_OK) {
129         APP_LOGE("Get dataMgr shared_ptr nullptr");
130         return ERR_APPEXECFWK_CLONE_UNINSTALL_INTERNAL_ERROR;
131     }
132     if (!dataMgr_->HasUserId(userId)) {
133         APP_LOGE("install clone app user %{public}d not exist", userId);
134         return ERR_APPEXECFWK_CLONE_UNINSTALL_USER_NOT_EXIST;
135     }
136     InnerBundleInfo info;
137     bool isExist = dataMgr_->FetchInnerBundleInfo(bundleName, info);
138     if (!isExist) {
139         APP_LOGE("the bundle is not installed");
140         return ERR_APPEXECFWK_CLONE_UNINSTALL_APP_NOT_EXISTED;
141     }
142     InnerBundleUserInfo userInfo;
143     if (!info.GetInnerBundleUserInfo(userId, userInfo)) {
144         APP_LOGE_NOFUNC("the origin application is not installed at current user");
145         return ERR_APPEXECFWK_CLONE_UNINSTALL_NOT_INSTALLED_AT_SPECIFIED_USERID;
146     }
147     ErrCode result = ERR_OK;
148     for (auto it = userInfo.cloneInfos.begin(); it != userInfo.cloneInfos.end(); it++) {
149         if (UninstallCloneApp(bundleName, userId, atoi(it->first.c_str()), sync) != ERR_OK) {
150             APP_LOGE("UninstallCloneApp failed, appIndex %{public}s", it->first.c_str());
151             result = ERR_APPEXECFWK_CLONE_UNINSTALL_INTERNAL_ERROR;
152         }
153     }
154     APP_LOGI_NOFUNC("UninstallAllCloneApps end");
155     return result;
156 }
157 
ProcessCloneBundleInstall(const std::string & bundleName,const int32_t userId,int32_t & appIndex)158 ErrCode BundleCloneInstaller::ProcessCloneBundleInstall(const std::string &bundleName,
159     const int32_t userId, int32_t &appIndex)
160 {
161     if (bundleName.empty()) {
162         APP_LOGE("the bundle name is empty");
163         return ERR_APPEXECFWK_CLONE_INSTALL_PARAM_ERROR;
164     }
165 
166     std::shared_ptr<BundleDataMgr> dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
167 
168     if (dataMgr == nullptr) {
169         LOG_E(BMS_TAG_INSTALLER, "Get dataMgr shared_ptr nullptr");
170         return ERR_APPEXECFWK_NULL_PTR;
171     }
172 
173     std::lock_guard<std::mutex> cloneGuard(gCloneInstallerMutex);
174     // 1. check whether original application installed or not
175     InnerBundleInfo info;
176     bool isExist = dataMgr->FetchInnerBundleInfo(bundleName, info);
177     if (!isExist) {
178         APP_LOGE("the bundle is not installed");
179         return ERR_APPEXECFWK_CLONE_INSTALL_APP_NOT_EXISTED;
180     }
181     isBundleCrossAppSharedConfig_ = info.IsBundleCrossAppSharedConfig();
182 
183     // 2. obtain userId
184     if (userId < Constants::DEFAULT_USERID) {
185         APP_LOGE("userId(%{public}d) invalid", userId);
186         return ERR_APPEXECFWK_CLONE_INSTALL_USER_NOT_EXIST;
187     }
188     if (!dataMgr->HasUserId(userId)) {
189         APP_LOGE("install clone app user %{public}d not exist", userId);
190         return ERR_APPEXECFWK_CLONE_INSTALL_USER_NOT_EXIST;
191     }
192 
193     // 3. check whether original application installed at current userId or not
194     InnerBundleUserInfo userInfo;
195     if (!info.GetInnerBundleUserInfo(userId, userInfo)) {
196         APP_LOGE("the origin application is not installed at current user");
197         return ERR_APPEXECFWK_CLONE_INSTALL_NOT_INSTALLED_AT_SPECIFIED_USERID;
198     }
199 
200     ErrCode ackRes = info.VerifyAndAckCloneAppIndex(userId, appIndex);
201     if (ackRes != ERR_OK) {
202         APP_LOGE("installCloneApp fail for verifyAndAck res %{public}d", ackRes);
203         return ackRes;
204     }
205 
206     // uid
207     std::string cloneBundleName = BundleCloneCommonHelper::GetCloneBundleIdKey(bundleName, appIndex);
208     InnerBundleUserInfo tmpUserInfo;
209     tmpUserInfo.bundleName = cloneBundleName;
210     tmpUserInfo.bundleUserInfo.userId = userId;
211     dataMgr->GenerateUidAndGid(tmpUserInfo);
212     BundleUtil::MakeFsConfig(info.GetBundleName(), ServiceConstants::HMDFS_CONFIG_PATH, info.GetAppProvisionType(),
213         Constants::APP_PROVISION_TYPE_FILE_NAME);
214     int32_t uid = tmpUserInfo.uid;
215 
216     // 4. generate the accesstoken id and inherit original permissions
217     info.SetAppIndex(appIndex);
218     Security::AccessToken::AccessTokenIDEx newTokenIdEx;
219     Security::AccessToken::HapInfoCheckResult checkResult;
220     AppProvisionInfo appProvisionInfo;
221     if (dataMgr->GetAppProvisionInfo(bundleName, userId, appProvisionInfo) != ERR_OK) {
222         APP_LOGE("GetAppProvisionInfo failed bundleName:%{public}s", bundleName.c_str());
223     }
224     if (BundlePermissionMgr::InitHapToken(info, userId, 0, newTokenIdEx, checkResult,
225         appProvisionInfo.appServiceCapabilities) != ERR_OK) {
226         auto result = BundlePermissionMgr::GetCheckResultMsg(checkResult);
227         APP_LOGE("bundleName:%{public}s InitHapToken failed, %{public}s", bundleName.c_str(), result.c_str());
228         return ERR_APPEXECFWK_INSTALL_GRANT_REQUEST_PERMISSIONS_FAILED;
229     }
230     ScopeGuard applyAccessTokenGuard([&] {
231         BundlePermissionMgr::DeleteAccessTokenId(newTokenIdEx.tokenIdExStruct.tokenID);
232     });
233 
234     InnerBundleCloneInfo attr = {
235         .userId = userId,
236         .appIndex = appIndex,
237         .uid = uid,
238         .accessTokenId = newTokenIdEx.tokenIdExStruct.tokenID,
239         .accessTokenIdEx = newTokenIdEx.tokenIDEx,
240         .gids = tmpUserInfo.gids,
241     };
242     uid_ = uid;
243     accessTokenId_ = newTokenIdEx.tokenIdExStruct.tokenID;
244     versionCode_ = info.GetVersionCode();
245     appId_ = info.GetAppId();
246     appIdentifier_ = info.GetAppIdentifier();
247 
248     ScopeGuard createCloneDataDirGuard([&] { RemoveCloneDataDir(bundleName, userId, appIndex, true); });
249     ErrCode result = CreateCloneDataDir(info, userId, uid, appIndex);
250     if (result != ERR_OK) {
251         APP_LOGE("InstallCloneApp create clone dir failed");
252         return result;
253     }
254 
255     ScopeGuard addCloneBundleGuard([&] { dataMgr->RemoveCloneBundle(bundleName, userId, appIndex); });
256     ErrCode addRes = dataMgr->AddCloneBundle(bundleName, attr);
257     if (addRes != ERR_OK) {
258         APP_LOGE("dataMgr add clone bundle fail, bundleName: %{public}s, userId: %{public}d, appIndex: %{public}d",
259             bundleName.c_str(), userId, appIndex);
260         return addRes;
261     }
262 
263     ScopeGuard createEl5DirGuard([&] { RemoveEl5Dir(userInfo, uid, userId, appIndex); });
264     CreateEl5Dir(info, userId, uid, appIndex);
265 
266     // process icon and label
267     {
268         auto appIndexes = info.GetCloneBundleAppIndexes();
269         // appIndex not exist, need parse
270         BundleResourceHelper::AddCloneBundleResourceInfo(bundleName, userId, appIndex,
271             appIndexes.find(appIndex) != appIndexes.end());
272     }
273 
274     // total to commit, avoid rollback
275     applyAccessTokenGuard.Dismiss();
276     createCloneDataDirGuard.Dismiss();
277     addCloneBundleGuard.Dismiss();
278     createEl5DirGuard.Dismiss();
279     APP_LOGI("InstallCloneApp %{public}s appIndex:%{public}d succesfully", bundleName.c_str(), appIndex);
280     return ERR_OK;
281 }
282 
ProcessCloneBundleUninstall(const std::string & bundleName,int32_t userId,int32_t appIndex,bool sync)283 ErrCode BundleCloneInstaller::ProcessCloneBundleUninstall(const std::string &bundleName,
284     int32_t userId, int32_t appIndex, bool sync)
285 {
286     if (bundleName.empty()) {
287         APP_LOGE("UninstallCloneApp failed due to empty bundle name");
288         return ERR_APPEXECFWK_CLONE_UNINSTALL_INVALID_BUNDLE_NAME;
289     }
290     if (appIndex < ServiceConstants::CLONE_APP_INDEX_MIN || appIndex > ServiceConstants::CLONE_APP_INDEX_MAX) {
291         APP_LOGE("Add Clone Bundle Fail, appIndex: %{public}d not in valid range", appIndex);
292         return ERR_APPEXECFWK_CLONE_UNINSTALL_INVALID_APP_INDEX;
293     }
294     if (GetDataMgr() != ERR_OK) {
295         APP_LOGE("Get dataMgr shared_ptr nullptr");
296         return ERR_APPEXECFWK_CLONE_UNINSTALL_INTERNAL_ERROR;
297     }
298     std::lock_guard<std::mutex> cloneGuard(gCloneInstallerMutex);
299     if (!dataMgr_->HasUserId(userId)) {
300         APP_LOGE("install clone app user %{public}d not exist", userId);
301         return ERR_APPEXECFWK_CLONE_UNINSTALL_USER_NOT_EXIST;
302     }
303     InnerBundleInfo info;
304     bool isExist = dataMgr_->FetchInnerBundleInfo(bundleName, info);
305     if (!isExist) {
306         APP_LOGE("the bundle is not installed");
307         return ERR_APPEXECFWK_CLONE_UNINSTALL_APP_NOT_EXISTED;
308     }
309     isBundleCrossAppSharedConfig_ = info.IsBundleCrossAppSharedConfig();
310     InnerBundleUserInfo userInfo;
311     if (!info.GetInnerBundleUserInfo(userId, userInfo)) {
312         APP_LOGE("the origin application is not installed at current user");
313         return ERR_APPEXECFWK_CLONE_UNINSTALL_NOT_INSTALLED_AT_SPECIFIED_USERID;
314     }
315     auto it = userInfo.cloneInfos.find(std::to_string(appIndex));
316     if (it == userInfo.cloneInfos.end()) {
317         APP_LOGE("the clone app is not installed");
318         return ERR_APPEXECFWK_CLONE_UNINSTALL_APP_NOT_CLONED;
319     }
320     uid_ = it->second.uid;
321     accessTokenId_ = it->second.accessTokenId;
322     versionCode_ = info.GetVersionCode();
323     appId_ = info.GetAppId();
324     appIdentifier_ = info.GetAppIdentifier();
325     if (!AbilityManagerHelper::UninstallApplicationProcesses(bundleName, uid_, false, appIndex)) {
326         APP_LOGE("fail to kill running application");
327     }
328     if (dataMgr_->RemoveCloneBundle(bundleName, userId, appIndex)) {
329         APP_LOGE("RemoveCloneBundle failed");
330         return ERR_APPEXECFWK_CLONE_UNINSTALL_INTERNAL_ERROR;
331     }
332     if (RemoveCloneDataDir(bundleName, userId, appIndex, sync) != ERR_OK) {
333         APP_LOGW("RemoveCloneDataDir failed");
334     }
335     RemoveEl5Dir(userInfo, uid_, userId, appIndex);
336 
337     if (BundlePermissionMgr::DeleteAccessTokenId(accessTokenId_) !=
338         AccessToken::AccessTokenKitRet::RET_SUCCESS) {
339         APP_LOGE("delete AT failed clone");
340     }
341     // process icon and label
342     {
343         InnerBundleInfo info;
344         if (dataMgr_->FetchInnerBundleInfo(bundleName, info)) {
345             auto appIndexes = info.GetCloneBundleAppIndexes();
346             BundleResourceHelper::DeleteCloneBundleResourceInfo(bundleName, userId, appIndex,
347                 appIndexes.find(appIndex) != appIndexes.end());
348         }
349     }
350 #ifdef BUNDLE_FRAMEWORK_APP_CONTROL
351     std::shared_ptr<AppControlManager> appControlMgr = DelayedSingleton<AppControlManager>::GetInstance();
352     if (appControlMgr != nullptr) {
353         APP_LOGD("Delete disposed rule when bundleName :%{public}s uninstall", bundleName.c_str());
354         appControlMgr->DeleteAllDisposedRuleByBundle(info, appIndex, userId);
355     }
356 #endif
357     UninstallDebugAppSandbox(bundleName, uid_, appIndex, info);
358     APP_LOGI("UninstallCloneApp %{public}s _ %{public}d succesfully", bundleName.c_str(), appIndex);
359     return ERR_OK;
360 }
361 
UninstallDebugAppSandbox(const std::string & bundleName,const int32_t uid,int32_t appIndex,const InnerBundleInfo & innerBundleInfo)362 void BundleCloneInstaller::UninstallDebugAppSandbox(const std::string &bundleName, const int32_t uid,
363     int32_t appIndex, const InnerBundleInfo& innerBundleInfo)
364 {
365     HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
366     APP_LOGD("call UninstallDebugAppSandbox start");
367     bool isDebugApp = innerBundleInfo.GetBaseApplicationInfo().appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG;
368     bool isDeveloperMode = OHOS::system::GetBoolParameter(ServiceConstants::DEVELOPERMODE_STATE, false);
369     if (isDeveloperMode && isDebugApp) {
370         AppSpawnRemoveSandboxDirMsg removeSandboxDirMsg;
371         removeSandboxDirMsg.code = MSG_UNINSTALL_DEBUG_HAP;
372         removeSandboxDirMsg.bundleName = bundleName;
373         removeSandboxDirMsg.bundleIndex = appIndex;
374         removeSandboxDirMsg.uid = uid;
375         removeSandboxDirMsg.flags = APP_FLAGS_CLONE_ENABLE;
376         if (BundleAppSpawnClient::GetInstance().RemoveSandboxDir(removeSandboxDirMsg) != 0) {
377             APP_LOGE("RemoveSandboxDir failed");
378         }
379     }
380     APP_LOGD("call UninstallDebugAppSandbox end");
381 }
382 
383 
CreateCloneDataDir(InnerBundleInfo & info,const int32_t userId,const int32_t & uid,const int32_t & appIndex) const384 ErrCode BundleCloneInstaller::CreateCloneDataDir(InnerBundleInfo &info,
385     const int32_t userId, const int32_t &uid, const int32_t &appIndex) const
386 {
387     APP_LOGD("CreateCloneDataDir %{public}s _ %{public}d begin", info.GetBundleName().c_str(), appIndex);
388     std::string innerDataDir = BundleCloneCommonHelper::GetCloneDataDir(info.GetBundleName(), appIndex);
389     CreateDirParam createDirParam;
390     createDirParam.bundleName = innerDataDir;
391     createDirParam.userId = userId;
392     createDirParam.uid = uid;
393     createDirParam.gid = uid;
394     createDirParam.apl = info.GetAppPrivilegeLevel();
395     createDirParam.isPreInstallApp = info.IsPreInstallApp();
396     createDirParam.debug = info.GetBaseApplicationInfo().appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG;
397     auto result = InstalldClient::GetInstance()->CreateBundleDataDir(createDirParam);
398     if (result != ERR_OK) {
399         // if user is not activated, access el2-el4 may return ok but dir cannot be created
400         if (AccountHelper::IsOsAccountVerified(userId)) {
401             APP_LOGE("fail to create data dir, error is %{public}d", result);
402             return result;
403         } else {
404             APP_LOGW("user %{public}d is not activated", userId);
405         }
406     }
407     APP_LOGI("CreateCloneDataDir successfully");
408     return result;
409 }
410 
RemoveCloneDataDir(const std::string bundleName,int32_t userId,int32_t appIndex,bool sync)411 ErrCode BundleCloneInstaller::RemoveCloneDataDir(
412     const std::string bundleName, int32_t userId, int32_t appIndex, bool sync)
413 {
414     std::string key = BundleCloneCommonHelper::GetCloneDataDir(bundleName, appIndex);
415     if (InstalldClient::GetInstance()->RemoveBundleDataDir(key, userId, false, !sync) != ERR_OK) {
416         APP_LOGW("CloneApp cannot remove the data dir");
417         return ERR_APPEXECFWK_CLONE_INSTALL_INTERNAL_ERROR;
418     }
419     return ERR_OK;
420 }
421 
CreateEl5Dir(InnerBundleInfo & info,const int32_t userId,const int32_t uid,const int32_t appIndex)422 void BundleCloneInstaller::CreateEl5Dir(InnerBundleInfo &info, const int32_t userId,
423     const int32_t uid, const int32_t appIndex)
424 {
425     std::vector<RequestPermission> reqPermissions = info.GetAllRequestPermissions();
426     auto it = std::find_if(reqPermissions.begin(), reqPermissions.end(), [](const RequestPermission& permission) {
427         return permission.name == ServiceConstants::PERMISSION_PROTECT_SCREEN_LOCK_DATA;
428     });
429     if (it == reqPermissions.end()) {
430         APP_LOGD("no el5 permission");
431         return;
432     }
433     APP_LOGI("el5 -n %{public}s -i %{public}d", info.GetBundleName().c_str(), appIndex);
434     CreateDirParam el5Param;
435     el5Param.bundleName = info.GetBundleName();
436     el5Param.userId = userId;
437     el5Param.uid = uid;
438     el5Param.gid = uid;
439     el5Param.apl = info.GetAppPrivilegeLevel();
440     el5Param.isPreInstallApp = info.IsPreInstallApp();
441     el5Param.debug = info.GetBaseApplicationInfo().appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG;
442     el5Param.appIndex = appIndex;
443     if (GetDataMgr() != ERR_OK) {
444         return;
445     }
446     dataMgr_->CreateEl5Dir(std::vector<CreateDirParam> {el5Param}, true);
447 }
448 
RemoveEl5Dir(InnerBundleUserInfo & userInfo,const int32_t uid,int32_t userId,const int32_t appIndex)449 void BundleCloneInstaller::RemoveEl5Dir(InnerBundleUserInfo &userInfo, const int32_t uid,
450     int32_t userId, const int32_t appIndex)
451 {
452     APP_LOGI("el5 -n %{public}s -i %{public}d", userInfo.bundleName.c_str(), appIndex);
453     std::string key = BundleCloneCommonHelper::GetCloneDataDir(userInfo.bundleName, appIndex);
454     std::vector<std::string> dirs;
455     dirs.emplace_back(std::string(ServiceConstants::SCREEN_LOCK_FILE_DATA_PATH) + ServiceConstants::PATH_SEPARATOR +
456         std::to_string(userId) + ServiceConstants::BASE + key);
457     dirs.emplace_back(std::string(ServiceConstants::SCREEN_LOCK_FILE_DATA_PATH) + ServiceConstants::PATH_SEPARATOR +
458         std::to_string(userId) + ServiceConstants::DATABASE + key);
459     for (const std::string &dir : dirs) {
460         if (InstalldClient::GetInstance()->RemoveDir(dir) != ERR_OK) {
461             APP_LOGW("remove el5 dir %{public}s failed", dir.c_str());
462         }
463     }
464     auto it = userInfo.cloneInfos.find(std::to_string(appIndex));
465     if (it == userInfo.cloneInfos.end()) {
466         APP_LOGE("find cloneInfo failed");
467         return;
468     }
469     if (it->second.keyId.empty()) {
470         return;
471     }
472     EncryptionParam encryptionParam(key, "", 0, userId, EncryptionDirType::APP);
473     if (InstalldClient::GetInstance()->DeleteEncryptionKeyId(encryptionParam) != ERR_OK) {
474         APP_LOGW("delete encryption key id failed");
475     }
476 }
477 
GetDataMgr()478 ErrCode BundleCloneInstaller::GetDataMgr()
479 {
480     if (dataMgr_ == nullptr) {
481         dataMgr_ = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
482         if (dataMgr_ == nullptr) {
483             APP_LOGE("Get dataMgr shared_ptr nullptr");
484             return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
485         }
486     }
487     return ERR_OK;
488 }
489 
SendBundleSystemEvent(const std::string & bundleName,BundleEventType bundleEventType,int32_t userId,int32_t appIndex,bool isPreInstallApp,bool isFreeInstallMode,InstallScene preBundleScene,ErrCode errCode)490 void BundleCloneInstaller::SendBundleSystemEvent(const std::string &bundleName, BundleEventType bundleEventType,
491     int32_t userId, int32_t appIndex, bool isPreInstallApp, bool isFreeInstallMode,
492     InstallScene preBundleScene, ErrCode errCode)
493 {
494     if (std::find(Constants::EXPECTED_ERROR.begin(), Constants::EXPECTED_ERROR.end(), errCode) !=
495         Constants::EXPECTED_ERROR.end()) {
496         APP_LOGD("No need report for -e:%{public}d", errCode);
497         return;
498     }
499     EventInfo sysEventInfo;
500     sysEventInfo.bundleName = bundleName;
501     sysEventInfo.isPreInstallApp = isPreInstallApp;
502     sysEventInfo.errCode = errCode;
503     sysEventInfo.isFreeInstallMode = isFreeInstallMode;
504     sysEventInfo.userId = userId;
505     sysEventInfo.appIndex = appIndex;
506     sysEventInfo.callingUid = IPCSkeleton::GetCallingUid();
507     sysEventInfo.versionCode = versionCode_;
508     sysEventInfo.preBundleScene = preBundleScene;
509     GetCallingEventInfo(sysEventInfo);
510     EventReport::SendBundleSystemEvent(bundleEventType, sysEventInfo);
511 }
512 
GetCallingEventInfo(EventInfo & eventInfo)513 void BundleCloneInstaller::GetCallingEventInfo(EventInfo &eventInfo)
514 {
515     APP_LOGD("GetCallingEventInfo start, bundleName:%{public}s", eventInfo.callingBundleName.c_str());
516     if (dataMgr_ == nullptr) {
517         APP_LOGE("Get dataMgr shared_ptr nullptr");
518         return;
519     }
520     if (!dataMgr_->GetBundleNameForUid(eventInfo.callingUid, eventInfo.callingBundleName)) {
521         APP_LOGE("CallingUid %{public}d is not hap, no bundleName", eventInfo.callingUid);
522         eventInfo.callingBundleName = Constants::EMPTY_STRING;
523         return;
524     }
525     BundleInfo bundleInfo;
526     if (!dataMgr_->GetBundleInfo(eventInfo.callingBundleName, BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo,
527         eventInfo.callingUid / Constants::BASE_USER_RANGE)) {
528         APP_LOGE("GetBundleInfo failed, bundleName: %{public}s", eventInfo.callingBundleName.c_str());
529         return;
530     }
531     eventInfo.callingAppId = bundleInfo.appId;
532 }
533 
ResetInstallProperties()534 void BundleCloneInstaller::ResetInstallProperties()
535 {
536     uid_ = 0;
537     accessTokenId_ = 0;
538     versionCode_ = 0;
539     appId_ = "";
540     appIdentifier_ = "";
541     isBundleCrossAppSharedConfig_ = false;
542 }
543 
GetAssetAccessGroups(const std::string & bundleName)544 std::string BundleCloneInstaller::GetAssetAccessGroups(const std::string &bundleName)
545 {
546     if (GetDataMgr() != ERR_OK) {
547         APP_LOGE("DataMgr null");
548         return Constants::EMPTY_STRING;
549     }
550     std::vector<std::string> assetAccessGroups;
551     ErrCode ret = dataMgr_->GetAssetAccessGroups(bundleName, assetAccessGroups);
552     if (ret != ERR_OK) {
553         APP_LOGE("GetAssetAccessGroups failed, ret=%{public}d", ret);
554         return Constants::EMPTY_STRING;
555     }
556     std::string assetAccessGroupsStr;
557     if (!assetAccessGroups.empty()) {
558         std::stringstream assetAccessGroupsStream;
559         std::copy(assetAccessGroups.begin(), assetAccessGroups.end(),
560             std::ostream_iterator<std::string>(assetAccessGroupsStream, ","));
561         assetAccessGroupsStr = assetAccessGroupsStream.str();
562         if (!assetAccessGroupsStr.empty()) {
563             assetAccessGroupsStr.pop_back();
564         }
565     }
566     return assetAccessGroupsStr;
567 }
568 
GetDeveloperId(const std::string & bundleName)569 std::string BundleCloneInstaller::GetDeveloperId(const std::string &bundleName)
570 {
571     if (GetDataMgr() != ERR_OK) {
572         APP_LOGE("DataMgr null");
573         return Constants::EMPTY_STRING;
574     }
575     std::string developerId;
576     ErrCode ret = dataMgr_->GetDeveloperId(bundleName, developerId);
577     if (ret != ERR_OK) {
578         APP_LOGE("GetDeveloperId failed, ret=%{public}d", ret);
579     }
580     return developerId;
581 }
582 } // AppExecFwk
583 } // OHOS
584