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