1 /*
2 * Copyright (c) 2021-2022 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 "bundle_mgr_service_event_handler.h"
17
18 #include <future>
19
20 #include "app_log_wrapper.h"
21 #include "bundle_mgr_service.h"
22 #include "bundle_scanner.h"
23 #include "perf_profile.h"
24 #include "system_bundle_installer.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
BMSEventHandler(const std::shared_ptr<EventRunner> & runner)28 BMSEventHandler::BMSEventHandler(const std::shared_ptr<EventRunner> &runner) : EventHandler(runner)
29 {
30 APP_LOGD("instance is created");
31 }
32
~BMSEventHandler()33 BMSEventHandler::~BMSEventHandler()
34 {
35 APP_LOGD("instance is destroyed");
36 }
37
ProcessEvent(const InnerEvent::Pointer & event)38 void BMSEventHandler::ProcessEvent(const InnerEvent::Pointer &event)
39 {
40 switch (event->GetInnerEventId()) {
41 case BUNDLE_SCAN_START: {
42 OnStartScanning(Constants::DEFAULT_USERID);
43 SetAllInstallFlag();
44 DelayedSingleton<BundleMgrService>::GetInstance()->RegisterService();
45 break;
46 }
47 case BUNDLE_SCAN_FINISHED:
48 break;
49 case BMS_START_FINISHED:
50 break;
51 case BUNDLE_REBOOT_SCAN_START: {
52 RebootStartScanning();
53 SetAllInstallFlag();
54 DelayedSingleton<BundleMgrService>::GetInstance()->RegisterService();
55 break;
56 }
57 default:
58 APP_LOGE("the eventId is not supported");
59 break;
60 }
61 }
62
OnStartScanning(int32_t userId)63 void BMSEventHandler::OnStartScanning(int32_t userId)
64 {
65 auto future = std::async(std::launch::async, [this, userId] {
66 ProcessSystemBundleInstall(Constants::AppType::SYSTEM_APP, userId);
67 ProcessSystemBundleInstall(Constants::AppType::THIRD_SYSTEM_APP, userId);
68 });
69 future.get();
70 }
71
ProcessSystemBundleInstall(Constants::AppType appType,int32_t userId) const72 void BMSEventHandler::ProcessSystemBundleInstall(Constants::AppType appType, int32_t userId) const
73 {
74 APP_LOGD("scan thread start");
75 auto scanner = std::make_unique<BundleScanner>();
76 if (!scanner) {
77 APP_LOGE("make scanner failed");
78 return;
79 }
80
81 std::string scanDir = (appType == Constants::AppType::SYSTEM_APP) ? Constants::SYSTEM_APP_SCAN_PATH
82 : Constants::THIRD_SYSTEM_APP_SCAN_PATH;
83 APP_LOGD("scanDir: %{public}s and userId: %{public}d", scanDir.c_str(), userId);
84 std::list<std::string> bundleList = scanner->Scan(scanDir);
85 auto iter = std::find(bundleList.begin(), bundleList.end(), Constants::SYSTEM_RESOURCES_APP_PATH);
86 if (iter != bundleList.end()) {
87 bundleList.erase(iter);
88 bundleList.insert(bundleList.begin(), Constants::SYSTEM_RESOURCES_APP_PATH);
89 }
90
91 for (const auto &item : bundleList) {
92 SystemBundleInstaller installer(item);
93 APP_LOGD("scan item %{public}s", item.c_str());
94 if (!installer.InstallSystemBundle(appType, userId)) {
95 APP_LOGW("Install System app:%{public}s error", item.c_str());
96 }
97 }
98
99 PerfProfile::GetInstance().Dump();
100 }
101
SetAllInstallFlag() const102 void BMSEventHandler::SetAllInstallFlag() const
103 {
104 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
105 if (dataMgr == nullptr) {
106 APP_LOGE("DataMgr is nullptr");
107 return;
108 }
109
110 dataMgr->SetInitialUserFlag(true);
111 }
112
RebootStartScanning(int32_t userId)113 void BMSEventHandler::RebootStartScanning(int32_t userId)
114 {
115 auto future = std::async(std::launch::async, [this, userId] {
116 RebootProcessSystemBundle(userId);
117 });
118 future.get();
119 }
120
RebootProcessSystemBundle(int32_t userId)121 void BMSEventHandler::RebootProcessSystemBundle(int32_t userId)
122 {
123 APP_LOGD("reboot scan thread start");
124 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
125 if (dataMgr == nullptr) {
126 APP_LOGE("DataMgr is nullptr");
127 return;
128 }
129
130 auto scanner = std::make_unique<BundleScanner>();
131 if (!scanner) {
132 APP_LOGE("make scanner failed");
133 return;
134 }
135
136 std::list<std::string> appBundleList = scanner->Scan(Constants::SYSTEM_APP_SCAN_PATH);
137 auto iter = std::find(
138 appBundleList.begin(), appBundleList.end(), Constants::SYSTEM_RESOURCES_APP_PATH);
139 if (iter != appBundleList.end()) {
140 appBundleList.erase(iter);
141 appBundleList.insert(appBundleList.begin(), Constants::SYSTEM_RESOURCES_APP_PATH);
142 }
143
144 std::list<std::string> vendorBundleList =
145 scanner->Scan(Constants::THIRD_SYSTEM_APP_SCAN_PATH);
146 BundleInfo bundleInfo;
147 std::vector<PreInstallBundleInfo> preInstallBundleInfos;
148 if (!dataMgr->LoadAllPreInstallBundleInfos(preInstallBundleInfos)) {
149 APP_LOGE("LoadAllPreInstallBundleInfos failed.");
150 return;
151 }
152
153 for (auto &iter : preInstallBundleInfos) {
154 APP_LOGD("preInstallBundleInfos: %{public}s ", iter.GetBundleName().c_str());
155 loadExistData_.emplace(iter.GetBundleName(), iter);
156 }
157
158 RebootBundleInstall(appBundleList, Constants::AppType::SYSTEM_APP);
159 RebootBundleInstall(vendorBundleList, Constants::AppType::THIRD_SYSTEM_APP);
160 RebootBundleUninstall();
161 }
162
RebootBundleInstall(const std::list<std::string> & scanPathList,Constants::AppType appType)163 void BMSEventHandler::RebootBundleInstall(
164 const std::list<std::string> &scanPathList, Constants::AppType appType)
165 {
166 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
167 if (dataMgr == nullptr) {
168 APP_LOGE("DataMgr is nullptr");
169 return;
170 }
171
172 for (auto &scanPathIter : scanPathList) {
173 APP_LOGD("reboot scan bundle path: %{public}s ", scanPathIter.c_str());
174 std::unordered_map<std::string, InnerBundleInfo> infos;
175 if (!ParseHapFiles(scanPathIter, infos) || infos.empty()) {
176 APP_LOGE("obtain bundleinfo failed : %{public}s ", scanPathIter.c_str());
177 continue;
178 }
179
180 auto bundleName = infos.begin()->second.GetBundleName();
181 auto hapVersionCode = infos.begin()->second.GetVersionCode();
182 AddParseInfosToMap(bundleName, infos);
183 auto mapIter = loadExistData_.find(bundleName);
184 if (mapIter == loadExistData_.end()) {
185 APP_LOGD("OTA Install new bundle(%{public}s) by path(%{public}s).",
186 bundleName.c_str(), scanPathIter.c_str());
187 if (!OTAInstallSystemBundle(scanPathIter, appType)) {
188 APP_LOGE("OTA Install new bundle(%{public}s) error.", bundleName.c_str());
189 }
190
191 continue;
192 }
193
194 APP_LOGD("OTA process bundle(%{public}s) by path(%{public}s).",
195 bundleName.c_str(), scanPathIter.c_str());
196 BundleInfo hasInstalledInfo;
197 auto hasBundleInstalled = dataMgr->GetBundleInfo(
198 bundleName, BundleFlag::GET_BUNDLE_DEFAULT, hasInstalledInfo, Constants::ANY_USERID);
199 if (!hasBundleInstalled) {
200 APP_LOGW("app(%{public}s) has been uninstalled and do not OTA install.",
201 bundleName.c_str());
202 continue;
203 }
204
205 for (auto item : infos) {
206 auto parserModuleNames = item.second.GetModuleNameVec();
207 if (parserModuleNames.empty()) {
208 APP_LOGE("module is empty when parser path(%{public}s).", item.first.c_str());
209 continue;
210 }
211
212 // Used to judge whether the module has been installed.
213 bool hasModuleInstalled = std::find(
214 hasInstalledInfo.hapModuleNames.begin(), hasInstalledInfo.hapModuleNames.end(),
215 parserModuleNames[0]) != hasInstalledInfo.hapModuleNames.end();
216 if (HasModuleSavedInPreInstalledDb(bundleName, item.first) && !hasModuleInstalled) {
217 APP_LOGW("module(%{public}s) has been uninstalled and do not OTA install",
218 parserModuleNames[0].c_str());
219 continue;
220 }
221
222 // Generally, when the versionCode of Hap is greater than the installed versionCode,
223 // Except for the uninstalled app, they can be installed or upgraded directly by OTA.
224 if (hasInstalledInfo.versionCode < hapVersionCode) {
225 APP_LOGD("OTA update module(%{public}s) by path(%{public}s)",
226 parserModuleNames[0].c_str(), item.first.c_str());
227 if (!OTAInstallSystemBundle(item.first, appType)) {
228 APP_LOGE("OTA update module(%{public}s) failed", parserModuleNames[0].c_str());
229 }
230 }
231
232 // The versionCode of Hap is equal to the installed versionCode.
233 // You can only install new modules by OTA
234 if (hasInstalledInfo.versionCode == hapVersionCode) {
235 if (hasModuleInstalled) {
236 APP_LOGD("module(%{public}s) has been installed and versionCode is same.",
237 parserModuleNames[0].c_str());
238 continue;
239 }
240
241 APP_LOGD("OTA install module(%{public}s) by path(%{public}s)",
242 parserModuleNames[0].c_str(), item.first.c_str());
243 if (!OTAInstallSystemBundle(item.first, appType)) {
244 APP_LOGE("OTA install module(%{public}s) failed", parserModuleNames[0].c_str());
245 }
246 }
247 }
248 }
249 }
250
AddParseInfosToMap(const std::string & bundleName,const std::unordered_map<std::string,InnerBundleInfo> & infos)251 void BMSEventHandler::AddParseInfosToMap(
252 const std::string &bundleName, const std::unordered_map<std::string, InnerBundleInfo> &infos)
253 {
254 auto hapParseInfoMapIter = hapParseInfoMap_.find(bundleName);
255 if (hapParseInfoMapIter == hapParseInfoMap_.end()) {
256 hapParseInfoMap_.emplace(bundleName, infos);
257 return;
258 }
259
260 auto iterMap = hapParseInfoMapIter->second;
261 for (auto infoIter : infos) {
262 iterMap.emplace(infoIter.first, infoIter.second);
263 }
264
265 hapParseInfoMap_.at(bundleName) = iterMap;
266 }
267
RebootBundleUninstall()268 void BMSEventHandler::RebootBundleUninstall()
269 {
270 APP_LOGD("Reboot scan and OTA uninstall start");
271 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
272 if (dataMgr == nullptr) {
273 APP_LOGE("DataMgr is nullptr");
274 return;
275 }
276
277 for (auto &loadIter : loadExistData_) {
278 std::string bundleName = loadIter.first;
279 auto listIter = hapParseInfoMap_.find(bundleName);
280 if (listIter == hapParseInfoMap_.end()) {
281 APP_LOGD("OTA uninstall app(%{public}s).", bundleName.c_str());
282 std::string list;
283 SystemBundleInstaller installer(list);
284 if (!installer.UninstallSystemBundle(bundleName)) {
285 APP_LOGE("OTA uninstall app(%{public}s) error", bundleName.c_str());
286 } else {
287 std::string moduleName;
288 DeletePreInfoInDb(bundleName, moduleName, true);
289 }
290
291 continue;
292 }
293
294 BundleInfo hasInstalledInfo;
295 auto hasBundleInstalled = dataMgr->GetBundleInfo(
296 bundleName, BundleFlag::GET_BUNDLE_DEFAULT, hasInstalledInfo, Constants::ANY_USERID);
297 if (!hasBundleInstalled) {
298 APP_LOGW("app(%{public}s) maybe has been uninstall.", bundleName.c_str());
299 continue;
300 }
301
302 // Check the installed module.
303 // If the corresponding Hap does not exist, it should be uninstalled.
304 for (auto moduleName : hasInstalledInfo.hapModuleNames) {
305 bool hasModuleHapExist = false;
306 for (auto parserInfoIter : listIter->second) {
307 auto parserModuleNames = parserInfoIter.second.GetModuleNameVec();
308 if (!parserModuleNames.empty() && moduleName == parserModuleNames[0]) {
309 hasModuleHapExist = true;
310 break;
311 }
312 }
313
314 if (!hasModuleHapExist) {
315 APP_LOGD("OTA app(%{public}s) uninstall module(%{public}s).",
316 bundleName.c_str(), moduleName.c_str());
317 std::string list;
318 SystemBundleInstaller installer(list);
319 if (!installer.UninstallSystemBundle(bundleName, moduleName)) {
320 APP_LOGE("OTA app(%{public}s) uninstall module(%{public}s) error.",
321 bundleName.c_str(), moduleName.c_str());
322 }
323 }
324 }
325
326 // Check the preInstall path in Db.
327 // If the corresponding Hap does not exist, it should be deleted.
328 auto parserInfoMap = listIter->second;
329 for (auto preBundlePath : loadIter.second.GetBundlePaths()) {
330 auto parserInfoIter = parserInfoMap.find(preBundlePath);
331 if (parserInfoIter != parserInfoMap.end()) {
332 APP_LOGD("OTA uninstall app(%{public}s) module path(%{public}s) exits.",
333 bundleName.c_str(), preBundlePath.c_str());
334 continue;
335 }
336
337 APP_LOGD("OTA app(%{public}s) delete path(%{public}s).",
338 bundleName.c_str(), preBundlePath.c_str());
339 DeletePreInfoInDb(bundleName, preBundlePath, false);
340 }
341 }
342
343 APP_LOGD("Reboot scan and OTA uninstall success");
344 }
345
DeletePreInfoInDb(const std::string & bundleName,const std::string & bundlePath,bool bundleLevel)346 void BMSEventHandler::DeletePreInfoInDb(
347 const std::string &bundleName, const std::string &bundlePath, bool bundleLevel)
348 {
349 APP_LOGD("DeletePreInfoInDb bundle(%{public}s)", bundleName.c_str());
350 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
351 if (dataMgr == nullptr) {
352 APP_LOGE("DataMgr is nullptr");
353 return;
354 }
355
356 PreInstallBundleInfo preInstallBundleInfo;
357 preInstallBundleInfo.SetBundleName(bundleName);
358 if (bundleLevel) {
359 APP_LOGD("DeletePreInfoInDb bundle bundleLevel");
360 dataMgr->DeletePreInstallBundleInfo(bundleName, preInstallBundleInfo);
361 return;
362 }
363
364 APP_LOGD("DeletePreInfoInDb bundle not bundleLevel with path(%{public}s)",
365 bundlePath.c_str());
366 dataMgr->GetPreInstallBundleInfo(bundleName, preInstallBundleInfo);
367 preInstallBundleInfo.DeleteBundlePath(bundlePath);
368 if (preInstallBundleInfo.GetBundlePaths().empty()) {
369 dataMgr->DeletePreInstallBundleInfo(bundleName, preInstallBundleInfo);
370 } else {
371 dataMgr->SavePreInstallBundleInfo(bundleName, preInstallBundleInfo);
372 }
373 }
374
HasModuleSavedInPreInstalledDb(const std::string & bundleName,const std::string & bundlePath)375 bool BMSEventHandler::HasModuleSavedInPreInstalledDb(
376 const std::string &bundleName, const std::string &bundlePath)
377 {
378 auto preInstallIter = loadExistData_.find(bundleName);
379 if (preInstallIter == loadExistData_.end()) {
380 APP_LOGE("app(%{public}s) does not save in PreInstalledDb.", bundleName.c_str());
381 return false;
382 }
383
384 return preInstallIter->second.HasBundlePath(bundlePath);
385 }
386
OTAInstallSystemBundle(const std::string & filePath,Constants::AppType appType)387 bool BMSEventHandler::OTAInstallSystemBundle(
388 const std::string &filePath, Constants::AppType appType)
389 {
390 APP_LOGD("OTA install start in bunlde: %{public}s", filePath.c_str());
391 if (filePath.empty()) {
392 return false;
393 }
394
395 SystemBundleInstaller installer(filePath);
396 return installer.OTAInstallSystemBundle(appType);
397 }
398
ParseHapFiles(const std::string & hapFilePath,std::unordered_map<std::string,InnerBundleInfo> & infos)399 bool BMSEventHandler::ParseHapFiles(
400 const std::string &hapFilePath, std::unordered_map<std::string, InnerBundleInfo> &infos)
401 {
402 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
403 std::vector<std::string> hapFilePathVec { hapFilePath };
404 std::vector<std::string> realPaths;
405 auto ret = BundleUtil::CheckFilePath(hapFilePathVec, realPaths);
406 if (ret != ERR_OK) {
407 APP_LOGE("File path %{public}s invalid", hapFilePath.c_str());
408 return false;
409 }
410
411 BundleParser bundleParser;
412 for (auto realPath : realPaths) {
413 InnerBundleInfo innerBundleInfo;
414 ret = bundleParser.Parse(realPath, innerBundleInfo);
415 if (ret != ERR_OK) {
416 APP_LOGE("parse bundle info failed, error: %{public}d", ret);
417 continue;
418 }
419
420 infos.emplace(realPath, innerBundleInfo);
421 }
422
423 ret = CheckAppLabelInfo(infos);
424 if (ret != ERR_OK) {
425 APP_LOGE("Check APP label failed %{public}d", ret);
426 return false;
427 }
428
429 return true;
430 }
431
CheckAppLabelInfo(const std::unordered_map<std::string,InnerBundleInfo> & infos)432 ErrCode BMSEventHandler::CheckAppLabelInfo(
433 const std::unordered_map<std::string, InnerBundleInfo> &infos)
434 {
435 APP_LOGD("Check APP label");
436 ErrCode ret = ERR_OK;
437 if (infos.empty()) {
438 return ret;
439 }
440
441 std::string bundleName = (infos.begin()->second).GetBundleName();
442 std::string vendor = (infos.begin()->second).GetVendor();
443 auto versionCode = (infos.begin()->second).GetVersionCode();
444 std::string versionName = (infos.begin()->second).GetVersionName();
445 uint32_t target = (infos.begin()->second).GetTargetVersion();
446 uint32_t compatible = (infos.begin()->second).GetCompatibleVersion();
447 bool singleUser = (infos.begin()->second).IsSingleUser();
448 Constants::AppType appType = (infos.begin()->second).GetAppType();
449
450 for (const auto &info :infos) {
451 // check bundleName
452 if (bundleName != info.second.GetBundleName()) {
453 return ERR_APPEXECFWK_INSTALL_BUNDLENAME_NOT_SAME;
454 }
455 // check version
456 if (versionCode != info.second.GetVersionCode()) {
457 return ERR_APPEXECFWK_INSTALL_VERSIONCODE_NOT_SAME;
458 }
459 if (versionName != info.second.GetVersionName()) {
460 return ERR_APPEXECFWK_INSTALL_VERSIONNAME_NOT_SAME;
461 }
462 // check vendor
463 if (vendor != info.second.GetVendor()) {
464 return ERR_APPEXECFWK_INSTALL_VENDOR_NOT_SAME;
465 }
466 // check release type
467 if (target != info.second.GetTargetVersion()) {
468 return ERR_APPEXECFWK_INSTALL_RELEASETYPE_TARGET_NOT_SAME;
469 }
470 if (compatible != info.second.GetCompatibleVersion()) {
471 return ERR_APPEXECFWK_INSTALL_RELEASETYPE_COMPATIBLE_NOT_SAME;
472 }
473 if (singleUser != info.second.IsSingleUser()) {
474 return ERR_APPEXECFWK_INSTALL_SINGLETON_NOT_SAME;
475 }
476 if (appType != info.second.GetAppType()) {
477 return ERR_APPEXECFWK_INSTALL_APPTYPE_NOT_SAME;
478 }
479 }
480 APP_LOGD("finish check APP label");
481 return ret;
482 }
483 } // namespace AppExecFwk
484 } // namespace OHOS
485