1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/pkgmgr_interface.h"
7 #include <boost/filesystem/path.hpp>
8 #include <boost/filesystem.hpp>
10 #include <tzplatform_config.h>
16 #include "common/app_query_interface.h"
17 #include "common/utils/pkgmgr_query.h"
18 #include "common/pkgmgr_signal.h"
19 #include "common/pkgmgr_registration.h"
20 #include "common/utils/file_util.h"
21 #include "common/utils/manifest_util.h"
22 #include "common/utils/user_util.h"
24 namespace bf = boost::filesystem;
25 namespace ci = common_installer;
29 const char kDeltaFileExtension[] = ".delta";
30 const char kDeltaFileName[] = "delta_info.xml";
31 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
33 bool CheckIfAppFilesExists(const std::string& pkgid,
36 return bf::exists(ci::GetManifestLocation(pkgid,
40 bool IsDeltaPkg(const std::string& path) {
41 bool is_delta = false;
42 if (!ci::CheckPathInZipArchive(path.c_str(), kDeltaFileName, &is_delta)) {
43 LOG(ERROR) << "Failed to check delta package";
48 std::string extension = bf::path(path).extension().string();
49 if (extension == kDeltaFileExtension)
58 namespace common_installer {
60 bool PkgmgrInstaller::CreatePkgMgrInstaller(pkgmgr_installer** installer,
61 InstallationMode* mode) {
62 *installer = pkgmgr_installer_new();
64 LOG(WARNING) << "Cannot create pkgmgr_installer object. Will try offline";
65 // We assume offline mode if we cannot connect to pkgmgr-server
66 *installer = pkgmgr_installer_offline_new();
70 *mode = InstallationMode::OFFLINE;
72 *mode = InstallationMode::ONLINE;
77 bool PkgmgrInstaller::ShouldCreateSignal() const {
81 PkgMgrPtr PkgMgrInterface::Create(int argc, char** argv,
82 PkgmgrInstallerInterface* pkgmgr_installer_interface,
83 std::shared_ptr<AppQueryInterface> interface) {
84 PkgMgrPtr instance(new PkgMgrInterface(pkgmgr_installer_interface,
86 int result = instance->InitInternal(argc, argv);
93 int PkgMgrInterface::InitInternal(int argc, char** argv) {
94 if (!pkgmgr_installer_interface_->CreatePkgMgrInstaller(&pi_,
96 LOG(ERROR) << "Cannot create pkgmgr_installer object. Aborting.";
100 int result = pkgmgr_installer_receive_request(pi_, argc, argv);
102 LOG(ERROR) << "Cannot receive request. Invalid arguments?";
103 // no need to free pkgmgr_installer here. it will be freed in DTOR.
107 boost::optional<bool> is_admin_user =
108 IsAdminUser(pkgmgr_installer_get_uid(pi_));
109 if (!is_admin_user) {
110 LOG(ERROR) << "Cannot get admin user info. Aborting.";
114 // Set target uid as tizenglobalapp if admin user's request
115 if (*is_admin_user) {
116 result = pkgmgr_installer_set_uid(pi_, kGlobalUserUid);
118 LOG(ERROR) << "Failed to set global uid";
126 PkgMgrInterface::~PkgMgrInterface() {
128 pkgmgr_installer_free(pi_);
132 bool PkgMgrInterface::SetAppQueryInterface(int idx) {
133 // reset this flag to processing new package
134 is_app_installed_ = boost::none;
136 auto it = query_interface_map_.find(idx);
137 if (it == query_interface_map_.end()) {
138 if (!query_interface_) {
139 LOG(ERROR) << "Cannot find query interface for index(" << idx << ")";
142 // using legacy query interface (for single pkg installer)
146 query_interface_ = it->second;
150 void PkgMgrInterface::AddAppQueryInterface(
151 int idx, std::shared_ptr<AppQueryInterface> interface) {
152 query_interface_map_.emplace(idx, interface);
155 RequestType PkgMgrInterface::GetRequestType(int idx) const {
156 // These type could be determined even if there are no query_interface_.
157 switch (pkgmgr_installer_get_request_type(pi_)) {
158 case PKGMGR_REQ_DISABLE_PKG:
159 return RequestType::DisablePkg;
160 case PKGMGR_REQ_ENABLE_PKG:
161 return RequestType::EnablePkg;
162 case PKGMGR_REQ_MIGRATE_EXTIMG:
163 return RequestType::MigrateExtImg;
164 case PKGMGR_REQ_RECOVER_DB:
165 return RequestType::RecoverDB;
166 case PKGMGR_REQ_REINSTALL:
167 return RequestType::Reinstall;
168 case PKGMGR_REQ_RECOVER:
169 return RequestType::Recovery;
170 case PKGMGR_REQ_MOVE:
171 return RequestType::Move;
174 std::shared_ptr<AppQueryInterface> query_interface = query_interface_;
175 if (!query_interface) {
176 auto it = query_interface_map_.find(idx);
177 if (it == query_interface_map_.end())
178 return RequestType::Unknown;
179 query_interface = it->second;
182 if (!is_app_installed_) {
184 query_interface->IsPkgInstalled(GetRequestInfo(idx), GetUid());
186 switch (pkgmgr_installer_get_request_type(pi_)) {
187 case PKGMGR_REQ_UPGRADE :
188 case PKGMGR_REQ_INSTALL : {
189 auto request_info = GetRequestInfo(idx);
190 if (request_info.empty())
191 return RequestType::Unknown;
192 bool is_delta = IsDeltaPkg(request_info);
193 if (!is_app_installed_.get()) {
195 LOG(ERROR) << "Package is not installed. "
196 "Cannot update from delta package";
197 return RequestType::Unknown;
199 return RequestType::Install;
203 return RequestType::Delta;
205 std::string pkgid = query_interface->GetPkgId(GetRequestInfo(idx));
206 uid_t uid = GetUid();
207 ci::PkgQueryInterface pkg_query(pkgid, uid);
208 if (!GetIsPreloadRequest() &&
209 pkg_query.IsReadonlyPackage() &&
210 !pkg_query.IsUpdatedPackage()) {
211 return RequestType::ReadonlyUpdateInstall;
212 } else if (CheckIfAppFilesExists(pkgid, uid,
213 pkg_query.IsReadonlyPackage())
215 return RequestType::Update;
217 RequestMode request_mode = GetRequestMode(uid);
218 UnregisterAppInPkgmgrForPkgId(pkgid, uid, request_mode);
219 return RequestType::Install;
224 case PKGMGR_REQ_UNINSTALL: {
225 std::string pkgid = GetRequestInfo(idx);
226 uid_t uid = GetUid();
227 ci::PkgQueryInterface pkg_query(pkgid, uid);
228 if (pkg_query.IsSystemPackage() &&
229 pkg_query.IsUpdatedPackage() &&
230 pkg_query.IsRemovablePackage())
231 return RequestType::ReadonlyUpdateUninstall;
232 else if (GetIsPreloadRequest() && GetIsPartialRW())
233 return RequestType::PartialUninstall;
235 return RequestType::Uninstall;
237 case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
238 if (!is_app_installed_.get()) {
239 if (GetIsPreloadRequest() && GetIsPartialRW())
240 return RequestType::ManifestPartialInstall;
242 return RequestType::ManifestDirectInstall;
244 if (GetIsPreloadRequest() && GetIsPartialRW())
245 return RequestType::ManifestPartialUpdate;
247 return RequestType::ManifestDirectUpdate;
249 case PKGMGR_REQ_MOUNT_INSTALL: {
250 if (!is_app_installed_.get()) {
251 return RequestType::MountInstall;
253 std::string pkgid = query_interface->GetPkgId(GetRequestInfo(idx));
254 uid_t uid = GetUid();
255 ci::PkgQueryInterface pkg_query(pkgid, uid);
256 if (CheckIfAppFilesExists(pkgid, uid, pkg_query.IsReadonlyPackage())) {
257 return RequestType::MountUpdate;
259 RequestMode request_mode = GetRequestMode(uid);
260 UnregisterAppInPkgmgrForPkgId(pkgid, uid, request_mode);
261 return RequestType::MountInstall;
266 return RequestType::Unknown;
270 uid_t PkgMgrInterface::GetUid() const {
271 return pkgmgr_installer_get_uid(pi_);
274 std::string PkgMgrInterface::GetRequestInfo(int idx) const {
275 const char* request_info = pkgmgr_installer_get_request_info_at(pi_, idx);
282 boost::filesystem::path PkgMgrInterface::GetTepPath() const {
283 if (pkgmgr_installer_get_tep_path(pi_) == nullptr)
284 return boost::filesystem::path("");
286 return boost::filesystem::path(pkgmgr_installer_get_tep_path(pi_));
289 bool PkgMgrInterface::GetIsTepMove() const {
290 return (pkgmgr_installer_get_tep_move_type(pi_) == 1);
293 bool PkgMgrInterface::GetIsMoveToExternal() const {
294 return (pkgmgr_installer_get_move_type(pi_) == 1);
297 int PkgMgrInterface::GetMoveType() const {
298 return pkgmgr_installer_get_move_type(pi_);
301 bool PkgMgrInterface::GetIsPreloadRequest() const {
302 return (pkgmgr_installer_get_is_preload(pi_) == 1);
305 bool PkgMgrInterface::GetIsPreloadRWRequest() const {
306 return (pkgmgr_installer_get_is_preload_rw(pi_) == 1);
309 bool PkgMgrInterface::GetIsKeepRWData() const {
310 return (pkgmgr_installer_get_keep_rwdata(pi_) == 1);
313 bool PkgMgrInterface::GetIsPartialRW() const {
314 return (pkgmgr_installer_get_partial_rw(pi_) == 1);
317 std::unique_ptr<PkgmgrSignal> PkgMgrInterface::CreatePkgmgrSignal() const {
318 if (!pkgmgr_installer_interface_->ShouldCreateSignal())
320 return std::unique_ptr<PkgmgrSignal>(new PkgmgrSignal(pi_));
323 bool PkgMgrInterface::GetIsForceRemoval() const {
324 return (pkgmgr_installer_get_force_removal(pi_) == 1);
327 bool PkgMgrInterface::GetIsNoRemoval() const {
328 return (pkgmgr_installer_get_no_removal(pi_) == 1);
331 bool PkgMgrInterface::GetDebugMode() const {
332 return (pkgmgr_installer_get_debug_mode(pi_) == 1);
335 bool PkgMgrInterface::GetIsSkipCheckReference() const {
336 return (pkgmgr_installer_get_skip_check_reference(pi_) == 1);
339 bool PkgMgrInterface::GetSkipOptimization() const {
340 return (pkgmgr_installer_get_skip_optimization(pi_) == 1);
343 int PkgMgrInterface::GetRequestInfoCount() const {
344 return pkgmgr_installer_get_request_info_count(pi_);
347 bool PkgMgrInterface::GetRecoveryCleanup() const {
348 return (pkgmgr_installer_get_recovery_cleanup(pi_) == 1);
351 } // namespace common_installer