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 <bundle_cpp.h>
12 #include <sys/types.h>
13 #include <systemd/sd-login.h>
14 #include <tzplatform_config.h>
20 #include "common/utils/pkgmgr_query.h"
24 namespace ci = common_installer;
26 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
27 const std::map<ci::RequestType, const char*> kEventStr = {
28 {ci::RequestType::Install, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
29 {ci::RequestType::Recovery, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
30 {ci::RequestType::RecoveryUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
31 {ci::RequestType::Reinstall, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
32 {ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
33 {ci::RequestType::PartialUninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
34 {ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
35 {ci::RequestType::ReadonlyUpdateInstall, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
36 {ci::RequestType::ReadonlyUpdateUninstall,
37 PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
38 {ci::RequestType::Delta, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
39 {ci::RequestType::Move, PKGMGR_INSTALLER_MOVE_EVENT_STR},
40 {ci::RequestType::MountInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
41 {ci::RequestType::MountUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
42 {ci::RequestType::ManifestDirectInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
43 {ci::RequestType::ManifestDirectUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
44 {ci::RequestType::ManifestPartialInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
45 {ci::RequestType::ManifestPartialUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
46 {ci::RequestType::DisablePkg, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
47 {ci::RequestType::EnablePkg, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
48 {ci::RequestType::MigrateExtImg, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
49 {ci::RequestType::Unknown, PKGMGR_INSTALLER_UNKNOWN_EVENT_STR}
54 namespace common_installer {
57 PkgmgrSignal::PkgmgrSignal(pkgmgr_installer* pi)
58 : pi_(pi), state_(State::NOT_SENT), request_type_(RequestType::Unknown),
59 error_message_sent_(false), is_upgrade_(false) {
60 uid_ = pkgmgr_installer_get_uid(pi_);
61 request_mode_ = GetRequestMode(uid_);
64 bool PkgmgrSignal::SendStarted(
65 const std::string& type, const std::string& pkgid) {
66 if (state_ != State::NOT_SENT)
69 if (!SetupUserList(pkgid))
70 LOG(WARNING) << "Failed to setup user list";
72 auto key = kEventStr.find(request_type_);
73 if (key == kEventStr.end())
76 if (strcmp(key->second, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
79 pkgmgr_installer_set_is_upgrade(pi_, is_upgrade_ ? 1 : 0);
81 if (!SendSignal(PKGMGR_INSTALLER_START_KEY_STR, key->second, type, pkgid))
84 for (auto l : user_list_) {
85 key = kEventStr.find(l.second);
86 if (key == kEventStr.end())
88 SendSignal(l.first, PKGMGR_INSTALLER_START_KEY_STR, key->second, type,
92 state_ = State::STARTED;
94 // workaround for pkgmgr client to know all appids which are uninstalled
95 if (request_type_ == ci::RequestType::Uninstall) {
96 if (!SendAppids(type, pkgid))
98 for (const auto& l : user_list_)
99 SendAppids(l.first, type, pkgid);
105 bool PkgmgrSignal::SendProgress(int progress,
106 const std::string& type, const std::string& pkgid) {
107 if (state_ != State::STARTED)
110 if (!SendSignal(PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
111 std::to_string(progress).c_str(), type, pkgid))
113 for (const auto& l : user_list_) {
115 SendSignal(l.first, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
116 std::to_string(progress).c_str(), type, pkgid);
122 bool PkgmgrSignal::SendFinished(
123 Step::Status result, const std::string& type, const std::string& pkgid) {
124 if (state_ != State::STARTED)
127 pkgmgr_installer_set_is_upgrade(pi_, is_upgrade_ ? 1 : 0);
129 if (result != Step::Status::OK && !error_message_sent_) {
131 PKGMGR_INSTALLER_ERROR_KEY_STR,
132 std::to_string(static_cast<int>(result)).c_str(), type, pkgid))
135 for (auto l : user_list_)
137 PKGMGR_INSTALLER_ERROR_KEY_STR,
138 std::to_string(static_cast<int>(result)).c_str(), type, pkgid);
142 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid))
145 for (const auto& l : user_list_)
147 PKGMGR_INSTALLER_END_KEY_STR, GetResultKey(result), type, pkgid);
149 state_ = State::FINISHED;
153 bool PkgmgrSignal::SendError(
155 const std::string& error_message,
156 const std::string& type,
157 const std::string& pkgid) {
158 if (state_ != State::STARTED)
161 pkgmgr_installer_set_is_upgrade(pi_, is_upgrade_ ? 1 : 0);
163 std::string error_value = std::to_string(static_cast<int>(result));
164 if (!error_message.empty())
165 error_value = error_value + ":" + error_message;
167 LOG(ERROR) << "PkgmgrSignal error_value: (" << error_value << ")";
168 error_message_sent_ = true;
170 PKGMGR_INSTALLER_ERROR_KEY_STR,
175 for (const auto& l : user_list_)
177 PKGMGR_INSTALLER_ERROR_KEY_STR,
184 void PkgmgrSignal::SetRequestType(RequestType req_type) {
185 request_type_ = req_type;
188 bool PkgmgrSignal::SendSignal(
191 const std::string& type,
192 const std::string& pkgid) const {
193 if (!strcmp(key, "start") || !strcmp(key, "error") || !strcmp(key, "end")) {
194 uid_t uid = pkgmgr_installer_get_uid(pi_);
195 tizen_base::Bundle b({
196 { AUL_K_PKGID, pkgid },
197 { AUL_K_PACKAGETYPE, type },
198 { AUL_K_PKG_EVENT_NAME, key },
199 { AUL_K_PKG_EVENT_RESULT, value }
202 if (aul_package_pre_event_send(uid, b.GetHandle()) != AUL_R_OK)
203 LOG(ERROR) << "aul_package_pre_event_send() is failed";
206 // send pkgmgr signal
207 if (pkgmgr_installer_send_signal(
209 !type.empty() ? type.c_str(): "",
210 !pkgid.empty() ? pkgid.c_str() : "",
213 LOG(ERROR) << "Fail to send pkgmgr signal";
217 LOG(DEBUG) << "Success to send pkgmgr signal"
218 << " PKGID=" << pkgid
220 << " VALUE=" << value;
224 bool PkgmgrSignal::SendSignal(
228 const std::string& type,
229 const std::string& pkgid) const {
230 // send pkgmgr signal
231 if (pkgmgr_installer_send_signal_for_uid(
234 !type.empty() ? type.c_str(): "",
235 !pkgid.empty() ? pkgid.c_str() : "",
238 LOG(ERROR) << "Fail to send pkgmgr signal";
242 LOG(DEBUG) << "Success to send pkgmgr signal"
244 << " PKGID=" << pkgid
246 << " VALUE=" << value;
250 const char* PkgmgrSignal::GetResultKey(Step::Status result) const {
252 case Step::Status::OK:
253 return PKGMGR_INSTALLER_OK_EVENT_STR;
255 return PKGMGR_INSTALLER_FAIL_EVENT_STR;
259 bool PkgmgrSignal::SendAppids(const std::string& type,
260 const std::string& pkgid) const {
261 std::vector<std::string> appids;
262 ci::PkgQueryInterface pkg_query(pkgid, pkgmgr_installer_get_uid(pi_));
263 if (!pkg_query.AppidsForPkgId(&appids))
265 for (auto& appid : appids) {
266 if (pkgmgr_installer_send_app_uninstall_signal(pi_, type.c_str(),
274 bool PkgmgrSignal::SendAppids(uid_t uid,
275 const std::string& type,
276 const std::string& pkgid) const {
277 std::vector<std::string> appids;
278 ci::PkgQueryInterface pkg_query(pkgid, pkgmgr_installer_get_uid(pi_));
279 if (!pkg_query.AppidsForPkgId(&appids))
281 for (auto& appid : appids) {
282 if (pkgmgr_installer_send_app_uninstall_signal_for_uid(
283 pi_, uid, type.c_str(), pkgid.c_str(), appid.c_str()))
289 bool PkgmgrSignal::SetupUserList(const std::string& pkgid) {
290 uid_t* uids = nullptr;
291 int n = sd_get_uids(&uids);
295 ci::PkgQueryInterface pkg_query_for_global(pkgid, kGlobalUserUid);
296 for (int i = 0; i < n; i++) {
297 ci::PkgQueryInterface pkg_query(pkgid, uids[i]);
298 switch (request_mode_) {
299 case RequestMode::GLOBAL:
300 // if user pkg is installed, installer will not send signal to user.
301 if (pkg_query.IsPackageInstalled(ci::RequestMode::USER))
304 user_list_.emplace_back(uids[i], request_type_);
306 case RequestMode::USER:
309 user_list_.emplace_back(uids[i], request_type_);
312 user_list_.emplace_back(uids[i], request_type_);
323 } // namespace common_installer