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