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