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.
5 #include "common/pkgmgr_signal.h"
7 #include <manifest_parser/utils/logging.h>
10 #include <sys/types.h>
11 #include <systemd/sd-login.h>
12 #include <tzplatform_config.h>
18 #include "common/pkgmgr_query.h"
22 namespace ci = common_installer;
24 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
25 const std::map<ci::RequestType, const char*> kEventStr = {
26 {ci::RequestType::Install, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
27 {ci::RequestType::Recovery, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
28 {ci::RequestType::Reinstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
29 {ci::RequestType::Clear, PKGMGR_INSTALLER_CLEAR_EVENT_STR},
30 {ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
31 {ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
32 {ci::RequestType::Delta, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
33 {ci::RequestType::Move, PKGMGR_INSTALLER_MOVE_EVENT_STR},
34 {ci::RequestType::MountInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
35 {ci::RequestType::MountUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
36 {ci::RequestType::ManifestDirectInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
37 {ci::RequestType::ManifestDirectUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
38 {ci::RequestType::DisablePkg, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
39 {ci::RequestType::EnablePkg, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
40 {ci::RequestType::Unknown, PKGMGR_INSTALLER_UNKNOWN_EVENT_STR}
45 namespace common_installer {
47 PkgmgrSignal::State PkgmgrSignal::state_ = PkgmgrSignal::State::NOT_SENT;
49 PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi, RequestType req_type)
50 : pi_(pi), request_type_(req_type), error_message_sent_(false) {
51 uid_ = pkgmgr_installer_get_uid(pi_);
52 request_mode_ = GetRequestMode(uid_);
55 bool PkgmgrSignal::SendStarted(
56 const std::string& type, const std::string& pkgid) {
57 if (state_ != State::NOT_SENT) {
61 if (!SetupUserList(pkgid))
62 LOG(WARNING) << "Failed to setup user list";
64 auto key = kEventStr.find(request_type_);
65 if (key == kEventStr.end()) {
68 if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, key->second, type, pkgid)) {
71 for (auto l : user_list_) {
72 key = kEventStr.find(l.second);
73 if (key == kEventStr.end())
75 SendSignal(l.first, PKGMGR_INSTALLER_START_KEY_STR, key->second, type,
79 state_ = State::STARTED;
81 // workaround for pkgmgr client to know all appids which are uninstalled
82 if (request_type_ == ci::RequestType::Uninstall)
83 if (!SendAppids(type, pkgid))
89 bool PkgmgrSignal::SendProgress(int progress,
90 const std::string& type, const std::string& pkgid) {
91 if (state_ != State::STARTED) {
95 if (!SendSignal(PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
96 std::to_string(progress).c_str(), type, pkgid))
98 for (auto l : user_list_)
100 SendSignal(l.first, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
101 std::to_string(progress).c_str(), type, pkgid);
106 bool PkgmgrSignal::SendFinished(
107 Step::Status result, const std::string& type, const std::string& pkgid) {
108 if (state_ != State::STARTED) {
111 if (result != Step::Status::OK && !error_message_sent_) {
113 PKGMGR_INSTALLER_ERROR_KEY_STR,
114 std::to_string(static_cast<int>(result)).c_str(), type, pkgid)) {
117 for (auto l : user_list_)
119 PKGMGR_INSTALLER_ERROR_KEY_STR,
120 std::to_string(static_cast<int>(result)).c_str(), type, pkgid);
123 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid)) {
126 for (auto l : user_list_)
128 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid);
129 state_ = State::FINISHED;
133 bool PkgmgrSignal::SendError(
135 const std::string& error_message,
136 const std::string& type,
137 const std::string& pkgid) {
138 if (state_ != State::STARTED) {
141 std::string error_value = std::to_string(static_cast<int>(result));
142 if (!error_message.empty()) {
143 error_value = error_value + ":" + error_message;
145 LOG(ERROR) << "PkgmgrSignal error_value: (" << error_value << ")";
146 error_message_sent_ = true;
148 PKGMGR_INSTALLER_ERROR_KEY_STR,
153 for (auto l : user_list_)
155 PKGMGR_INSTALLER_ERROR_KEY_STR,
162 bool PkgmgrSignal::SendSignal(
165 const std::string& type,
166 const std::string& pkgid) const {
167 // send pkgmgr signal
168 if (pkgmgr_installer_send_signal(
170 !type.empty() ? type.c_str(): "",
171 !pkgid.empty() ? pkgid.c_str() : "",
174 LOG(ERROR) << "Fail to send pkgmgr signal";
178 LOG(DEBUG) << "Success to send pkgmgr signal"
179 << " PKGID=" << pkgid
181 << " VALUE=" << value;
185 bool PkgmgrSignal::SendSignal(
189 const std::string& type,
190 const std::string& pkgid) const {
191 // send pkgmgr signal
192 if (pkgmgr_installer_send_signal_for_uid(
195 !type.empty() ? type.c_str(): "",
196 !pkgid.empty() ? pkgid.c_str() : "",
199 LOG(ERROR) << "Fail to send pkgmgr signal";
203 LOG(DEBUG) << "Success to send pkgmgr signal"
205 << " PKGID=" << pkgid
207 << " VALUE=" << value;
211 const char* PkgmgrSignal::GetResultKey(Step::Status result) const {
213 case Step::Status::OK:
214 return PKGMGR_INSTALLER_OK_EVENT_STR;
216 return PKGMGR_INSTALLER_FAIL_EVENT_STR;
220 bool PkgmgrSignal::SendAppids(const std::string& type,
221 const std::string& pkgid) const {
222 std::vector<std::string> appids;
223 if (!QueryAppidsForPkgId(pkgid, &appids, pkgmgr_installer_get_uid(pi_)))
225 for (auto& appid : appids) {
226 if (pkgmgr_installer_send_app_uninstall_signal(pi_, type.c_str(),
234 bool PkgmgrSignal::SetupUserList(const std::string& pkgid) {
236 uid_t* uids = nullptr;
237 int n = sd_get_uids(&uids);
242 for (i = 0; i < n; i++) {
243 switch (request_mode_) {
244 case RequestMode::GLOBAL:
245 // if user pkg is installed, installer will not send signal to user.
246 if (QueryIsPackageInstalled(pkgid, RequestMode::USER, uids[i]))
249 user_list_.emplace_back(uids[i], request_type_);
251 case RequestMode::USER:
254 // if global pkg is installed,
255 // user pkg operation will be handled as update.
256 if (QueryIsPackageInstalled(pkgid, kGlobalUserUid))
257 user_list_.emplace_back(uids[i], RequestType::Update);
259 user_list_.emplace_back(uids[i], request_type_);
262 user_list_.emplace_back(uids[i], request_type_);
273 } // namespace common_installer