1 /*
2 * Copyright (c) 2023 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 "app_service_fwk_installer.h"
17
18 #include "app_provision_info_manager.h"
19 #include "bundle_mgr_service.h"
20 #include "inner_patch_info.h"
21 #include "installd_client.h"
22 #include "ipc_skeleton.h"
23 #include "patch_data_mgr.h"
24 #include "scope_guard.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
28 namespace {
29 constexpr const char* HSP_VERSION_PREFIX = "v";
30 constexpr const char* HSP_PATH = ", path: ";
31 constexpr const char* SHARED_MODULE_TYPE = "shared";
32 constexpr const char* COMPILE_SDK_TYPE_OPEN_HARMONY = "OpenHarmony";
33 constexpr const char* DEBUG_APP_IDENTIFIER = "DEBUG_LIB_ID";
34 constexpr const char* APP_INSTALL_PATH = "/data/app/el1/bundle";
35 constexpr const int64_t FIVE_MB = 1024 * 1024 * 5; // 5MB
36 }
37
ObtainTempSoPath(const std::string & moduleName,const std::string & nativeLibPath)38 std::string ObtainTempSoPath(
39 const std::string &moduleName, const std::string &nativeLibPath)
40 {
41 std::string tempSoPath;
42 if (nativeLibPath.empty()) {
43 APP_LOGE("invalid native libs path");
44 return tempSoPath;
45 }
46 tempSoPath = nativeLibPath;
47 auto pos = tempSoPath.find(moduleName);
48 if (pos == std::string::npos) {
49 tempSoPath = moduleName + AppExecFwk::ServiceConstants::TMP_SUFFIX
50 + AppExecFwk::ServiceConstants::PATH_SEPARATOR + tempSoPath;
51 } else {
52 std::string innerTempStr = moduleName + AppExecFwk::ServiceConstants::TMP_SUFFIX;
53 tempSoPath.replace(pos, moduleName.length(), innerTempStr);
54 }
55 return tempSoPath + AppExecFwk::ServiceConstants::PATH_SEPARATOR;
56 };
57
BuildCheckParam(const InstallParam & installParam,InstallCheckParam & checkParam)58 void BuildCheckParam(
59 const InstallParam &installParam, InstallCheckParam &checkParam)
60 {
61 checkParam.isPreInstallApp = installParam.isPreInstallApp;
62 checkParam.crowdtestDeadline = installParam.crowdtestDeadline;
63 checkParam.appType = AppExecFwk::Constants::AppType::SYSTEM_APP;
64 checkParam.removable = installParam.removable;
65 checkParam.installBundlePermissionStatus = installParam.installBundlePermissionStatus;
66 checkParam.installEnterpriseBundlePermissionStatus = installParam.installEnterpriseBundlePermissionStatus;
67 checkParam.installEtpNormalBundlePermissionStatus = installParam.installEtpNormalBundlePermissionStatus;
68 checkParam.installEtpMdmBundlePermissionStatus = installParam.installEtpMdmBundlePermissionStatus;
69 checkParam.isCallByShell = installParam.isCallByShell;
70 checkParam.needSendEvent = installParam.needSendEvent;
71 checkParam.specifiedDistributionType = installParam.specifiedDistributionType;
72 };
73
AppServiceFwkInstaller()74 AppServiceFwkInstaller::AppServiceFwkInstaller()
75 : bundleInstallChecker_(std::make_unique<BundleInstallChecker>())
76 {
77 APP_LOGI_NOFUNC("AppServiceFwk installer instance created");
78 }
79
~AppServiceFwkInstaller()80 AppServiceFwkInstaller::~AppServiceFwkInstaller()
81 {
82 APP_LOGI_NOFUNC("AppServiceFwk installer instance destroyed");
83 }
84
Install(const std::vector<std::string> & hspPaths,InstallParam & installParam)85 ErrCode AppServiceFwkInstaller::Install(
86 const std::vector<std::string> &hspPaths, InstallParam &installParam)
87 {
88 ErrCode result = BeforeInstall(hspPaths, installParam);
89 CHECK_RESULT(result, "BeforeInstall check failed %{public}d");
90 result = ProcessInstall(hspPaths, installParam);
91 APP_LOGI("%{public}s %{public}s result %{public}d first time", hspPaths[0].c_str(), bundleName_.c_str(), result);
92 if (result != ERR_OK && installParam.copyHapToInstallPath) {
93 PreInstallBundleInfo preInstallBundleInfo;
94 if (!dataMgr_->GetPreInstallBundleInfo(bundleName_, preInstallBundleInfo) ||
95 preInstallBundleInfo.GetBundlePaths().empty()) {
96 APP_LOGE("get preInstallBundleInfo failed");
97 return ERR_APPEXECFWK_INSTALL_BUNDLE_MGR_SERVICE_ERROR;
98 }
99 ResetProperties();
100 auto uninstallRes = UnInstall(bundleName_, true);
101 ResetProperties();
102 InstallParam reinstallParam;
103 reinstallParam.isPreInstallApp = true;
104 reinstallParam.removable = false;
105 reinstallParam.copyHapToInstallPath = false;
106 reinstallParam.needSavePreInstallInfo = true;
107 result = ProcessInstall(preInstallBundleInfo.GetBundlePaths(), reinstallParam);
108 APP_LOGI("uninstallRes %{public}d installRes second time %{public}d", uninstallRes, result);
109 } else if (result != ERR_OK && installParam.isOTA) {
110 ResetProperties();
111 auto uninstallRes = UnInstall(bundleName_, true);
112 ResetProperties();
113 result = ProcessInstall(hspPaths, installParam);
114 APP_LOGI("uninstallRes %{public}d installRes second time %{public}d", uninstallRes, result);
115 }
116 SendBundleSystemEvent(
117 hspPaths,
118 BundleEventType::INSTALL,
119 installParam,
120 (installParam.isOTA ? InstallScene::REBOOT : InstallScene::BOOT),
121 result);
122 return result;
123 }
124
UnInstall(const std::string & bundleName,bool isKeepData)125 ErrCode AppServiceFwkInstaller::UnInstall(const std::string &bundleName, bool isKeepData)
126 {
127 APP_LOGI("Uninstall bundle %{public}s", bundleName.c_str());
128 if (BeforeUninstall(bundleName) != ERR_OK) {
129 APP_LOGE("check bundleType failed for bundle %{public}s", bundleName.c_str());
130 return ERR_APPEXECFWK_UNINSTALL_PARAM_ERROR;
131 }
132 if (!dataMgr_->UpdateBundleInstallState(bundleName, InstallState::UNINSTALL_START)) {
133 APP_LOGE("uninstall already start");
134 return ERR_APPEXECFWK_UPDATE_BUNDLE_INSTALL_STATUS_ERROR;
135 }
136 if (!dataMgr_->UpdateBundleInstallState(bundleName, InstallState::UNINSTALL_SUCCESS)) {
137 APP_LOGE("delete inner info failed for bundle %{public}s", bundleName.c_str());
138 return ERR_APPEXECFWK_UPDATE_BUNDLE_INSTALL_STATUS_ERROR;
139 }
140 PreInstallBundleInfo preInstallBundleInfo;
141 if (dataMgr_->GetPreInstallBundleInfo(bundleName, preInstallBundleInfo)) {
142 dataMgr_->DeletePreInstallBundleInfo(bundleName, preInstallBundleInfo);
143 }
144 std::string bundleDir =
145 std::string(AppExecFwk::Constants::BUNDLE_CODE_DIR) +
146 AppExecFwk::ServiceConstants::PATH_SEPARATOR + bundleName;
147 APP_LOGI("start to remove bundle dir: %{public}s", bundleDir.c_str());
148 if (InstalldClient::GetInstance()->RemoveDir(bundleDir) != ERR_OK) {
149 APP_LOGW("remove bundle dir %{public}s failed", bundleDir.c_str());
150 return ERR_APPEXECFWK_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR;
151 }
152 if (!isKeepData) {
153 InstalldClient::GetInstance()->RemoveBundleDataDir(bundleName, 0, false);
154 }
155 return ERR_OK;
156 }
157
UnInstall(const std::string & bundleName,const std::string & moduleName)158 ErrCode AppServiceFwkInstaller::UnInstall(
159 const std::string &bundleName, const std::string &moduleName)
160 {
161 if (bundleName.empty() || moduleName.empty()) {
162 APP_LOGE("bundleName or moduleName is empty, param error");
163 return ERR_APPEXECFWK_UNINSTALL_PARAM_ERROR;
164 }
165 APP_LOGI("bundle %{public}s module %{public}s need to be unstalled", bundleName.c_str(), moduleName.c_str());
166 if (BeforeUninstall(bundleName) != ERR_OK) {
167 APP_LOGE("check bundleType failed");
168 return ERR_APPEXECFWK_UNINSTALL_PARAM_ERROR;
169 }
170 InnerBundleInfo info;
171 if (!dataMgr_->GetInnerBundleInfoWithDisable(bundleName, info)) {
172 APP_LOGE("get bundle info for %{public}s failed", bundleName.c_str());
173 return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
174 }
175 if (CheckNeedUninstallBundle(moduleName, info)) {
176 APP_LOGI("need uninstall bundle %{public}s", bundleName.c_str());
177 return UnInstall(bundleName);
178 }
179 ScopeGuard enableGuard([&] { dataMgr_->EnableBundle(bundleName); });
180 std::vector<std::string> installedModules;
181 info.GetModuleNames(installedModules);
182 if (std::find(installedModules.begin(), installedModules.end(), moduleName) == installedModules.end()) {
183 APP_LOGE("Error: module %{public}s is not found in installedModules", moduleName.c_str());
184 return ERR_BUNDLE_MANAGER_MODULE_NOT_EXIST;
185 }
186
187 if (installedModules.size() == 1) {
188 APP_LOGE("can not uninstall only one module");
189 return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
190 }
191 if (!dataMgr_->UpdateBundleInstallState(bundleName, InstallState::UNINSTALL_START)) {
192 APP_LOGE("uninstall already start");
193 return ERR_APPEXECFWK_UPDATE_BUNDLE_INSTALL_STATUS_ERROR;
194 }
195 ScopeGuard stateGuard([&] { dataMgr_->UpdateBundleInstallState(bundleName, InstallState::INSTALL_SUCCESS); });
196 auto result = UnInstall(bundleName, moduleName, info);
197 if (result != ERR_OK) {
198 APP_LOGE("uninstall failed, module %{public}s bundle %{public}s", moduleName.c_str(), bundleName.c_str());
199 return result;
200 }
201 APP_LOGI("uninstall -n %{public}s -m %{public}s success", bundleName.c_str(), moduleName.c_str());
202 return ERR_OK;
203 }
204
ResetProperties()205 void AppServiceFwkInstaller::ResetProperties()
206 {
207 bundleMsg_ = "";
208 uninstallModuleVec_.clear();
209 versionUpgrade_ = false;
210 moduleUpdate_ = false;
211 deleteBundlePath_.clear();
212 versionCode_ = 0;
213 newInnerBundleInfo_ = InnerBundleInfo();
214 isEnterpriseBundle_ = false;
215 appIdentifier_ = "";
216 compileSdkType_ = "";
217 cpuAbi_ = "";
218 nativeLibraryPath_ = "";
219 }
220
CheckNeedUninstallBundle(const std::string & moduleName,const InnerBundleInfo & info)221 bool AppServiceFwkInstaller::CheckNeedUninstallBundle(const std::string &moduleName, const InnerBundleInfo &info)
222 {
223 for (const auto &item : info.GetInnerModuleInfos()) {
224 if (item.second.distro.moduleType == "shared" && item.second.moduleName != moduleName) {
225 return false;
226 }
227 }
228 return true;
229 }
230
UnInstall(const std::string & bundleName,const std::string & moduleName,InnerBundleInfo & oldInfo)231 ErrCode AppServiceFwkInstaller::UnInstall(
232 const std::string &bundleName, const std::string &moduleName, InnerBundleInfo &oldInfo)
233 {
234 // remove info & remove dir under el1
235 APP_LOGI("start to remove module info of %{public}s in %{public}s ", moduleName.c_str(), bundleName.c_str());
236 if (!dataMgr_->RemoveModuleInfo(bundleName, moduleName, oldInfo)) {
237 APP_LOGE("RemoveModuleInfo failed");
238 return ERR_APPEXECFWK_RMV_MODULE_ERROR;
239 }
240 RemoveModuleDataDir(bundleName, moduleName, oldInfo);
241 return ERR_OK;
242 }
243
RemoveModuleDataDir(const std::string & bundleName,const std::string & moduleName,const InnerBundleInfo & oldInfo)244 void AppServiceFwkInstaller::RemoveModuleDataDir(
245 const std::string &bundleName, const std::string &moduleName, const InnerBundleInfo &oldInfo)
246 {
247 APP_LOGI("start to remove module info of %{public}s in %{public}s ", moduleName.c_str(), bundleName.c_str());
248 std::string moduleDir =
249 std::string(AppExecFwk::Constants::BUNDLE_CODE_DIR) +
250 AppExecFwk::ServiceConstants::PATH_SEPARATOR + bundleName +
251 AppExecFwk::ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(oldInfo.GetVersionCode()) +
252 AppExecFwk::ServiceConstants::PATH_SEPARATOR + moduleName;
253 APP_LOGI("start to remove module dir: %{public}s", moduleDir.c_str());
254 if (InstalldClient::GetInstance()->RemoveDir(moduleDir) != ERR_OK) {
255 APP_LOGW("remove module dir %{public}s failed", moduleDir.c_str());
256 }
257 }
258
BeforeInstall(const std::vector<std::string> & hspPaths,InstallParam & installParam)259 ErrCode AppServiceFwkInstaller::BeforeInstall(
260 const std::vector<std::string> &hspPaths, InstallParam &installParam)
261 {
262 if (hspPaths.empty()) {
263 APP_LOGE("HspPaths is empty");
264 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
265 }
266
267 dataMgr_ = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
268 if (dataMgr_ == nullptr) {
269 APP_LOGE("DataMgr is nullptr");
270 return ERR_APPEXECFWK_NULL_PTR;
271 }
272
273 return ERR_OK;
274 }
275
BeforeUninstall(const std::string & bundleName)276 ErrCode AppServiceFwkInstaller::BeforeUninstall(const std::string &bundleName)
277 {
278 if (bundleName.empty()) {
279 APP_LOGE("bundleName is empty");
280 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
281 }
282
283 dataMgr_ = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
284 if (dataMgr_ == nullptr) {
285 APP_LOGE("DataMgr is nullptr");
286 return ERR_APPEXECFWK_NULL_PTR;
287 }
288
289 BundleType type;
290 if (!dataMgr_->GetBundleType(bundleName, type)) {
291 APP_LOGE("get bundle type for %{public}s failed", bundleName.c_str());
292 return ERR_APPEXECFWK_UNINSTALL_PARAM_ERROR;
293 }
294 return type == BundleType::APP_SERVICE_FWK ? ERR_OK : ERR_APPEXECFWK_UNINSTALL_PARAM_ERROR;
295 }
296
ProcessInstall(const std::vector<std::string> & hspPaths,InstallParam & installParam)297 ErrCode AppServiceFwkInstaller::ProcessInstall(
298 const std::vector<std::string> &hspPaths, InstallParam &installParam)
299 {
300 std::unordered_map<std::string, InnerBundleInfo> newInfos;
301 ErrCode result = CheckAndParseFiles(hspPaths, installParam, newInfos);
302 CHECK_RESULT(result, "CheckAndParseFiles failed %{public}d");
303
304 InnerBundleInfo oldInfo;
305 bool isDowngrade = false;
306 if (!CheckNeedInstall(newInfos, oldInfo, isDowngrade)) {
307 if (isDowngrade) {
308 APP_LOGE("version down grade install");
309 return ERR_APPEXECFWK_INSTALL_VERSION_DOWNGRADE;
310 }
311 APP_LOGI_NOFUNC("fwk not need install");
312 return ERR_OK;
313 }
314
315 ScopeGuard stateGuard([&] {
316 dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_SUCCESS);
317 dataMgr_->EnableBundle(bundleName_);
318 });
319
320 if (versionUpgrade_ || moduleUpdate_) {
321 result = UpdateAppService(oldInfo, newInfos, installParam);
322 CHECK_RESULT(result, "UpdateAppService failed %{public}d");
323 } else {
324 result = InnerProcessInstall(newInfos, installParam);
325 if (result != ERR_OK) {
326 APP_LOGE("InnerProcessInstall failed %{public}d", result);
327 RollBack();
328 return result;
329 }
330 }
331 SavePreInstallBundleInfo(result, newInfos, installParam);
332 PatchDataMgr::GetInstance().ProcessPatchInfo(bundleName_, hspPaths,
333 newInfos.begin()->second.GetVersionCode(), AppPatchType::SERVICE_FWK, installParam.isPatch);
334 // check mark install finish
335 result = MarkInstallFinish();
336 if (result != ERR_OK) {
337 APP_LOGE("mark install finish failed %{public}d", result);
338 if (!versionUpgrade_ && !moduleUpdate_) {
339 RollBack();
340 }
341 PatchDataMgr::GetInstance().DeleteInnerPatchInfo(bundleName_);
342 return result;
343 }
344 return result;
345 }
346
SavePreInstallBundleInfo(ErrCode installResult,const std::unordered_map<std::string,InnerBundleInfo> & newInfos,const InstallParam & installParam)347 void AppServiceFwkInstaller::SavePreInstallBundleInfo(ErrCode installResult,
348 const std::unordered_map<std::string, InnerBundleInfo> &newInfos, const InstallParam &installParam)
349 {
350 if (installResult != ERR_OK) {
351 APP_LOGW("install bundle %{public}s failed for %{public}d", bundleName_.c_str(), installResult);
352 return;
353 }
354 if (!installParam.needSavePreInstallInfo) {
355 APP_LOGI("no need to save pre info");
356 return;
357 }
358 PreInstallBundleInfo preInstallBundleInfo;
359 preInstallBundleInfo.SetBundleName(bundleName_);
360 dataMgr_->GetPreInstallBundleInfo(bundleName_, preInstallBundleInfo);
361 preInstallBundleInfo.SetAppType(Constants::AppType::SYSTEM_APP);
362 preInstallBundleInfo.SetVersionCode(versionCode_);
363 preInstallBundleInfo.SetIsUninstalled(false);
364 for (const std::string &bundlePath : deleteBundlePath_) {
365 APP_LOGI_NOFUNC("preInstallBundleInfo delete path %{public}s", bundlePath.c_str());
366 preInstallBundleInfo.DeleteBundlePath(bundlePath);
367 }
368 for (const auto &item : newInfos) {
369 preInstallBundleInfo.AddBundlePath(item.first);
370 }
371 preInstallBundleInfo.SetRemovable(false);
372
373 for (const auto &innerBundleInfo : newInfos) {
374 auto applicationInfo = innerBundleInfo.second.GetBaseApplicationInfo();
375 innerBundleInfo.second.AdaptMainLauncherResourceInfo(applicationInfo);
376 preInstallBundleInfo.SetLabelId(applicationInfo.labelResource.id);
377 preInstallBundleInfo.SetIconId(applicationInfo.iconResource.id);
378 preInstallBundleInfo.SetModuleName(applicationInfo.labelResource.moduleName);
379 preInstallBundleInfo.SetSystemApp(applicationInfo.isSystemApp);
380 preInstallBundleInfo.SetBundleType(BundleType::APP_SERVICE_FWK);
381 auto innerModuleInfos = innerBundleInfo.second.GetInnerModuleInfos();
382 if (!innerModuleInfos.empty() &&
383 innerModuleInfos.begin()->second.distro.moduleType == Profile::MODULE_TYPE_ENTRY) {
384 break;
385 }
386 }
387 if (!dataMgr_->SavePreInstallBundleInfo(bundleName_, preInstallBundleInfo)) {
388 APP_LOGE("SavePreInstallBundleInfo for bundleName_ failed");
389 }
390 }
391
CheckAndParseFiles(const std::vector<std::string> & hspPaths,InstallParam & installParam,std::unordered_map<std::string,InnerBundleInfo> & newInfos)392 ErrCode AppServiceFwkInstaller::CheckAndParseFiles(
393 const std::vector<std::string> &hspPaths, InstallParam &installParam,
394 std::unordered_map<std::string, InnerBundleInfo> &newInfos)
395 {
396 InstallCheckParam checkParam;
397 BuildCheckParam(installParam, checkParam);
398
399 std::vector<std::string> checkedHspPaths;
400 // check hsp paths
401 ErrCode result = BundleUtil::CheckFilePath(hspPaths, checkedHspPaths);
402 CHECK_RESULT(result, "Hsp file check failed %{public}d");
403
404 // check file type
405 result = CheckFileType(checkedHspPaths);
406 CHECK_RESULT(result, "Hsp suffix check failed %{public}d");
407
408 // check syscap
409 result = bundleInstallChecker_->CheckSysCap(checkedHspPaths);
410 bool isSysCapValid = (result == ERR_OK);
411 if (!isSysCapValid) {
412 APP_LOGI("Hsp syscap check failed %{public}d", result);
413 }
414
415 // verify signature info for all haps
416 std::vector<Security::Verify::HapVerifyResult> hapVerifyResults;
417 result = bundleInstallChecker_->CheckMultipleHapsSignInfo(
418 checkedHspPaths, hapVerifyResults);
419 CHECK_RESULT(result, "Hsp files check signature info failed %{public}d");
420
421 result = bundleInstallChecker_->ParseHapFiles(
422 checkedHspPaths, checkParam, hapVerifyResults, newInfos);
423 CHECK_RESULT(result, "Parse hsps file failed %{public}d");
424
425 // check u1Enable
426 result = bundleInstallChecker_->CheckNoU1Enable(newInfos);
427 CHECK_RESULT(result, "Check u1enable failed %{public}d");
428
429 // check install permission
430 result = bundleInstallChecker_->CheckInstallPermission(checkParam, hapVerifyResults);
431 CHECK_RESULT(result, "Check install permission failed %{public}d");
432
433 // check hsp install condition
434 result = bundleInstallChecker_->CheckHspInstallCondition(hapVerifyResults);
435 CHECK_RESULT(result, "Check hsp install condition failed %{public}d");
436
437 // check device type
438 if (!isSysCapValid) {
439 result = bundleInstallChecker_->CheckDeviceType(newInfos);
440 if (result != ERR_OK) {
441 APP_LOGE("Check device type failed : %{public}d", result);
442 return ERR_APPEXECFWK_INSTALL_SYSCAP_FAILED_AND_DEVICE_TYPE_ERROR;
443 }
444 }
445
446 result = CheckAppLabelInfo(newInfos);
447 CHECK_RESULT(result, "Check app label failed %{public}d");
448
449 // delivery sign profile to code signature
450 result = DeliveryProfileToCodeSign(hapVerifyResults);
451 CHECK_RESULT(result, "delivery sign profile failed %{public}d");
452
453 // check native file
454 result = bundleInstallChecker_->CheckMultiNativeFile(newInfos);
455 CHECK_RESULT(result, "Native so is incompatible in all hsps %{public}d");
456
457 isEnterpriseBundle_ = bundleInstallChecker_->CheckEnterpriseBundle(hapVerifyResults[0]);
458 appIdentifier_ = (hapVerifyResults[0].GetProvisionInfo().type == Security::Verify::ProvisionType::DEBUG) ?
459 DEBUG_APP_IDENTIFIER : hapVerifyResults[0].GetProvisionInfo().bundleInfo.appIdentifier;
460 compileSdkType_ = newInfos.empty() ? COMPILE_SDK_TYPE_OPEN_HARMONY :
461 (newInfos.begin()->second).GetBaseApplicationInfo().compileSdkType;
462
463 GenerateOdid(newInfos, hapVerifyResults);
464 AddAppProvisionInfo(bundleName_, hapVerifyResults[0].GetProvisionInfo(), installParam);
465 return result;
466 }
467
GenerateOdid(std::unordered_map<std::string,InnerBundleInfo> & infos,const std::vector<Security::Verify::HapVerifyResult> & hapVerifyRes) const468 void AppServiceFwkInstaller::GenerateOdid(
469 std::unordered_map<std::string, InnerBundleInfo> &infos,
470 const std::vector<Security::Verify::HapVerifyResult> &hapVerifyRes) const
471 {
472 if (hapVerifyRes.size() < infos.size() || infos.empty()) {
473 APP_LOGE("hapVerifyRes size less than infos size or infos is empty");
474 return;
475 }
476
477 std::string developerId = hapVerifyRes[0].GetProvisionInfo().bundleInfo.developerId;
478 if (developerId.empty()) {
479 developerId = hapVerifyRes[0].GetProvisionInfo().bundleInfo.bundleName;
480 }
481 std::string odid;
482 dataMgr_->GenerateOdid(developerId, odid);
483
484 for (auto &item : infos) {
485 item.second.UpdateOdid(developerId, odid);
486 }
487 }
488
CheckFileType(const std::vector<std::string> & bundlePaths)489 ErrCode AppServiceFwkInstaller::CheckFileType(const std::vector<std::string> &bundlePaths)
490 {
491 if (bundlePaths.empty()) {
492 APP_LOGE("check hsp suffix failed due to empty bundlePaths");
493 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
494 }
495
496 for (const auto &bundlePath : bundlePaths) {
497 if (!BundleUtil::CheckFileType(bundlePath, ServiceConstants::HSP_FILE_SUFFIX)) {
498 APP_LOGE("Hsp %{public}s suffix check failed", bundlePath.c_str());
499 return ERR_APPEXECFWK_INSTALL_INVALID_HAP_NAME;
500 }
501 }
502
503 return ERR_OK;
504 }
505
CheckAppLabelInfo(const std::unordered_map<std::string,InnerBundleInfo> & infos)506 ErrCode AppServiceFwkInstaller::CheckAppLabelInfo(
507 const std::unordered_map<std::string, InnerBundleInfo> &infos)
508 {
509 for (const auto &info : infos) {
510 if (info.second.GetApplicationBundleType() != BundleType::APP_SERVICE_FWK) {
511 APP_LOGE("App BundleType is not AppService");
512 return ERR_APP_SERVICE_FWK_INSTALL_TYPE_FAILED;
513 }
514
515 auto moduleInfo = info.second.GetInnerModuleInfoByModuleName(info.second.GetCurModuleName());
516 if (moduleInfo && moduleInfo->bundleType != BundleType::SHARED) {
517 APP_LOGE("Module BundleType is not Shared");
518 return ERR_APP_SERVICE_FWK_INSTALL_TYPE_FAILED;
519 }
520 }
521
522 ErrCode ret = bundleInstallChecker_->CheckAppLabelInfo(infos);
523 if (ret != ERR_OK) {
524 APP_LOGE("CheckAppLabelInfo failed, ret %{public}d", ret);
525 return ret;
526 }
527
528 bundleName_ = (infos.begin()->second).GetBundleName();
529 versionCode_ = (infos.begin()->second).GetVersionCode();
530 return ERR_OK;
531 }
532
AddAppProvisionInfo(const std::string & bundleName,const Security::Verify::ProvisionInfo & provisionInfo,const InstallParam & installParam) const533 void AppServiceFwkInstaller::AddAppProvisionInfo(
534 const std::string &bundleName,
535 const Security::Verify::ProvisionInfo &provisionInfo,
536 const InstallParam &installParam) const
537 {
538 AppProvisionInfo appProvisionInfo = bundleInstallChecker_->ConvertToAppProvisionInfo(provisionInfo);
539 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->AddAppProvisionInfo(
540 bundleName, appProvisionInfo)) {
541 APP_LOGW("BundleName %{public}s add appProvisionInfo failed", bundleName.c_str());
542 }
543
544 if (!installParam.specifiedDistributionType.empty()) {
545 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetSpecifiedDistributionType(
546 bundleName, installParam.specifiedDistributionType)) {
547 APP_LOGW("BundleName %{public}s SetSpecifiedDistributionType failed", bundleName.c_str());
548 }
549 }
550
551 if (!installParam.additionalInfo.empty()) {
552 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetAdditionalInfo(
553 bundleName, installParam.additionalInfo)) {
554 APP_LOGW("BundleName %{public}s SetAdditionalInfo failed", bundleName.c_str());
555 }
556 }
557 }
558
InnerProcessInstall(std::unordered_map<std::string,InnerBundleInfo> & newInfos,InstallParam & installParam)559 ErrCode AppServiceFwkInstaller::InnerProcessInstall(
560 std::unordered_map<std::string, InnerBundleInfo> &newInfos,
561 InstallParam &installParam)
562 {
563 APP_LOGI("start -n %{public}s, size: %{public}zu",
564 bundleName_.c_str(), newInfos.size());
565 ErrCode result = ERR_OK;
566 for (auto it = newInfos.begin(); it != newInfos.end(); ++it) {
567 InnerBundleInfo &newInfo = it->second;
568 APP_LOGD("InnerProcessInstall module %{public}s",
569 newInfo.GetCurrentModulePackage().c_str());
570 result = ExtractModule(newInfo, it->first, installParam.copyHapToInstallPath);
571 if (result != ERR_OK) {
572 return result;
573 }
574 newInfo.SetApplicationFlags(installParam.preinstallSourceFlag);
575 MergeBundleInfos(newInfo);
576 }
577
578 return SaveBundleInfoToStorage();
579 }
580
ExtractModule(InnerBundleInfo & newInfo,const std::string & bundlePath,bool copyHapToInstallPath)581 ErrCode AppServiceFwkInstaller::ExtractModule(
582 InnerBundleInfo &newInfo, const std::string &bundlePath, bool copyHapToInstallPath)
583 {
584 APP_LOGI_NOFUNC("begin ExtractModule with %{public}s bundlePath %{public}s",
585 newInfo.GetCurrentModulePackage().c_str(), bundlePath.c_str());
586 ErrCode result = ERR_OK;
587 std::string bundleDir =
588 std::string(AppExecFwk::Constants::BUNDLE_CODE_DIR) +
589 AppExecFwk::ServiceConstants::PATH_SEPARATOR + bundleName_;
590 result = MkdirIfNotExist(bundleDir);
591 CHECK_RESULT(result, "Check bundle dir failed %{public}d");
592
593 newInfo.SetAppCodePath(bundleDir);
594 uint32_t versionCode = newInfo.GetVersionCode();
595 std::string versionDir = bundleDir
596 + AppExecFwk::ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(versionCode);
597 result = MkdirIfNotExist(versionDir);
598 CHECK_RESULT(result, "Check version dir failed %{public}d");
599
600 auto &moduleName = newInfo.GetInnerModuleInfos().begin()->second.moduleName;
601 std::string moduleDir = versionDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR + moduleName;
602 result = MkdirIfNotExist(moduleDir);
603 CHECK_RESULT(result, "Check module dir failed %{public}d");
604
605 result = ProcessNativeLibrary(bundlePath, moduleDir, moduleName, versionDir, newInfo, copyHapToInstallPath);
606 CHECK_RESULT(result, "ProcessNativeLibrary failed %{public}d");
607
608 // preInstallHsp does not need to copy
609 newInfo.SetModuleHapPath(bundlePath);
610 newInfo.AddModuleSrcDir(moduleDir);
611 newInfo.AddModuleResPath(moduleDir);
612
613 if (copyHapToInstallPath) {
614 std::string realHspPath = moduleDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR +
615 moduleName + ServiceConstants::HSP_FILE_SUFFIX;
616 result = InstalldClient::GetInstance()->CopyFile(bundlePath, realHspPath);
617 newInfo.SetModuleHapPath(realHspPath);
618 CHECK_RESULT(result, "move hsp to install dir failed %{public}d");
619
620 std::string realSoPath = versionDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR +
621 nativeLibraryPath_;
622 result = VerifyCodeSignatureForHsp(realHspPath, realSoPath);
623 CHECK_RESULT(result, "verify code sign failed %{public}d");
624 }
625 return ERR_OK;
626 }
627
VerifyCodeSignatureForHsp(const std::string & realHspPath,const std::string & realSoPath) const628 ErrCode AppServiceFwkInstaller::VerifyCodeSignatureForHsp(
629 const std::string &realHspPath, const std::string &realSoPath) const
630 {
631 APP_LOGI("begin to verify code sign for hsp");
632 CodeSignatureParam codeSignatureParam;
633 codeSignatureParam.modulePath = realHspPath;
634 codeSignatureParam.targetSoPath = realSoPath;
635 codeSignatureParam.cpuAbi = cpuAbi_;
636 codeSignatureParam.appIdentifier = appIdentifier_;
637 codeSignatureParam.signatureFileDir = "";
638 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle_;
639 codeSignatureParam.isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
640 codeSignatureParam.isPreInstalledBundle = false;
641 codeSignatureParam.isCompressNativeLibrary = isCompressNativeLibs_;
642 return InstalldClient::GetInstance()->VerifyCodeSignatureForHap(codeSignatureParam);
643 }
644
ExtractModule(InnerBundleInfo & oldInfo,InnerBundleInfo & newInfo,const std::string & bundlePath)645 ErrCode AppServiceFwkInstaller::ExtractModule(InnerBundleInfo &oldInfo,
646 InnerBundleInfo &newInfo, const std::string &bundlePath)
647 {
648 ErrCode result = ERR_OK;
649 std::string bundleDir =
650 std::string(AppExecFwk::Constants::BUNDLE_CODE_DIR) +
651 AppExecFwk::ServiceConstants::PATH_SEPARATOR + bundleName_;
652 result = MkdirIfNotExist(bundleDir);
653 CHECK_RESULT(result, "Check bundle dir failed %{public}d");
654
655 oldInfo.SetAppCodePath(bundleDir);
656 uint32_t versionCode = newInfo.GetVersionCode();
657 std::string versionDir = bundleDir
658 + AppExecFwk::ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(versionCode);
659 result = MkdirIfNotExist(versionDir);
660 CHECK_RESULT(result, "Check version dir failed %{public}d");
661
662 auto &moduleName = newInfo.GetInnerModuleInfos().begin()->second.moduleName;
663 std::string moduleDir = versionDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR + moduleName;
664 result = MkdirIfNotExist(moduleDir);
665 CHECK_RESULT(result, "Check module dir failed %{public}d");
666
667 result = ProcessNativeLibrary(bundlePath, moduleDir, moduleName, versionDir, newInfo);
668 CHECK_RESULT(result, "ProcessNativeLibrary failed %{public}d");
669
670 // preInstallHsp does not need to copy
671 oldInfo.SetModuleHapPath(bundlePath);
672 oldInfo.AddModuleSrcDir(moduleDir);
673 oldInfo.AddModuleResPath(moduleDir);
674 return ERR_OK;
675 }
676
MkdirIfNotExist(const std::string & dir)677 ErrCode AppServiceFwkInstaller::MkdirIfNotExist(const std::string &dir)
678 {
679 bool isDirExist = false;
680 ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
681 CHECK_RESULT(result, "Check if dir exist failed %{public}d");
682
683 if (!isDirExist) {
684 result = InstalldClient::GetInstance()->CreateBundleDir(dir);
685 CHECK_RESULT(result, "Create dir failed %{public}d");
686 }
687 return result;
688 }
689
ProcessNativeLibrary(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & versionDir,InnerBundleInfo & newInfo,bool copyHapToInstallPath)690 ErrCode AppServiceFwkInstaller::ProcessNativeLibrary(
691 const std::string &bundlePath,
692 const std::string &moduleDir,
693 const std::string &moduleName,
694 const std::string &versionDir,
695 InnerBundleInfo &newInfo,
696 bool copyHapToInstallPath)
697 {
698 APP_LOGI_NOFUNC("ProcessNativeLibrary %{public}s %{public}s", bundlePath.c_str(), moduleDir.c_str());
699 if (!newInfo.FetchNativeSoAttrs(moduleName, cpuAbi_, nativeLibraryPath_)) {
700 return ERR_OK;
701 }
702 isCompressNativeLibs_ = newInfo.IsCompressNativeLibs(moduleName);
703 if (isCompressNativeLibs_) {
704 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
705 if (tempNativeLibraryPath.empty()) {
706 APP_LOGE("tempNativeLibraryPath is empty");
707 return ERR_APPEXECFWK_INSTALLD_EXTRACT_FILES_FAILED;
708 }
709
710 std::string tempSoPath =
711 versionDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
712 APP_LOGI_NOFUNC("TempSoPath %{public}s cpuAbi %{public}s", tempSoPath.c_str(), cpuAbi_.c_str());
713 auto result = InstalldClient::GetInstance()->ExtractModuleFiles(
714 bundlePath, moduleDir, tempSoPath, cpuAbi_);
715 CHECK_RESULT(result, "Extract module files failed %{public}d");
716 if (!copyHapToInstallPath) {
717 // verify hap or hsp code signature for compressed so files
718 result = VerifyCodeSignatureForNativeFiles(bundlePath, cpuAbi_, tempSoPath);
719 CHECK_RESULT(result, "fail to VerifyCodeSignature, error is %{public}d");
720 }
721 // move so to real path
722 result = MoveSoToRealPath(moduleName, versionDir, nativeLibraryPath_);
723 CHECK_RESULT(result, "Move so to real path failed %{public}d");
724 } else {
725 std::vector<std::string> fileNames;
726 auto result = InstalldClient::GetInstance()->GetNativeLibraryFileNames(
727 bundlePath, cpuAbi_, fileNames);
728 CHECK_RESULT(result, "Fail to GetNativeLibraryFileNames, error is %{public}d");
729 newInfo.SetNativeLibraryFileNames(moduleName, fileNames);
730 }
731 return ERR_OK;
732 }
733
MergeBundleInfos(InnerBundleInfo & info)734 void AppServiceFwkInstaller::MergeBundleInfos(InnerBundleInfo &info)
735 {
736 if (newInnerBundleInfo_.GetBundleName().empty()) {
737 newInnerBundleInfo_ = info;
738 return;
739 }
740
741 newInnerBundleInfo_.AddModuleInfo(info);
742 }
743
SaveBundleInfoToStorage()744 ErrCode AppServiceFwkInstaller::SaveBundleInfoToStorage()
745 {
746 newInnerBundleInfo_.SetInstallMark(bundleName_, newInnerBundleInfo_.GetCurModuleName(),
747 InstallExceptionStatus::INSTALL_START);
748 if (!dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_START)) {
749 APP_LOGE("UpdateBundleInstallState failed");
750 return ERR_APPEXECFWK_INSTALL_STATE_ERROR;
751 }
752
753 if (!dataMgr_->AddInnerBundleInfo(bundleName_, newInnerBundleInfo_)) {
754 dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::UNINSTALL_START);
755 dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::UNINSTALL_SUCCESS);
756 APP_LOGE("Save bundle failed %{public}s", bundleName_.c_str());
757 return ERR_APPEXECFWK_ADD_BUNDLE_ERROR;
758 }
759
760 return ERR_OK;
761 }
762
MoveSoToRealPath(const std::string & moduleName,const std::string & versionDir,const std::string & nativeLibraryPath)763 ErrCode AppServiceFwkInstaller::MoveSoToRealPath(
764 const std::string &moduleName, const std::string &versionDir,
765 const std::string &nativeLibraryPath)
766 {
767 // 1. move so files to real installation dir
768 std::string realSoPath = versionDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR
769 + nativeLibraryPath + AppExecFwk::ServiceConstants::PATH_SEPARATOR;
770 ErrCode result = MkdirIfNotExist(realSoPath);
771 CHECK_RESULT(result, "Check module dir failed %{public}d");
772 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath);
773 if (tempNativeLibraryPath.empty()) {
774 APP_LOGI("No so libs existed");
775 return ERR_OK;
776 }
777
778 std::string tempSoPath =
779 versionDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
780 APP_LOGD("Move so files from path %{public}s to path %{public}s",
781 tempSoPath.c_str(), realSoPath.c_str());
782 bool isDirExist = false;
783 result = InstalldClient::GetInstance()->IsExistDir(tempSoPath, isDirExist);
784 CHECK_RESULT(result, "Check temp so dir failed %{public}d");
785 if (!isDirExist) {
786 APP_LOGI("temp so dir not exist");
787 return ERR_OK;
788 }
789 result = InstalldClient::GetInstance()->MoveFiles(tempSoPath, realSoPath);
790 if (result != ERR_OK) {
791 APP_LOGE("Move to real path failed %{public}d", result);
792 return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
793 }
794
795 // 2. remove so temp dir
796 std::string deleteTempDir = versionDir + AppExecFwk::ServiceConstants::PATH_SEPARATOR
797 + moduleName + AppExecFwk::ServiceConstants::TMP_SUFFIX;
798 result = InstalldClient::GetInstance()->RemoveDir(deleteTempDir);
799 if (result != ERR_OK) {
800 APP_LOGW("Remove temp dir %{public}s failed %{public}d",
801 deleteTempDir.c_str(), result);
802 }
803 return ERR_OK;
804 }
805
RollBack()806 void AppServiceFwkInstaller::RollBack()
807 {
808 APP_LOGI("RollBack: %{public}s", bundleName_.c_str());
809 if (newInnerBundleInfo_.IsPreInstallApp() && !BundleUtil::CheckSystemFreeSize(APP_INSTALL_PATH, FIVE_MB)) {
810 APP_LOGW("pre bundle: %{public}s no rollback due to no space", bundleName_.c_str());
811 return;
812 }
813
814 // RemoveCache
815 RemoveInfo(bundleName_);
816 }
817
UpdateAppService(InnerBundleInfo & oldInfo,std::unordered_map<std::string,InnerBundleInfo> & newInfos,InstallParam & installParam)818 ErrCode AppServiceFwkInstaller::UpdateAppService(
819 InnerBundleInfo &oldInfo,
820 std::unordered_map<std::string, InnerBundleInfo> &newInfos,
821 InstallParam &installParam)
822 {
823 APP_LOGI_NOFUNC("UpdateAppService for bundle %{public}s", oldInfo.GetBundleName().c_str());
824 auto oldVersionCode = oldInfo.GetVersionCode();
825 // update
826 ErrCode result = ERR_OK;
827 for (auto &item : newInfos) {
828 if ((result = ProcessBundleUpdateStatus(oldInfo, item.second, item.first, installParam)) != ERR_OK) {
829 APP_LOGE("ProcessBundleUpdateStatus failed %{public}d", result);
830 return result;
831 }
832 }
833 if (!uninstallModuleVec_.empty()) {
834 result = UninstallLowerVersion(uninstallModuleVec_);
835 if (result != ERR_OK) {
836 APP_LOGE("UninstallLowerVersion failed %{public}d", result);
837 return result;
838 }
839 }
840 if (oldVersionCode < versionCode_) {
841 RemoveLowerVersionSoDir(oldVersionCode);
842 }
843
844 return ERR_OK;
845 }
846
ProcessBundleUpdateStatus(InnerBundleInfo & oldInfo,InnerBundleInfo & newInfo,const std::string & hspPath,const InstallParam & installParam)847 ErrCode AppServiceFwkInstaller::ProcessBundleUpdateStatus(InnerBundleInfo &oldInfo,
848 InnerBundleInfo &newInfo, const std::string &hspPath, const InstallParam &installParam)
849 {
850 std::string moduleName = newInfo.GetCurrentModulePackage();
851 APP_LOGI_NOFUNC("ProcessBundleUpdateStatus for module %{public}s", moduleName.c_str());
852 if (moduleName.empty()) {
853 APP_LOGE("get current package failed");
854 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
855 }
856 if (versionUpgrade_) {
857 APP_LOGI_NOFUNC("uninstallModuleVec_ insert module %{public}s", moduleName.c_str());
858 uninstallModuleVec_.emplace_back(moduleName);
859 }
860 if (!dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::UPDATING_START)) {
861 APP_LOGE("update already start");
862 return ERR_APPEXECFWK_INSTALL_STATE_ERROR;
863 }
864 // 1. bundle exist, module exist, update module
865 // 2. bundle exist, install new hsp
866 bool isModuleExist = oldInfo.FindModule(moduleName);
867 APP_LOGI("module %{public}s isModuleExist %{public}d", moduleName.c_str(), isModuleExist);
868
869 auto result = isModuleExist ? ProcessModuleUpdate(newInfo, oldInfo, hspPath, installParam) :
870 ProcessNewModuleInstall(newInfo, oldInfo, hspPath, installParam);
871 if (result != ERR_OK) {
872 APP_LOGE("install module failed %{public}d", result);
873 return result;
874 }
875 return ERR_OK;
876 }
877
ProcessModuleUpdate(InnerBundleInfo & newInfo,InnerBundleInfo & oldInfo,const std::string & hspPath,const InstallParam & installParam)878 ErrCode AppServiceFwkInstaller::ProcessModuleUpdate(InnerBundleInfo &newInfo,
879 InnerBundleInfo &oldInfo, const std::string &hspPath, const InstallParam &installParam)
880 {
881 std::string moduleName = newInfo.GetCurrentModulePackage();
882 APP_LOGD("ProcessModuleUpdate, bundleName : %{public}s, moduleName : %{public}s",
883 newInfo.GetBundleName().c_str(), moduleName.c_str());
884 if (oldInfo.GetModuleTypeByPackage(moduleName) != SHARED_MODULE_TYPE) {
885 APP_LOGE("moduleName is inconsistent in the updating hap");
886 return ERR_APPEXECFWK_INSTALL_INCONSISTENT_MODULE_NAME;
887 }
888 oldInfo.SetInstallMark(bundleName_, moduleName, InstallExceptionStatus::UPDATING_EXISTED_START);
889
890 std::string oldHspPath = oldInfo.GetModuleHapPath(moduleName);
891 if (!oldHspPath.empty()) {
892 APP_LOGI_NOFUNC("deleteBundlePath_ insert path %{public}s", oldHspPath.c_str());
893 deleteBundlePath_.emplace_back(oldHspPath);
894 }
895
896 auto result = ExtractModule(newInfo, hspPath, installParam.copyHapToInstallPath);
897 CHECK_RESULT(result, "ExtractModule failed %{public}d");
898
899 if (!dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::UPDATING_SUCCESS)) {
900 APP_LOGE("old module update state failed");
901 return ERR_APPEXECFWK_UPDATE_BUNDLE_INSTALL_STATUS_ERROR;
902 }
903
904 oldInfo.SetBundleUpdateTime(BundleUtil::GetCurrentTimeMs(), Constants::DEFAULT_USERID);
905 if (!dataMgr_->UpdateInnerBundleInfo(bundleName_, newInfo, oldInfo)) {
906 APP_LOGE("update innerBundleInfo %{public}s failed", bundleName_.c_str());
907 return ERR_APPEXECFWK_INSTALL_BUNDLE_MGR_SERVICE_ERROR;
908 }
909 return ERR_OK;
910 }
911
ProcessNewModuleInstall(InnerBundleInfo & newInfo,InnerBundleInfo & oldInfo,const std::string & hspPath,const InstallParam & installParam)912 ErrCode AppServiceFwkInstaller::ProcessNewModuleInstall(InnerBundleInfo &newInfo,
913 InnerBundleInfo &oldInfo, const std::string &hspPath, const InstallParam &installParam)
914 {
915 std::string moduleName = newInfo.GetCurrentModulePackage();
916 APP_LOGD("ProcessNewModuleInstall, bundleName : %{public}s, moduleName : %{public}s",
917 newInfo.GetBundleName().c_str(), moduleName.c_str());
918 if (bundleInstallChecker_->IsContainModuleName(newInfo, oldInfo)) {
919 APP_LOGE("moduleName is already existed");
920 return ERR_APPEXECFWK_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME;
921 }
922
923 oldInfo.SetInstallMark(bundleName_, moduleName, InstallExceptionStatus::UPDATING_NEW_START);
924
925 auto result = ExtractModule(newInfo, hspPath, installParam.copyHapToInstallPath);
926 if (result != ERR_OK) {
927 APP_LOGE("extract module and rename failed");
928 return result;
929 }
930
931 if (!dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::UPDATING_SUCCESS)) {
932 APP_LOGE("new moduleupdate state failed");
933 return ERR_APPEXECFWK_UPDATE_BUNDLE_INSTALL_STATUS_ERROR;
934 }
935
936 oldInfo.SetBundleUpdateTime(BundleUtil::GetCurrentTimeMs(), Constants::DEFAULT_USERID);
937 if (!dataMgr_->AddNewModuleInfo(bundleName_, newInfo, oldInfo)) {
938 APP_LOGE(
939 "add module %{public}s to %{public}s failed", moduleName.c_str(), bundleName_.c_str());
940 return ERR_APPEXECFWK_ADD_MODULE_ERROR;
941 }
942 return ERR_OK;
943 }
944
UninstallLowerVersion(const std::vector<std::string> & moduleNameList)945 ErrCode AppServiceFwkInstaller::UninstallLowerVersion(const std::vector<std::string> &moduleNameList)
946 {
947 APP_LOGI_NOFUNC("start to uninstall lower version module");
948 InnerBundleInfo info;
949 bool isExist = false;
950 if (!GetInnerBundleInfoWithDisable(info, isExist) || !isExist) {
951 return ERR_APPEXECFWK_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR;
952 }
953
954 if (!dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::UNINSTALL_START)) {
955 APP_LOGE("uninstall already start");
956 return ERR_APPEXECFWK_UPDATE_BUNDLE_INSTALL_STATUS_ERROR;
957 }
958
959 std::vector<std::string> moduleVec = info.GetModuleNameVec();
960 InnerBundleInfo oldInfo = info;
961 for (const auto &package : moduleVec) {
962 if (find(moduleNameList.begin(), moduleNameList.end(), package) == moduleNameList.end()) {
963 APP_LOGI("uninstall package %{public}s", package.c_str());
964 if (!dataMgr_->RemoveModuleInfo(bundleName_, package, info)) {
965 APP_LOGE("RemoveModuleInfo failed");
966 return ERR_APPEXECFWK_RMV_MODULE_ERROR;
967 }
968 }
969 }
970
971 if (!dataMgr_->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_SUCCESS)) {
972 APP_LOGE("uninstall already start");
973 return ERR_APPEXECFWK_UPDATE_BUNDLE_INSTALL_STATUS_ERROR;
974 }
975 return ERR_OK;
976 }
977
GetInnerBundleInfoWithDisable(InnerBundleInfo & info,bool & isAppExist)978 bool AppServiceFwkInstaller::GetInnerBundleInfoWithDisable(InnerBundleInfo &info, bool &isAppExist)
979 {
980 if (dataMgr_ == nullptr) {
981 dataMgr_ = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
982 if (dataMgr_ == nullptr) {
983 APP_LOGE("Get dataMgr shared_ptr nullptr");
984 return false;
985 }
986 }
987 isAppExist = dataMgr_->GetInnerBundleInfoWithDisable(bundleName_, info);
988 return true;
989 }
990
RemoveInfo(const std::string & bundleName)991 void AppServiceFwkInstaller::RemoveInfo(const std::string &bundleName)
992 {
993 if (!dataMgr_->UpdateBundleInstallState(bundleName, InstallState::UNINSTALL_SUCCESS)) {
994 APP_LOGE("Delete inner info failed");
995 }
996 }
997
SendBundleSystemEvent(const std::vector<std::string> & hspPaths,BundleEventType bundleEventType,const InstallParam & installParam,InstallScene preBundleScene,ErrCode errCode)998 void AppServiceFwkInstaller::SendBundleSystemEvent(
999 const std::vector<std::string> &hspPaths, BundleEventType bundleEventType,
1000 const InstallParam &installParam, InstallScene preBundleScene, ErrCode errCode)
1001 {
1002 EventInfo sysEventInfo;
1003 sysEventInfo.bundleName = bundleName_;
1004 sysEventInfo.isPreInstallApp = installParam.isPreInstallApp;
1005 sysEventInfo.errCode = errCode;
1006 sysEventInfo.userId = Constants::ALL_USERID;
1007 sysEventInfo.versionCode = versionCode_;
1008 sysEventInfo.preBundleScene = preBundleScene;
1009 sysEventInfo.filePath = hspPaths;
1010 sysEventInfo.callingUid = IPCSkeleton::GetCallingUid();
1011 EventReport::SendBundleSystemEvent(bundleEventType, sysEventInfo);
1012 }
1013
CheckNeedInstall(const std::unordered_map<std::string,InnerBundleInfo> & infos,InnerBundleInfo & oldInfo,bool & isDowngrade)1014 bool AppServiceFwkInstaller::CheckNeedInstall(const std::unordered_map<std::string, InnerBundleInfo> &infos,
1015 InnerBundleInfo &oldInfo, bool &isDowngrade)
1016 {
1017 if (infos.empty()) {
1018 APP_LOGW("innerbundleinfos is empty");
1019 return false;
1020 }
1021 if (!(dataMgr_->FetchInnerBundleInfo(bundleName_, oldInfo))) {
1022 APP_LOGD("bundleName %{public}s not existed local", bundleName_.c_str());
1023 return true;
1024 }
1025 APP_LOGI_NOFUNC("%{public}s old version:%{public}d, new version:%{public}d",
1026 bundleName_.c_str(), oldInfo.GetVersionCode(), versionCode_);
1027 if (oldInfo.GetVersionCode() == versionCode_) {
1028 if (oldInfo.GetApplicationBundleType() != BundleType::APP_SERVICE_FWK) {
1029 APP_LOGW("bundle %{public}s type is not same, existing type is %{public}d",
1030 bundleName_.c_str(), oldInfo.GetApplicationBundleType());
1031 return false;
1032 }
1033 moduleUpdate_ = true;
1034 return true;
1035 } else if (oldInfo.GetVersionCode() > versionCode_) {
1036 isDowngrade = true;
1037 APP_LOGW("version code is lower than current app service");
1038 return false;
1039 }
1040 APP_LOGI_NOFUNC("%{public}s version code is upgraded", bundleName_.c_str());
1041 versionUpgrade_ = true;
1042 return true;
1043 }
1044
RemoveLowerVersionSoDir(uint32_t versionCode)1045 ErrCode AppServiceFwkInstaller::RemoveLowerVersionSoDir(uint32_t versionCode)
1046 {
1047 if (!versionUpgrade_) {
1048 APP_LOGW("versionCode is not upgraded, so there is no need to delete the so dir");
1049 return ERR_OK;
1050 }
1051 std::string bundleDir =
1052 std::string(AppExecFwk::Constants::BUNDLE_CODE_DIR) +
1053 AppExecFwk::ServiceConstants::PATH_SEPARATOR + bundleName_;
1054 std::string versionDir = bundleDir
1055 + AppExecFwk::ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(versionCode);
1056 APP_LOGI_NOFUNC("RemoveLowerVersionSoDir %{public}s", versionDir.c_str());
1057 return InstalldClient::GetInstance()->RemoveDir(versionDir);
1058 }
1059
VerifyCodeSignatureForNativeFiles(const std::string & bundlePath,const std::string & cpuAbi,const std::string & targetSoPath) const1060 ErrCode AppServiceFwkInstaller::VerifyCodeSignatureForNativeFiles(const std::string &bundlePath,
1061 const std::string &cpuAbi, const std::string &targetSoPath) const
1062 {
1063 APP_LOGD("begin to verify code signature for hsp native files");
1064 CodeSignatureParam codeSignatureParam;
1065 codeSignatureParam.modulePath = bundlePath;
1066 codeSignatureParam.cpuAbi = cpuAbi;
1067 codeSignatureParam.targetSoPath = targetSoPath;
1068 codeSignatureParam.signatureFileDir = "";
1069 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle_;
1070 codeSignatureParam.appIdentifier = appIdentifier_;
1071 codeSignatureParam.isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
1072 codeSignatureParam.isPreInstalledBundle = true;
1073 return InstalldClient::GetInstance()->VerifyCodeSignature(codeSignatureParam);
1074 }
1075
DeliveryProfileToCodeSign(std::vector<Security::Verify::HapVerifyResult> & hapVerifyResults) const1076 ErrCode AppServiceFwkInstaller::DeliveryProfileToCodeSign(
1077 std::vector<Security::Verify::HapVerifyResult> &hapVerifyResults) const
1078 {
1079 InnerBundleInfo oldInfo;
1080 if (dataMgr_->FetchInnerBundleInfo(bundleName_, oldInfo)) {
1081 APP_LOGD("shared bundle %{public}s has been installed and unnecessary to delivery sign profile",
1082 bundleName_.c_str());
1083 return ERR_OK;
1084 }
1085 if (hapVerifyResults.empty()) {
1086 APP_LOGE("no sign info in the all haps");
1087 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
1088 }
1089
1090 Security::Verify::ProvisionInfo provisionInfo = hapVerifyResults[0].GetProvisionInfo();
1091 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE ||
1092 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
1093 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM ||
1094 provisionInfo.type == Security::Verify::ProvisionType::DEBUG) {
1095 if (provisionInfo.profileBlockLength == 0 || provisionInfo.profileBlock == nullptr) {
1096 APP_LOGE("invalid sign profile");
1097 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
1098 }
1099 return InstalldClient::GetInstance()->DeliverySignProfile(provisionInfo.bundleInfo.bundleName,
1100 provisionInfo.profileBlockLength, provisionInfo.profileBlock.get());
1101 }
1102 return ERR_OK;
1103 }
1104
MarkInstallFinish()1105 ErrCode AppServiceFwkInstaller::MarkInstallFinish()
1106 {
1107 if (dataMgr_ == nullptr) {
1108 APP_LOGE("dataMgr_ is nullptr");
1109 return ERR_APPEXECFWK_NULL_PTR;
1110 }
1111 InnerBundleInfo info;
1112 if (!dataMgr_->FetchInnerBundleInfo(bundleName_, info)) {
1113 APP_LOGE("mark finish failed, -n %{public}s not exist", bundleName_.c_str());
1114 return ERR_APPEXECFWK_FETCH_BUNDLE_ERROR;
1115 }
1116 info.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
1117 info.SetInstallMark(bundleName_, info.GetCurModuleName(), InstallExceptionStatus::INSTALL_FINISH);
1118 if (!dataMgr_->UpdateInnerBundleInfo(info, true)) {
1119 if (!dataMgr_->UpdateInnerBundleInfo(info, true)) {
1120 APP_LOGE("save mark failed, -n %{public}s", bundleName_.c_str());
1121 return ERR_APPEXECFWK_UPDATE_BUNDLE_ERROR;
1122 }
1123 }
1124 return ERR_OK;
1125 }
1126 } // namespace AppExecFwk
1127 } // namespace OHOS
1128