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 <tzplatform_config.h>
15 #include "common/app_query_interface.h"
16 #include "common/utils/pkgmgr_query.h"
17 #include "common/pkgmgr_signal.h"
18 #include "common/pkgmgr_registration.h"
19 #include "common/utils/file_util.h"
20 #include "common/utils/manifest_util.h"
21 #include "common/utils/user_util.h"
23 namespace fs = std::filesystem;
24 namespace ci = common_installer;
28 const char kDeltaFileExtension[] = ".delta";
29 const char kDeltaFileName[] = "delta_info.xml";
30 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
32 bool CheckIfAppFilesExists(const std::string& pkgid,
35 return fs::exists(ci::GetManifestLocation(pkgid,
39 bool IsDeltaPkg(const std::string& path) {
40 bool is_delta = false;
41 if (!ci::CheckPathInZipArchive(path.c_str(), kDeltaFileName, &is_delta)) {
42 LOG(ERROR) << "Failed to check delta package";
47 std::string extension = fs::path(path).extension().string();
48 if (extension == kDeltaFileExtension)
57 namespace common_installer {
59 bool PkgmgrInstaller::CreatePkgMgrInstaller(pkgmgr_installer** installer,
60 InstallationMode* mode) {
61 *installer = pkgmgr_installer_new();
63 LOG(WARNING) << "Cannot create pkgmgr_installer object. Will try offline";
64 // We assume offline mode if we cannot connect to pkgmgr-server
65 *installer = pkgmgr_installer_offline_new();
69 *mode = InstallationMode::OFFLINE;
71 *mode = InstallationMode::ONLINE;
76 bool PkgmgrInstaller::ShouldCreateSignal() const {
80 PkgMgrPtr PkgMgrInterface::Create(int argc, char** argv,
81 PkgmgrInstallerInterface* pkgmgr_installer_interface,
82 std::shared_ptr<AppQueryInterface> interface) {
83 PkgMgrPtr instance(new PkgMgrInterface(pkgmgr_installer_interface,
85 int result = instance->InitInternal(argc, argv);
92 int PkgMgrInterface::InitInternal(int argc, char** argv) {
93 if (!pkgmgr_installer_interface_->CreatePkgMgrInstaller(&pi_,
95 LOG(ERROR) << "Cannot create pkgmgr_installer object. Aborting.";
99 int result = pkgmgr_installer_receive_request(pi_, argc, argv);
101 LOG(ERROR) << "Cannot receive request. Invalid arguments?";
102 // no need to free pkgmgr_installer here. it will be freed in DTOR.
106 std::optional<bool> is_admin_user =
107 IsAdminUser(pkgmgr_installer_get_uid(pi_));
108 if (!is_admin_user) {
109 LOG(ERROR) << "Cannot get admin user info. Aborting.";
113 // Set target uid as tizenglobalapp if admin user's request
114 if (*is_admin_user) {
115 result = pkgmgr_installer_set_uid(pi_, kGlobalUserUid);
117 LOG(ERROR) << "Failed to set global uid";
125 PkgMgrInterface::~PkgMgrInterface() {
127 pkgmgr_installer_free(pi_);
131 bool PkgMgrInterface::SetAppQueryInterface(int idx) {
132 // reset this flag to processing new package
133 is_app_installed_.reset();
135 auto it = query_interface_map_.find(idx);
136 if (it == query_interface_map_.end()) {
137 if (!query_interface_) {
138 LOG(ERROR) << "Cannot find query interface for index(" << idx << ")";
141 // using legacy query interface (for single pkg installer)
145 query_interface_ = it->second;
149 void PkgMgrInterface::AddAppQueryInterface(
150 int idx, std::shared_ptr<AppQueryInterface> interface) {
151 query_interface_map_.emplace(idx, interface);
154 std::shared_ptr<AppQueryInterface> PkgMgrInterface::GetAppQueryInterface() {
155 return query_interface_;
158 RequestType PkgMgrInterface::GetRequestType(int idx) const {
159 // These type could be determined even if there are no query_interface_.
160 switch (pkgmgr_installer_get_request_type(pi_)) {
161 case PKGMGR_REQ_DISABLE_PKG:
162 return RequestType::DisablePkg;
163 case PKGMGR_REQ_ENABLE_PKG:
164 return RequestType::EnablePkg;
165 case PKGMGR_REQ_MIGRATE_EXTIMG:
166 return RequestType::MigrateExtImg;
167 case PKGMGR_REQ_RECOVER_DB:
168 return RequestType::RecoverDB;
169 case PKGMGR_REQ_REINSTALL:
170 return RequestType::Reinstall;
171 case PKGMGR_REQ_RECOVER:
172 return RequestType::Recovery;
173 case PKGMGR_REQ_MOVE:
174 return RequestType::Move;
177 std::shared_ptr<AppQueryInterface> query_interface = query_interface_;
178 if (!query_interface) {
179 auto it = query_interface_map_.find(idx);
180 if (it == query_interface_map_.end())
181 return RequestType::Unknown;
182 query_interface = it->second;
185 if (!is_app_installed_) {
187 query_interface->IsPkgInstalled(GetRequestInfo(idx), GetUid());
189 switch (pkgmgr_installer_get_request_type(pi_)) {
190 case PKGMGR_REQ_UPGRADE :
191 case PKGMGR_REQ_INSTALL : {
192 auto request_info = GetRequestInfo(idx);
193 if (request_info.empty())
194 return RequestType::Unknown;
195 bool is_delta = IsDeltaPkg(request_info);
196 if (!is_app_installed_.value()) {
198 LOG(ERROR) << "Package is not installed. "
199 "Cannot update from delta package";
200 return RequestType::Unknown;
202 return RequestType::Install;
206 return RequestType::Delta;
208 std::string pkgid = query_interface->GetPkgId(GetRequestInfo(idx));
209 uid_t uid = GetUid();
210 ci::PkgQueryInterface pkg_query(pkgid, uid);
211 if (!GetIsPreloadRequest() &&
212 pkg_query.IsReadonlyPackage() &&
213 !pkg_query.IsUpdatedPackage()) {
214 return RequestType::ReadonlyUpdateInstall;
215 } else if (CheckIfAppFilesExists(pkgid, uid,
216 pkg_query.IsReadonlyPackage())
218 return RequestType::Update;
220 RequestMode request_mode = GetRequestMode(uid);
221 UnregisterAppInPkgmgrForPkgId(pkgid, uid, request_mode);
222 return RequestType::Install;
227 case PKGMGR_REQ_UNINSTALL: {
228 std::string pkgid = GetRequestInfo(idx);
229 uid_t uid = GetUid();
230 ci::PkgQueryInterface pkg_query(pkgid, uid);
231 if (pkg_query.IsSystemPackage() &&
232 pkg_query.IsUpdatedPackage() &&
233 pkg_query.IsRemovablePackage())
234 return RequestType::ReadonlyUpdateUninstall;
235 else if (GetIsPreloadRequest() && GetIsPartialRW())
236 return RequestType::PartialUninstall;
238 return RequestType::Uninstall;
240 case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
241 if (!is_app_installed_.value()) {
242 if (GetIsPreloadRequest() && GetIsPartialRW())
243 return RequestType::ManifestPartialInstall;
245 return RequestType::ManifestDirectInstall;
247 if (GetIsPreloadRequest() && GetIsPartialRW())
248 return RequestType::ManifestPartialUpdate;
250 return RequestType::ManifestDirectUpdate;
252 case PKGMGR_REQ_MOUNT_INSTALL: {
253 if (!is_app_installed_.value()) {
254 return RequestType::MountInstall;
256 std::string pkgid = query_interface->GetPkgId(GetRequestInfo(idx));
257 uid_t uid = GetUid();
258 ci::PkgQueryInterface pkg_query(pkgid, uid);
259 if (CheckIfAppFilesExists(pkgid, uid, pkg_query.IsReadonlyPackage())) {
260 return RequestType::MountUpdate;
262 RequestMode request_mode = GetRequestMode(uid);
263 UnregisterAppInPkgmgrForPkgId(pkgid, uid, request_mode);
264 return RequestType::MountInstall;
269 return RequestType::Unknown;
273 uid_t PkgMgrInterface::GetUid() const {
274 return pkgmgr_installer_get_uid(pi_);
277 std::string PkgMgrInterface::GetRequestInfo(int idx) const {
278 const char* request_info = pkgmgr_installer_get_request_info_at(pi_, idx);
285 std::filesystem::path PkgMgrInterface::GetTepPath() const {
286 if (pkgmgr_installer_get_tep_path(pi_) == nullptr)
287 return std::filesystem::path("");
289 return std::filesystem::path(pkgmgr_installer_get_tep_path(pi_));
292 bool PkgMgrInterface::GetIsTepMove() const {
293 return (pkgmgr_installer_get_tep_move_type(pi_) == 1);
296 bool PkgMgrInterface::GetIsMoveToExternal() const {
297 return (pkgmgr_installer_get_move_type(pi_) == 1);
300 int PkgMgrInterface::GetMoveType() const {
301 return pkgmgr_installer_get_move_type(pi_);
304 bool PkgMgrInterface::GetIsPreloadRequest() const {
305 return (pkgmgr_installer_get_is_preload(pi_) == 1);
308 bool PkgMgrInterface::GetIsPreloadRWRequest() const {
309 return (pkgmgr_installer_get_is_preload_rw(pi_) == 1);
312 bool PkgMgrInterface::GetIsKeepRWData() const {
313 return (pkgmgr_installer_get_keep_rwdata(pi_) == 1);
316 bool PkgMgrInterface::GetIsPartialRW() const {
317 return (pkgmgr_installer_get_partial_rw(pi_) == 1);
320 std::unique_ptr<PkgmgrSignal> PkgMgrInterface::CreatePkgmgrSignal() const {
321 if (!pkgmgr_installer_interface_->ShouldCreateSignal())
323 return std::unique_ptr<PkgmgrSignal>(new PkgmgrSignal(pi_));
326 bool PkgMgrInterface::GetIsForceRemoval() const {
327 return (pkgmgr_installer_get_force_removal(pi_) == 1);
330 bool PkgMgrInterface::GetIsNoRemoval() const {
331 return (pkgmgr_installer_get_no_removal(pi_) == 1);
334 bool PkgMgrInterface::GetDebugMode() const {
335 return (pkgmgr_installer_get_debug_mode(pi_) == 1);
338 bool PkgMgrInterface::GetIsSkipCheckReference() const {
339 return (pkgmgr_installer_get_skip_check_reference(pi_) == 1);
342 bool PkgMgrInterface::GetSkipOptimization() const {
343 return (pkgmgr_installer_get_skip_optimization(pi_) == 1);
346 int PkgMgrInterface::GetRequestInfoCount() const {
347 return pkgmgr_installer_get_request_info_count(pi_);
350 bool PkgMgrInterface::GetRecoveryCleanup() const {
351 return (pkgmgr_installer_get_recovery_cleanup(pi_) == 1);
354 } // namespace common_installer