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