• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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