ea4c03a39694965f66e58da75ce5bbb325c4a5dc
[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 #include <pkgmgr_parser_db.h>
9
10 #include <list>
11 #include <string>
12 #include <utility>
13
14 #include "common/installer/app_installer.h"
15 #include "common/installer_context.h"
16 #include "common/installer_factory.h"
17 #include "common/pkgmgr_interface.h"
18
19 namespace common_installer {
20
21 InstallerRunner::InstallerRunner(
22     std::unique_ptr<InstallerFactory> factory, PkgMgrPtr pkgmgr)
23     : factory_(std::move(factory)), pkgmgr_(pkgmgr) {
24   Init();
25   if (pkgmgr->GetInstallationMode() == InstallationMode::ONLINE)
26     pi_ = pkgmgr->CreatePkgmgrSignal();
27 }
28
29 bool InstallerRunner::NeedCheckDependency() {
30   RequestType req_type = pkgmgr_->GetRequestType();
31   if (req_type == RequestType::Move)
32     return false;
33   if (req_type == RequestType::Recovery)
34     return false;
35   if (req_type == RequestType::RecoveryUpdate)
36     return false;
37   if (req_type == RequestType::DisablePkg)
38     return false;
39   if (req_type == RequestType::EnablePkg)
40     return false;
41   if (req_type == RequestType::MigrateExtImg)
42     return false;
43   if (req_type == RequestType::RecoverDB)
44     return false;
45
46   return true;
47 }
48
49 bool InstallerRunner::SortInstallers(DependencyChecker* dep_checker) {
50   for (auto& installer : installers_) {
51     if (!dep_checker->AddInstaller(std::move(installer)))
52       return false;
53   }
54   installers_ = dep_checker->GetSortedAppInstallers();
55   if (installers_.empty())
56     return false;
57
58   return true;
59 }
60
61 AppInstaller::Result InstallerRunner::Run() {
62   AppInstaller::Result result = AppInstaller::Result::OK;
63   if (installers_.size() == 0)
64     return result;
65
66   if (getuid() != 0 && NeedCheckDependency()) {
67     DependencyChecker dep_checker(pkgmgr_);
68     if (!SortInstallers(&dep_checker)) {
69       LOG(ERROR) << dep_checker.GetErrorMessage();
70       if (pi_) {
71         pi_->SetRequestType(pkgmgr_->GetRequestType());
72         pi_->SendStarted({}, {});
73         pi_->SendError(Step::Status::OPERATION_NOT_ALLOWED,
74             dep_checker.GetErrorMessage(), {}, {});
75         pi_->SendFinished(Step::Status::OPERATION_NOT_ALLOWED, {}, {});
76       }
77       return AppInstaller::Result::ERROR;
78     }
79   }
80
81   std::list<std::unique_ptr<AppInstaller>>::iterator it(installers_.begin());
82   for (; it != installers_.end(); ++it) {
83     result = (*it)->Process();
84     if (result != AppInstaller::Result::OK)
85       break;
86   }
87   if (it != installers_.end() && result == AppInstaller::Result::ERROR) {
88     pkgmgr_parser_clear_cache_memory_db();
89     do {
90       AppInstaller::Result ret = (*it)->Undo();
91       if (ret != AppInstaller::Result::OK && ret != AppInstaller::Result::ERROR)
92         result = AppInstaller::Result::UNDO_ERROR;
93     } while (it-- != installers_.begin());
94   } else {
95     pkgmgr_parser_clear_cache_memory_db();
96     if (pkgmgr_->GetRequestType() != RequestType::Recovery)
97       global_recovery_->AppendCleanUp();
98     --it;
99     do {
100       // Clean operation always succeeds
101       (*it)->Clean();
102     } while (it-- != installers_.begin());
103   }
104
105   return result;
106 }
107
108 void InstallerRunner::Init() {
109   global_recovery_ = std::make_unique<GlobalRecoveryFile>(pkgmgr_);
110   bool is_global_request = (pkgmgr_->GetRequestInfoCount() > 1) ? true : false;
111   if (pkgmgr_->GetRequestType() != RequestType::Recovery &&
112         is_global_request) {
113     if (!global_recovery_->Init())
114       return;
115   }
116   for (int i = 0; i < pkgmgr_->GetRequestInfoCount(); i++) {
117     std::unique_ptr<AppInstaller> installer =
118         factory_->CreateInstaller(pkgmgr_, i);
119     if (!installer) {
120       LOG(ERROR) << "Failed to create installer for "
121                  << pkgmgr_->GetRequestInfo(i);
122       continue;
123     }
124     installer->SetIndex(i);
125     if (pkgmgr_->GetRequestType() != RequestType::Recovery &&
126         is_global_request) {
127       std::string recovery_filepath =
128           global_recovery_->AddPathWithType(
129               installer->context_->pkg_type.get());
130       installer->context_->recovery_info.set(RecoveryInfo(recovery_filepath));
131     }
132     installers_.emplace_back(std::move(installer));
133   }
134 }
135
136 }  // namespace common_installer