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