Mount install steps
[platform/core/appfw/app-installers.git] / src / common / pkgmgr_signal.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/pkgmgr_signal.h"
6
7 #include <manifest_parser/utils/logging.h>
8
9 #include <unistd.h>
10 #include <sys/types.h>
11
12 #include <cassert>
13 #include <map>
14 #include <vector>
15
16 #include "common/pkgmgr_registration.h"
17
18 namespace {
19
20 namespace ci = common_installer;
21
22 const std::map<ci::RequestType, const char*> kEventStr = {
23   {ci::RequestType::Install, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
24   {ci::RequestType::Recovery, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
25   {ci::RequestType::Reinstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
26   {ci::RequestType::Clear, PKGMGR_INSTALLER_CLEAR_EVENT_STR},
27   {ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
28   {ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
29   {ci::RequestType::Delta, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
30   {ci::RequestType::MountInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
31   {ci::RequestType::MountUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
32   {ci::RequestType::ManifestDirectInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
33   {ci::RequestType::ManifestDirectUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR}
34 };
35
36 }  // namespace
37
38 namespace common_installer {
39
40 PkgmgrSignal::State PkgmgrSignal::state_ = PkgmgrSignal::State::NOT_SENT;
41
42 PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi, RequestType req_type)
43     : pi_(pi), request_type_(req_type), error_message_sent_(false) {
44 }
45
46 bool PkgmgrSignal::SendStarted(
47     const std::string& type, const std::string& pkgid) {
48   if (state_ != State::NOT_SENT) {
49     return false;
50   }
51
52   auto key = kEventStr.find(request_type_);
53   if (key == kEventStr.end()) {
54     return false;
55   }
56   if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, key->second, type, pkgid)) {
57     return false;
58   }
59
60   state_ = State::STARTED;
61
62   // workaround for pkgmgr client to know all appids which are uninstalled
63   if (request_type_ == ci::RequestType::Uninstall)
64     if (!SendAppids(type, pkgid))
65       return false;
66
67   return true;
68 }
69
70 bool PkgmgrSignal::SendProgress(int progress,
71     const std::string& type, const std::string& pkgid) {
72   if (state_ != State::STARTED) {
73     return false;
74   }
75
76   return SendSignal(PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
77       std::to_string(progress).c_str(), type, pkgid);
78 }
79
80 bool PkgmgrSignal::SendFinished(
81     Step::Status result, const std::string& type, const std::string& pkgid) {
82   if (state_ != State::STARTED) {
83     return false;
84   }
85   if (result != Step::Status::OK && !error_message_sent_) {
86     if (!SendSignal(
87         PKGMGR_INSTALLER_ERROR_KEY_STR,
88         std::to_string(static_cast<int>(result)).c_str(), type, pkgid)) {
89       return false;
90     }
91   }
92   if (!SendSignal(
93       PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid)) {
94     return false;
95   }
96   state_ = State::FINISHED;
97   return true;
98 }
99
100 bool PkgmgrSignal::SendError(
101     Step::Status result,
102     const std::string& error_message,
103     const std::string& type,
104     const std::string& pkgid) {
105   if (state_ != State::STARTED) {
106     return false;
107   }
108   std::string error_value = std::to_string(static_cast<int>(result));
109   if (!error_message.empty()) {
110     error_value = error_value + ":" + error_message;
111   }
112   LOG(ERROR) << "PkgmgrSignal error_value: (" << error_value << ")";
113   error_message_sent_ = true;
114   return SendSignal(
115     PKGMGR_INSTALLER_ERROR_KEY_STR,
116     error_value.c_str(),
117     type,
118     pkgid);
119 }
120
121 bool PkgmgrSignal::SendSignal(
122     const char* key,
123     const char* value,
124     const std::string& type,
125     const std::string& pkgid) const {
126   // send pkgmgr signal
127   if (pkgmgr_installer_send_signal(
128         pi_,
129         !type.empty() ?  type.c_str(): "",
130         !pkgid.empty() ? pkgid.c_str() : "",
131         key,
132         value)) {
133     LOG(ERROR) << "Fail to send pkgmgr signal";
134     return false;
135   }
136
137   LOG(DEBUG) << "Success to send pkgmgr signal"
138              << " PKGID=" << pkgid
139              << " KEY=" << key
140              << " VALUE=" << value;
141   return true;
142 }
143
144 const char* PkgmgrSignal::GetResultKey(Step::Status result) const {
145   switch (result) {
146     case Step::Status::OK:
147       return PKGMGR_INSTALLER_OK_EVENT_STR;
148     default:
149       return PKGMGR_INSTALLER_FAIL_EVENT_STR;
150   }
151 }
152
153 bool PkgmgrSignal::SendAppids(const std::string& type,
154                               const std::string& pkgid) const {
155   std::vector<std::string> appids;
156   if (!QueryAppidsForPkgId(pkgid, &appids, getuid()))
157     return true;
158   for (auto& appid : appids) {
159     if (pkgmgr_installer_send_app_uninstall_signal(pi_, type.c_str(),
160                                                     pkgid.c_str(),
161                                                     appid.c_str()))
162       return false;
163   }
164   return true;
165 }
166
167 }  // namespace common_installer