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