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_UPGRADE_EVENT_STR},
29 {ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
30 {ci::RequestType::PartialUninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
31 {ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
32 {ci::RequestType::ReadonlyUpdateInstall, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
33 {ci::RequestType::ReadonlyUpdateUninstall,
34 PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
35 {ci::RequestType::Delta, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
36 {ci::RequestType::Move, PKGMGR_INSTALLER_MOVE_EVENT_STR},
37 {ci::RequestType::MountInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
38 {ci::RequestType::MountUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
39 {ci::RequestType::ManifestDirectInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
40 {ci::RequestType::ManifestDirectUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
41 {ci::RequestType::ManifestPartialInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
42 {ci::RequestType::ManifestPartialUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
43 {ci::RequestType::DisablePkg, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
44 {ci::RequestType::EnablePkg, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
45 {ci::RequestType::MigrateExtImg, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
46 {ci::RequestType::Unknown, PKGMGR_INSTALLER_UNKNOWN_EVENT_STR}
51 namespace common_installer {
53 PkgmgrSignal::State PkgmgrSignal::state_ = PkgmgrSignal::State::NOT_SENT;
55 PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi, RequestType req_type)
56 : pi_(pi), request_type_(req_type), error_message_sent_(false) {
57 uid_ = pkgmgr_installer_get_uid(pi_);
58 request_mode_ = GetRequestMode(uid_);
61 bool PkgmgrSignal::SendStarted(
62 const std::string& type, const std::string& pkgid,
63 const RecoveryInfo& recovery_info) {
64 if (state_ != State::NOT_SENT) {
68 if (!SetupUserList(pkgid))
69 LOG(WARNING) << "Failed to setup user list";
71 auto key = kEventStr.find(request_type_);
72 if (key == kEventStr.end()) {
76 if (request_type_ == ci::RequestType::Recovery) {
77 value = GetRecoverySignalValue(recovery_info.recovery_file->type());
84 if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, value, type, pkgid)) {
87 for (auto l : user_list_) {
88 key = kEventStr.find(l.second);
89 if (key == kEventStr.end())
91 SendSignal(l.first, PKGMGR_INSTALLER_START_KEY_STR, value, type,
95 state_ = State::STARTED;
97 // workaround for pkgmgr client to know all appids which are uninstalled
98 if (request_type_ == ci::RequestType::Uninstall) {
99 if (!SendAppids(type, pkgid))
101 for (auto l : user_list_)
102 SendAppids(l.first, type, pkgid);
108 const char* PkgmgrSignal::GetRecoverySignalValue(RequestType recovery_type) {
109 switch (recovery_type) {
110 case RequestType::Install:
111 case RequestType::Uninstall:
112 case RequestType::MountInstall:
113 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
114 case RequestType::Update:
115 case RequestType::Reinstall:
116 case RequestType::Delta:
117 case RequestType::MountUpdate:
118 case RequestType::ReadonlyUpdateInstall:
119 return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
121 LOG(ERROR) << "Unsupported request type for recovery";
126 bool PkgmgrSignal::SendProgress(int progress,
127 const std::string& type, const std::string& pkgid) {
128 if (state_ != State::STARTED) {
132 if (!SendSignal(PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
133 std::to_string(progress).c_str(), type, pkgid))
135 for (auto l : user_list_)
137 SendSignal(l.first, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
138 std::to_string(progress).c_str(), type, pkgid);
143 bool PkgmgrSignal::SendFinished(
144 Step::Status result, const std::string& type, const std::string& pkgid) {
145 if (state_ != State::STARTED) {
148 if (result != Step::Status::OK && !error_message_sent_) {
150 PKGMGR_INSTALLER_ERROR_KEY_STR,
151 std::to_string(static_cast<int>(result)).c_str(), type, pkgid)) {
154 for (auto l : user_list_)
156 PKGMGR_INSTALLER_ERROR_KEY_STR,
157 std::to_string(static_cast<int>(result)).c_str(), type, pkgid);
160 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid)) {
163 for (auto l : user_list_)
165 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid);
166 state_ = State::FINISHED;
170 bool PkgmgrSignal::SendError(
172 const std::string& error_message,
173 const std::string& type,
174 const std::string& pkgid) {
175 if (state_ != State::STARTED) {
178 std::string error_value = std::to_string(static_cast<int>(result));
179 if (!error_message.empty()) {
180 error_value = error_value + ":" + error_message;
182 LOG(ERROR) << "PkgmgrSignal error_value: (" << error_value << ")";
183 error_message_sent_ = true;
185 PKGMGR_INSTALLER_ERROR_KEY_STR,
190 for (auto l : user_list_)
192 PKGMGR_INSTALLER_ERROR_KEY_STR,
199 bool PkgmgrSignal::SendSignal(
202 const std::string& type,
203 const std::string& pkgid) const {
204 // send pkgmgr signal
205 if (pkgmgr_installer_send_signal(
207 !type.empty() ? type.c_str(): "",
208 !pkgid.empty() ? pkgid.c_str() : "",
211 LOG(ERROR) << "Fail to send pkgmgr signal";
215 LOG(DEBUG) << "Success to send pkgmgr signal"
216 << " PKGID=" << pkgid
218 << " VALUE=" << value;
222 bool PkgmgrSignal::SendSignal(
226 const std::string& type,
227 const std::string& pkgid) const {
228 // send pkgmgr signal
229 if (pkgmgr_installer_send_signal_for_uid(
232 !type.empty() ? type.c_str(): "",
233 !pkgid.empty() ? pkgid.c_str() : "",
236 LOG(ERROR) << "Fail to send pkgmgr signal";
240 LOG(DEBUG) << "Success to send pkgmgr signal"
242 << " PKGID=" << pkgid
244 << " VALUE=" << value;
248 const char* PkgmgrSignal::GetResultKey(Step::Status result) const {
250 case Step::Status::OK:
251 return PKGMGR_INSTALLER_OK_EVENT_STR;
253 return PKGMGR_INSTALLER_FAIL_EVENT_STR;
257 bool PkgmgrSignal::SendAppids(const std::string& type,
258 const std::string& pkgid) const {
259 std::vector<std::string> appids;
260 ci::PkgQueryInterface pkg_query(pkgid, pkgmgr_installer_get_uid(pi_));
261 if (!pkg_query.AppidsForPkgId(&appids))
263 for (auto& appid : appids) {
264 if (pkgmgr_installer_send_app_uninstall_signal(pi_, type.c_str(),
272 bool PkgmgrSignal::SendAppids(uid_t uid,
273 const std::string& type,
274 const std::string& pkgid) const {
275 std::vector<std::string> appids;
276 ci::PkgQueryInterface pkg_query(pkgid, pkgmgr_installer_get_uid(pi_));
277 if (!pkg_query.AppidsForPkgId(&appids))
279 for (auto& appid : appids) {
280 if (pkgmgr_installer_send_app_uninstall_signal_for_uid(
281 pi_, uid, type.c_str(), pkgid.c_str(), appid.c_str()))
287 bool PkgmgrSignal::SetupUserList(const std::string& pkgid) {
289 uid_t* uids = nullptr;
290 int n = sd_get_uids(&uids);
294 ci::PkgQueryInterface pkg_query_for_global(pkgid, kGlobalUserUid);
295 for (i = 0; i < n; i++) {
296 ci::PkgQueryInterface pkg_query(pkgid, uids[i]);
297 switch (request_mode_) {
298 case RequestMode::GLOBAL:
299 // if user pkg is installed, installer will not send signal to user.
300 if (pkg_query.IsPackageInstalled(ci::RequestMode::USER))
303 user_list_.emplace_back(uids[i], request_type_);
305 case RequestMode::USER:
308 // if global pkg is installed,
309 // user pkg operation will be handled as update.
310 if (pkg_query_for_global.IsPackageInstalled(ci::RequestMode::GLOBAL))
311 user_list_.emplace_back(uids[i], RequestType::Update);
313 user_list_.emplace_back(uids[i], request_type_);
316 user_list_.emplace_back(uids[i], request_type_);
327 } // namespace common_installer