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