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/utils/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_UNINSTALL_EVENT_STR},
28 {ci::RequestType::RecoveryUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
29 {ci::RequestType::Reinstall, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
30 {ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
31 {ci::RequestType::PartialUninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
32 {ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
33 {ci::RequestType::ReadonlyUpdateInstall, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
34 {ci::RequestType::ReadonlyUpdateUninstall,
35 PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
36 {ci::RequestType::Delta, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
37 {ci::RequestType::Move, PKGMGR_INSTALLER_MOVE_EVENT_STR},
38 {ci::RequestType::MountInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
39 {ci::RequestType::MountUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
40 {ci::RequestType::ManifestDirectInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
41 {ci::RequestType::ManifestDirectUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
42 {ci::RequestType::ManifestPartialInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
43 {ci::RequestType::ManifestPartialUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
44 {ci::RequestType::DisablePkg, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
45 {ci::RequestType::EnablePkg, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
46 {ci::RequestType::MigrateExtImg, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
47 {ci::RequestType::Unknown, PKGMGR_INSTALLER_UNKNOWN_EVENT_STR}
52 namespace common_installer {
55 PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi)
56 : pi_(pi), state_(State::NOT_SENT), request_type_(RequestType::Unknown),
57 error_message_sent_(false), is_upgrade_(false) {
58 uid_ = pkgmgr_installer_get_uid(pi_);
59 request_mode_ = GetRequestMode(uid_);
62 bool PkgmgrSignal::SendStarted(
63 const std::string& type, const std::string& pkgid) {
64 if (state_ != State::NOT_SENT)
67 if (!SetupUserList(pkgid))
68 LOG(WARNING) << "Failed to setup user list";
70 auto key = kEventStr.find(request_type_);
71 if (key == kEventStr.end())
74 if (strcmp(key->second, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
77 pkgmgr_installer_set_is_upgrade(pi_, is_upgrade_ ? 1 : 0);
79 if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, key->second, type, pkgid))
82 for (auto l : user_list_) {
83 key = kEventStr.find(l.second);
84 if (key == kEventStr.end())
86 SendSignal(l.first, PKGMGR_INSTALLER_START_KEY_STR, key->second, type,
90 state_ = State::STARTED;
92 // workaround for pkgmgr client to know all appids which are uninstalled
93 if (request_type_ == ci::RequestType::Uninstall) {
94 if (!SendAppids(type, pkgid))
96 for (auto l : user_list_)
97 SendAppids(l.first, type, pkgid);
103 bool PkgmgrSignal::SendProgress(int progress,
104 const std::string& type, const std::string& pkgid) {
105 if (state_ != State::STARTED)
108 if (!SendSignal(PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
109 std::to_string(progress).c_str(), type, pkgid))
111 for (auto l : user_list_) {
113 SendSignal(l.first, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
114 std::to_string(progress).c_str(), type, pkgid);
120 bool PkgmgrSignal::SendFinished(
121 Step::Status result, const std::string& type, const std::string& pkgid) {
122 if (state_ != State::STARTED)
125 pkgmgr_installer_set_is_upgrade(pi_, is_upgrade_ ? 1 : 0);
127 if (result != Step::Status::OK && !error_message_sent_) {
129 PKGMGR_INSTALLER_ERROR_KEY_STR,
130 std::to_string(static_cast<int>(result)).c_str(), type, pkgid))
133 for (auto l : user_list_)
135 PKGMGR_INSTALLER_ERROR_KEY_STR,
136 std::to_string(static_cast<int>(result)).c_str(), type, pkgid);
139 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid))
142 for (auto l : user_list_)
144 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid);
145 state_ = State::FINISHED;
149 bool PkgmgrSignal::SendError(
151 const std::string& error_message,
152 const std::string& type,
153 const std::string& pkgid) {
154 if (state_ != State::STARTED)
157 pkgmgr_installer_set_is_upgrade(pi_, is_upgrade_ ? 1 : 0);
159 std::string error_value = std::to_string(static_cast<int>(result));
160 if (!error_message.empty())
161 error_value = error_value + ":" + error_message;
163 LOG(ERROR) << "PkgmgrSignal error_value: (" << error_value << ")";
164 error_message_sent_ = true;
166 PKGMGR_INSTALLER_ERROR_KEY_STR,
171 for (auto l : user_list_)
173 PKGMGR_INSTALLER_ERROR_KEY_STR,
180 void PkgmgrSignal::SetRequestType(RequestType req_type) {
181 request_type_ = req_type;
184 bool PkgmgrSignal::SendSignal(
187 const std::string& type,
188 const std::string& pkgid) const {
189 // send pkgmgr signal
190 if (pkgmgr_installer_send_signal(
192 !type.empty() ? type.c_str(): "",
193 !pkgid.empty() ? pkgid.c_str() : "",
196 LOG(ERROR) << "Fail to send pkgmgr signal";
200 LOG(DEBUG) << "Success to send pkgmgr signal"
201 << " PKGID=" << pkgid
203 << " VALUE=" << value;
207 bool PkgmgrSignal::SendSignal(
211 const std::string& type,
212 const std::string& pkgid) const {
213 // send pkgmgr signal
214 if (pkgmgr_installer_send_signal_for_uid(
217 !type.empty() ? type.c_str(): "",
218 !pkgid.empty() ? pkgid.c_str() : "",
221 LOG(ERROR) << "Fail to send pkgmgr signal";
225 LOG(DEBUG) << "Success to send pkgmgr signal"
227 << " PKGID=" << pkgid
229 << " VALUE=" << value;
233 const char* PkgmgrSignal::GetResultKey(Step::Status result) const {
235 case Step::Status::OK:
236 return PKGMGR_INSTALLER_OK_EVENT_STR;
238 return PKGMGR_INSTALLER_FAIL_EVENT_STR;
242 bool PkgmgrSignal::SendAppids(const std::string& type,
243 const std::string& pkgid) const {
244 std::vector<std::string> appids;
245 ci::PkgQueryInterface pkg_query(pkgid, pkgmgr_installer_get_uid(pi_));
246 if (!pkg_query.AppidsForPkgId(&appids))
248 for (auto& appid : appids) {
249 if (pkgmgr_installer_send_app_uninstall_signal(pi_, type.c_str(),
257 bool PkgmgrSignal::SendAppids(uid_t uid,
258 const std::string& type,
259 const std::string& pkgid) const {
260 std::vector<std::string> appids;
261 ci::PkgQueryInterface pkg_query(pkgid, pkgmgr_installer_get_uid(pi_));
262 if (!pkg_query.AppidsForPkgId(&appids))
264 for (auto& appid : appids) {
265 if (pkgmgr_installer_send_app_uninstall_signal_for_uid(
266 pi_, uid, type.c_str(), pkgid.c_str(), appid.c_str()))
272 bool PkgmgrSignal::SetupUserList(const std::string& pkgid) {
273 uid_t* uids = nullptr;
274 int n = sd_get_uids(&uids);
278 ci::PkgQueryInterface pkg_query_for_global(pkgid, kGlobalUserUid);
279 for (int i = 0; i < n; i++) {
280 ci::PkgQueryInterface pkg_query(pkgid, uids[i]);
281 switch (request_mode_) {
282 case RequestMode::GLOBAL:
283 // if user pkg is installed, installer will not send signal to user.
284 if (pkg_query.IsPackageInstalled(ci::RequestMode::USER))
287 user_list_.emplace_back(uids[i], request_type_);
289 case RequestMode::USER:
292 user_list_.emplace_back(uids[i], request_type_);
295 user_list_.emplace_back(uids[i], request_type_);
306 } // namespace common_installer