Run MountInstall when xml file is not exist
[platform/core/appfw/app-installers.git] / src / common / pkgmgr_interface.cc
index 7026a91..184dfaf 100644 (file)
@@ -9,26 +9,52 @@
 
 #include <tzplatform_config.h>
 
-#include <cstring>
 #include <memory>
 #include <string>
 #include <fstream>
 
 #include "common/app_query_interface.h"
-#include "common/pkgmgr_query.h"
+#include "common/utils/pkgmgr_query.h"
 #include "common/pkgmgr_signal.h"
+#include "common/pkgmgr_registration.h"
+#include "common/utils/file_util.h"
+#include "common/utils/manifest_util.h"
 #include "common/utils/user_util.h"
 
 namespace bf = boost::filesystem;
+namespace ci = common_installer;
 
 namespace {
 
 const char kDeltaFileExtension[] = ".delta";
-const char kLegacyContentPath[] = "/opt/usr/media";
+const char kDeltaFileName[] = "delta_info.xml";
 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
 
+bool CheckIfAppFilesExists(const std::string& pkgid,
+                           uid_t uid,
+                           bool is_readonly) {
+  return bf::exists(ci::GetManifestLocation(pkgid,
+              uid, is_readonly));
 }
 
+bool IsDeltaPkg(const std::string& path) {
+  bool is_delta = false;
+  if (!ci::CheckPathInZipArchive(path.c_str(), kDeltaFileName, &is_delta)) {
+    LOG(ERROR) << "Failed to check delta package";
+    return false;
+  }
+
+  if (!is_delta) {
+    std::string extension = bf::path(path).extension().string();
+    if (extension == kDeltaFileExtension)
+      is_delta = true;
+  }
+
+  return is_delta;
+}
+
+}  // namespace
+
 namespace common_installer {
 
 bool PkgmgrInstaller::CreatePkgMgrInstaller(pkgmgr_installer** installer,
@@ -54,7 +80,7 @@ bool PkgmgrInstaller::ShouldCreateSignal() const {
 
 PkgMgrPtr PkgMgrInterface::Create(int argc, char** argv,
     PkgmgrInstallerInterface* pkgmgr_installer_interface,
-    AppQueryInterface* interface) {
+    std::shared_ptr<AppQueryInterface> interface) {
   PkgMgrPtr instance(new PkgMgrInterface(pkgmgr_installer_interface,
                                          interface));
   int result = instance->InitInternal(argc, argv);
@@ -78,16 +104,21 @@ int PkgMgrInterface::InitInternal(int argc, char** argv) {
     return -1;
   }
 
-#ifdef ADMIN_USER_GLOBAL_INSTALLATION_ONLY
+  boost::optional<bool> is_admin_user =
+      IsAdminUser(pkgmgr_installer_get_uid(pi_));
+  if (!is_admin_user) {
+    LOG(ERROR) << "Cannot get admin user info. Aborting.";
+    return -1;
+  }
+
   // Set target uid as tizenglobalapp if admin user's request
-  if (IsAdminUser(pkgmgr_installer_get_uid(pi_))) {
+  if (*is_admin_user) {
     result = pkgmgr_installer_set_uid(pi_, kGlobalUserUid);
     if (result) {
       LOG(ERROR) << "Failed to set global uid";
       return -1;
     }
   }
-#endif
 
   return 0;
 }
@@ -97,22 +128,70 @@ PkgMgrInterface::~PkgMgrInterface() {
     pkgmgr_installer_free(pi_);
 }
 
-RequestType PkgMgrInterface::GetRequestType() const {
-  if (!query_interface_)
-    return RequestType::Unknown;
+// method name?
+bool PkgMgrInterface::SetAppQueryInterface(int idx) {
+  // reset this flag to processing new package
+  is_app_installed_ = boost::none;
+
+  auto it = query_interface_map_.find(idx);
+  if (it == query_interface_map_.end()) {
+    if (!query_interface_) {
+      LOG(ERROR) << "Cannot find query interface for index(" << idx << ")";
+      return false;
+    } else {
+      // using legacy query interface (for single pkg installer)
+      return true;
+    }
+  }
+  query_interface_ = it->second;
+  return true;
+}
+
+void PkgMgrInterface::AddAppQueryInterface(
+    int idx, std::shared_ptr<AppQueryInterface> interface) {
+  query_interface_map_.emplace(idx, interface);
+}
+
+RequestType PkgMgrInterface::GetRequestType(int idx) const {
+  // These type could be determined even if there are no query_interface_.
+  switch (pkgmgr_installer_get_request_type(pi_)) {
+    case PKGMGR_REQ_DISABLE_PKG:
+      return RequestType::DisablePkg;
+    case PKGMGR_REQ_ENABLE_PKG:
+      return RequestType::EnablePkg;
+    case PKGMGR_REQ_MIGRATE_EXTIMG:
+      return RequestType::MigrateExtImg;
+    case PKGMGR_REQ_RECOVER_DB:
+      return RequestType::RecoverDB;
+    case PKGMGR_REQ_REINSTALL:
+      return RequestType::Reinstall;
+    case PKGMGR_REQ_RECOVER:
+      return RequestType::Recovery;
+    case PKGMGR_REQ_MOVE:
+      return RequestType::Move;
+  }
+
+  std::shared_ptr<AppQueryInterface> query_interface = query_interface_;
+  if (!query_interface) {
+    auto it = query_interface_map_.find(idx);
+    if (it == query_interface_map_.end())
+      return RequestType::Unknown;
+    query_interface = it->second;
+  }
 
   if (!is_app_installed_) {
     is_app_installed_ =
-        query_interface_->IsPkgInstalled(GetRequestInfo(), GetUid());
+        query_interface->IsPkgInstalled(GetRequestInfo(idx), GetUid());
   }
   switch (pkgmgr_installer_get_request_type(pi_)) {
+    case PKGMGR_REQ_UPGRADE :
     case PKGMGR_REQ_INSTALL : {
-      auto request_info = GetRequestInfo();
+      auto request_info = GetRequestInfo(idx);
       if (request_info.empty())
         return RequestType::Unknown;
-      std::string extension = bf::path(request_info).extension().string();
+      bool is_delta = IsDeltaPkg(request_info);
       if (!is_app_installed_.get()) {
-        if (extension == kDeltaFileExtension) {
+        if (is_delta) {
           LOG(ERROR) << "Package is not installed. "
                         "Cannot update from delta package";
           return RequestType::Unknown;
@@ -120,37 +199,41 @@ RequestType PkgMgrInterface::GetRequestType() const {
           return RequestType::Install;
         }
       } else {
-        if (extension == kDeltaFileExtension) {
+        if (is_delta) {
           return RequestType::Delta;
         } else {
-          std::string pkgid = query_interface_->GetPkgId(GetRequestInfo());
+          std::string pkgid = query_interface->GetPkgId(GetRequestInfo(idx));
+          uid_t uid = GetUid();
+          ci::PkgQueryInterface pkg_query(pkgid, uid);
           if (!GetIsPreloadRequest() &&
-              QueryIsReadonlyPackage(pkgid, GetUid()) &&
-              !QueryIsUpdatedReadonlyPackage(pkgid, GetUid()))
+              pkg_query.IsReadonlyPackage() &&
+              !pkg_query.IsUpdatedPackage()) {
             return RequestType::ReadonlyUpdateInstall;
-          else
+          } else if (CheckIfAppFilesExists(pkgid, uid,
+              pkg_query.IsReadonlyPackage())
+                  ) {
             return RequestType::Update;
+          } else {
+            RequestMode request_mode = GetRequestMode(uid);
+            UnregisterAppInPkgmgrForPkgId(pkgid, uid, request_mode);
+            return RequestType::Install;
+          }
         }
       }
     }
     case PKGMGR_REQ_UNINSTALL: {
-      std::string pkgid = GetRequestInfo();
-      if (!GetIsPreloadRequest() &&
-          QueryIsUpdatedReadonlyPackage(pkgid, GetUid()))
+      std::string pkgid = GetRequestInfo(idx);
+      uid_t uid = GetUid();
+      ci::PkgQueryInterface pkg_query(pkgid, uid);
+      if (pkg_query.IsSystemPackage() &&
+          pkg_query.IsUpdatedPackage() &&
+          pkg_query.IsRemovablePackage())
         return RequestType::ReadonlyUpdateUninstall;
       else if (GetIsPreloadRequest() && GetIsPartialRW())
         return RequestType::PartialUninstall;
       else
         return RequestType::Uninstall;
     }
-    case PKGMGR_REQ_REINSTALL:
-      return RequestType::Reinstall;
-    case PKGMGR_REQ_CLEAR:
-      return RequestType::Clear;
-    case PKGMGR_REQ_RECOVER:
-      return RequestType::Recovery;
-    case PKGMGR_REQ_MOVE:
-      return RequestType::Move;
     case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
       if (!is_app_installed_.get()) {
         if (GetIsPreloadRequest() && GetIsPartialRW())
@@ -163,15 +246,22 @@ RequestType PkgMgrInterface::GetRequestType() const {
         else
           return RequestType::ManifestDirectUpdate;
       }
-    case PKGMGR_REQ_MOUNT_INSTALL:
-      if (!is_app_installed_.get())
+    case PKGMGR_REQ_MOUNT_INSTALL: {
+      if (!is_app_installed_.get()) {
         return RequestType::MountInstall;
-      else
-        return RequestType::MountUpdate;
-    case PKGMGR_REQ_DISABLE_PKG:
-      return RequestType::DisablePkg;
-    case PKGMGR_REQ_ENABLE_PKG:
-      return RequestType::EnablePkg;
+      } else {
+        std::string pkgid = query_interface->GetPkgId(GetRequestInfo(idx));
+        uid_t uid = GetUid();
+        ci::PkgQueryInterface pkg_query(pkgid, uid);
+        if (CheckIfAppFilesExists(pkgid, uid, pkg_query.IsReadonlyPackage())) {
+          return RequestType::MountUpdate;
+        } else {
+          RequestMode request_mode = GetRequestMode(uid);
+          UnregisterAppInPkgmgrForPkgId(pkgid, uid, request_mode);
+          return RequestType::MountInstall;
+        }
+      }
+    }
     default:
       return RequestType::Unknown;
   }
@@ -181,24 +271,12 @@ uid_t PkgMgrInterface::GetUid() const {
   return pkgmgr_installer_get_uid(pi_);
 }
 
-std::string PkgMgrInterface::GetRequestInfo() const {
-  std::string info;
-  const char* raw_info = pkgmgr_installer_get_request_info(pi_);
-  if (raw_info == nullptr)
+std::string PkgMgrInterface::GetRequestInfo(int idx) const {
+  const char* request_info = pkgmgr_installer_get_request_info_at(pi_, idx);
+  if (!request_info)
     return {};
-  // to support legacy content directory path,
-  // if the requested path starts with "/opt/usr/media", return modified path.
-  // note that "/opt/usr/media" is a mount point for TZ_USER_CONTENT.
-  if (!strncmp(raw_info, kLegacyContentPath, strlen(kLegacyContentPath))) {
-    tzplatform_set_user(GetUid());
-    const char* content_path = tzplatform_getenv(TZ_USER_CONTENT);
-    tzplatform_reset_user();
-    info = std::string(content_path) +
-      std::string(raw_info + strlen(kLegacyContentPath));
-  } else {
-    info = std::string(raw_info);
-  }
-  return info;
+  else
+    return request_info;
 }
 
 boost::filesystem::path PkgMgrInterface::GetTepPath() const {
@@ -216,6 +294,10 @@ bool PkgMgrInterface::GetIsMoveToExternal() const {
   return (pkgmgr_installer_get_move_type(pi_) == 1);
 }
 
+int PkgMgrInterface::GetMoveType() const {
+  return pkgmgr_installer_get_move_type(pi_);
+}
+
 bool PkgMgrInterface::GetIsPreloadRequest() const {
   return (pkgmgr_installer_get_is_preload(pi_) == 1);
 }
@@ -235,7 +317,7 @@ bool PkgMgrInterface::GetIsPartialRW() const {
 std::unique_ptr<PkgmgrSignal> PkgMgrInterface::CreatePkgmgrSignal() const {
   if (!pkgmgr_installer_interface_->ShouldCreateSignal())
     return nullptr;
-  return std::unique_ptr<PkgmgrSignal>(new PkgmgrSignal(pi_, GetRequestType()));
+  return std::unique_ptr<PkgmgrSignal>(new PkgmgrSignal(pi_));
 }
 
 bool PkgMgrInterface::GetIsForceRemoval() const {
@@ -250,4 +332,20 @@ bool PkgMgrInterface::GetDebugMode() const {
   return (pkgmgr_installer_get_debug_mode(pi_) == 1);
 }
 
+bool PkgMgrInterface::GetIsSkipCheckReference() const {
+  return (pkgmgr_installer_get_skip_check_reference(pi_) == 1);
+}
+
+bool PkgMgrInterface::GetSkipOptimization() const {
+  return (pkgmgr_installer_get_skip_optimization(pi_) == 1);
+}
+
+int PkgMgrInterface::GetRequestInfoCount() const {
+  return pkgmgr_installer_get_request_info_count(pi_);
+}
+
+bool PkgMgrInterface::GetRecoveryCleanup() const {
+  return (pkgmgr_installer_get_recovery_cleanup(pi_) == 1);
+}
+
 }  // namespace common_installer