Add Dependency Checker
[platform/core/appfw/app-installers.git] / src / common / installer_runner.cc
1 // Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/installer_runner.h"
6
7 #include <manifest_parser/utils/logging.h>
8
9 #include <list>
10 #include <utility>
11
12 #include "common/app_installer.h"
13 #include "common/installer_factory.h"
14 #include "common/pkgmgr_interface.h"
15
16 namespace common_installer {
17
18 InstallerRunner::InstallerRunner(
19     std::unique_ptr<InstallerFactory> factory, PkgMgrPtr pkgmgr)
20     : factory_(std::move(factory)), pkgmgr_(pkgmgr) {
21   Init();
22   if (pkgmgr->GetInstallationMode() == InstallationMode::ONLINE)
23     pi_ = pkgmgr->CreatePkgmgrSignal();
24 }
25
26 bool InstallerRunner::SortInstallers() {
27   DependencyChecker dep_checker(pkgmgr_->GetUid(), pkgmgr_);
28   for (auto& installer : installers_) {
29     if (!dep_checker.AddInstaller(std::move(installer))) {
30       LOG(ERROR) << "Failed to add installer to dependency checker";
31       return false;
32     }
33   }
34   installers_ = dep_checker.GetSortedAppInstallers();
35   if (installers_.empty()) {
36     LOG(ERROR) << "Sort installers fail";
37     return false;
38   }
39   return true;
40 }
41
42 AppInstaller::Result InstallerRunner::Run() {
43   AppInstaller::Result result = AppInstaller::Result::OK;
44   if (getuid() != 0 && !SortInstallers()) {
45     if (pi_) {
46       pi_->SetRequestType(pkgmgr_->GetRequestType());
47       pi_->SendStarted({}, {});
48       pi_->SendError(Step::Status::OPERATION_NOT_ALLOWED,
49           "package dependency are not met", {}, {});
50       pi_->SendFinished(Step::Status::OPERATION_NOT_ALLOWED, {}, {});
51     }
52     return AppInstaller::Result::ERROR;
53   }
54
55   std::list<std::unique_ptr<AppInstaller>>::iterator it(installers_.begin());
56   for (; it != installers_.end(); ++it) {
57     result = (*it)->Process();
58     if (result != AppInstaller::Result::OK)
59       break;
60   }
61   if (it != installers_.end() && result == AppInstaller::Result::ERROR) {
62     do {
63       AppInstaller::Result ret = (*it)->Undo();
64       if (ret != AppInstaller::Result::OK && ret != AppInstaller::Result::ERROR)
65         result = AppInstaller::Result::UNDO_ERROR;
66     } while (it-- != installers_.begin());
67   } else {
68     --it;
69     do {
70       // Clean operation always succeeds
71       (*it)->Clean();
72     } while (it-- != installers_.begin());
73   }
74
75   return result;
76 }
77
78 void InstallerRunner::Init() {
79   for (int i = 0; i < pkgmgr_->GetRequestInfoCount(); i++) {
80     std::unique_ptr<AppInstaller> installer =
81         factory_->CreateInstaller(pkgmgr_, i);
82     installers_.emplace_back(std::move(installer));
83   }
84 }
85
86 }  // namespace common_installer