Merge "Remove defininition PKGMGR_INSTALLER_ERROR_KEY_STR" into tizen
[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 <unistd.h>
8 #include <sys/types.h>
9
10 #include <cassert>
11 #include <map>
12 #include <vector>
13
14 #include "common/pkgmgr_registration.h"
15 #include "common/utils/logging.h"
16
17 namespace {
18
19 namespace ci = common_installer;
20
21 const std::map<ci::RequestType, const char*> kEventStr = {
22   {ci::RequestType::Install, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
23   {ci::RequestType::Recovery, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
24   {ci::RequestType::Reinstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
25   {ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
26   {ci::RequestType::Unknown, PKGMGR_INSTALLER_INSTALL_EVENT_STR},  // not needed
27   {ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR}
28 };
29
30 }  // namespace
31
32 namespace common_installer {
33
34 PkgmgrSignal::State PkgmgrSignal::state_ = PkgmgrSignal::State::NOT_SENT;
35
36 PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi, RequestType req_type)
37     : pi_(pi), request_type_(req_type) {
38 }
39
40 bool PkgmgrSignal::SendStarted(
41     const std::string& type, const std::string& pkgid) {
42   if (state_ != State::NOT_SENT) {
43     return false;
44   }
45
46   auto key = kEventStr.find(request_type_);
47   if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, key->second, type, pkgid)) {
48     return false;
49   }
50
51   state_ = State::STARTED;
52
53   // workaround for pkgmgr client to know all appids which are uninstalled
54   if (request_type_ == ci::RequestType::Uninstall)
55     if (!SendAppids(type, pkgid))
56       return false;
57
58   return true;
59 }
60
61 bool PkgmgrSignal::SendProgress(int progress,
62     const std::string& type, const std::string& pkgid) {
63   if (state_ != State::STARTED) {
64     return false;
65   }
66
67   return SendSignal(PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
68       std::to_string(progress).c_str(), type, pkgid);
69 }
70
71 bool PkgmgrSignal::SendFinished(
72     Step::Status result, const std::string& type, const std::string& pkgid) {
73   if (state_ != State::STARTED) {
74     return false;
75   }
76   if (result != Step::Status::OK) {
77     if (!SendSignal(
78         PKGMGR_INSTALLER_ERROR_KEY_STR,
79         std::to_string(static_cast<int>(result)).c_str(), type, pkgid)) {
80       return false;
81     }
82   }
83   if (!SendSignal(
84       PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid)) {
85     return false;
86   }
87   state_ = State::FINISHED;
88   return true;
89 }
90
91 bool PkgmgrSignal::SendSignal(
92     const char* key,
93     const char* value,
94     const std::string& type,
95     const std::string& pkgid) const {
96   // send pkgmgr signal
97   if (pkgmgr_installer_send_signal(
98         pi_,
99         !type.empty() ?  type.c_str(): "",
100         !pkgid.empty() ? pkgid.c_str() : "",
101         key,
102         value)) {
103     LOG(ERROR) << "Fail to send pkgmgr signal";
104     return false;
105   }
106
107   LOG(DEBUG) << "Success to send pkgmgr signal"
108              << " PKGID=" << pkgid
109              << " KEY=" << key
110              << " VALUE=" << value;
111   return true;
112 }
113
114 const char* PkgmgrSignal::GetResultKey(Step::Status result) const {
115   switch (result) {
116     case Step::Status::OK:
117       return PKGMGR_INSTALLER_OK_EVENT_STR;
118     default:
119       return PKGMGR_INSTALLER_FAIL_EVENT_STR;
120   }
121 }
122
123 bool PkgmgrSignal::SendAppids(const std::string& type,
124                               const std::string& pkgid) const {
125   std::vector<std::string> appids;
126   if (!QueryAppidsForPkgId(pkgid, &appids, getuid()))
127     return true;
128   for (auto& appid : appids) {
129     if (!pkgmgr_installer_send_app_uninstall_signal(pi_, type.c_str(),
130                                                     pkgid.c_str(),
131                                                     appid.c_str()))
132       return false;
133   }
134   return true;
135 }
136
137 }  // namespace common_installer