Block different type installation with same pkgid
[platform/core/appfw/app-installers.git] / src / common / step / configuration / step_configure.cc
index 33460dc..6608e03 100644 (file)
 #include <string>
 #include <utility>
 
-#include "common/request.h"
+#include "common/utils/pkgmgr_query.h"
 #include "common/utils/file_util.h"
 #include "common/utils/user_util.h"
+#include "common/utils/request.h"
 
 namespace bf = boost::filesystem;
 
@@ -27,6 +28,8 @@ namespace configuration {
 
 const char kStrEmpty[] = "";
 const char kAppFWUser[] = "app_fw";
+const char kRpmPkgType[] = "rpm";
+const char kRpmInstaller[] = "tpk";
 
 StepConfigure::StepConfigure(InstallerContext* context, PkgMgrPtr pkgmgr)
     : Step(context),
@@ -38,141 +41,129 @@ Step::Status StepConfigure::process() {
   SetupRequestType();
   SetupFileCreationMask();
   SetupDebugMode();
+  SetupSkipCheckReference();
+  SetupSkipOptimization();
 
   if (!SetupRootAppDirectory())
     return Status::CONFIG_ERROR;
 
-  switch (pkgmgr_->GetRequestType()) {
+  RequestType request_type = context_->request_type.get();
+  switch (request_type) {
     case RequestType::Install:
-    case RequestType::Update:
-      context_->file_path.set(pkgmgr_->GetRequestInfo());
-      context_->pkgid.set(kStrEmpty);
+    case RequestType::Update: {
+      context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       if (!pkgmgr_->GetTepPath().empty()) {
         context_->tep_path.set(pkgmgr_->GetTepPath());
         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
       }
+      context_->pkgid.set(GetPkgIdFromFile());
       break;
+    }
     case RequestType::PartialUninstall:
-      SetupIsPartialRW();
     case RequestType::Uninstall:
-      if (context_->is_preload_rw_package.get())
-        SetupIsKeepRWData();
+      if (request_type == RequestType::PartialUninstall)
+        SetupIsPartialRW();
+      SetupIsKeepRWData();
       SetupIsForceRemoval();
-      context_->pkgid.set(pkgmgr_->GetRequestInfo());
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       context_->file_path.set(kStrEmpty);
       break;
     case RequestType::Reinstall:
       context_->unpacked_dir_path.set(
-          context_->root_application_path.get() / "tmp" /
-          pkgmgr_->GetRequestInfo());
-      context_->pkgid.set(pkgmgr_->GetRequestInfo());
+          bf::path(tzplatform_getenv(TZ_SDK_TOOLS)) / "tmp" /
+          pkgmgr_->GetRequestInfo(context_->index.get()));
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       context_->file_path.set(kStrEmpty);
       break;
     case RequestType::Delta:
       context_->unpacked_dir_path.set(kStrEmpty);
-      context_->pkgid.set(kStrEmpty);
-      context_->file_path.set(pkgmgr_->GetRequestInfo());
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
+      context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       break;
     case RequestType::Move:
-      context_->pkgid.set(pkgmgr_->GetRequestInfo());
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       context_->is_move_to_external.set(pkgmgr_->GetIsMoveToExternal());
+      SetupMoveType();
       break;
     case RequestType::Recovery:
-      context_->file_path.set(pkgmgr_->GetRequestInfo());
-      context_->pkgid.set(kStrEmpty);
+      context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
+      context_->recovery_info.set(
+          RecoveryInfo(context_->file_path.get(),
+              pkgmgr_->GetRecoveryCleanup()));
       break;
     case RequestType::MountInstall:
-    case RequestType::MountUpdate:
-      context_->file_path.set(pkgmgr_->GetRequestInfo());
-      context_->pkgid.set(kStrEmpty);
+    case RequestType::MountUpdate: {
+      context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       if (!pkgmgr_->GetTepPath().empty()) {
         context_->tep_path.set(pkgmgr_->GetTepPath());
         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
       }
+      context_->pkgid.set(GetPkgIdFromFile());
       break;
+    }
     case RequestType::ManifestPartialInstall:
     case RequestType::ManifestPartialUpdate:
-      SetupIsPartialRW();
     case RequestType::ManifestDirectInstall:
     case RequestType::ManifestDirectUpdate: {
-      context_->pkgid.set(pkgmgr_->GetRequestInfo());
-      bf::path package_directory =
-          context_->root_application_path.get() / context_->pkgid.get();
+      if (request_type == RequestType::ManifestPartialInstall ||
+          request_type == RequestType::ManifestPartialUpdate)
+        SetupIsPartialRW();
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       bf::path xml_path =
           bf::path(getUserManifestPath(context_->uid.get(),
               context_->is_readonly_package.get()))
           / bf::path(context_->pkgid.get());
       xml_path += ".xml";
-      context_->unpacked_dir_path.set(package_directory);
-      context_->pkg_path.set(package_directory);
+      context_->unpacked_dir_path.set(context_->GetPkgPath());
       context_->xml_path.set(xml_path);
       break;
     }
-    case RequestType::ReadonlyUpdateInstall:
-      context_->file_path.set(pkgmgr_->GetRequestInfo());
-      context_->pkgid.set(kStrEmpty);
+    case RequestType::ReadonlyUpdateInstall: {
+      context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       if (!pkgmgr_->GetTepPath().empty()) {
         context_->tep_path.set(pkgmgr_->GetTepPath());
         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
       }
+      context_->pkgid.set(GetPkgIdFromFile());
       break;
+    }
     case RequestType::ReadonlyUpdateUninstall: {
-      context_->pkgid.set(pkgmgr_->GetRequestInfo());
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       bf::path original_path =
           bf::path(tzplatform_getenv(TZ_SYS_RO_APP)) / context_->pkgid.get();
       context_->unpacked_dir_path.set(original_path);
       context_->file_path.set(kStrEmpty);
+      SetupIsKeepRWData();
       break;
     }
     case RequestType::DisablePkg:
     case RequestType::EnablePkg:
-      context_->pkgid.set(pkgmgr_->GetRequestInfo());
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       break;
     case RequestType::MigrateExtImg: {
-      context_->pkgid.set(pkgmgr_->GetRequestInfo());
-      bf::path package_directory =
-          context_->root_application_path.get() / context_->pkgid.get();
-      context_->pkg_path.set(package_directory);
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       break;
     }
-    default:
-      LOG(ERROR) <<
-          "Only installation, update and uninstallation is now supported";
-      return Status::CONFIG_ERROR;
+    case RequestType::RecoverDB: {
+      context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
       break;
-  }
-
-  // Record recovery file
-  if (pkgmgr_->GetRequestType() == RequestType::Install ||
-      pkgmgr_->GetRequestType() == RequestType::Update ||
-      pkgmgr_->GetRequestType() == RequestType::Delta ||
-      pkgmgr_->GetRequestType() == RequestType::MountInstall ||
-      pkgmgr_->GetRequestType() == RequestType::MountUpdate) {
-    std::unique_ptr<recovery::RecoveryFile> recovery_file =
-        recovery::RecoveryFile::CreateRecoveryFileForPath(
-            GenerateTemporaryPath(
-                context_->root_application_path.get() /
-                (context_->pkg_type.get() + "-recovery")));
-    if (!recovery_file) {
-      LOG(ERROR) << "Failed to create recovery file";
-      return Status::CONFIG_ERROR;
     }
-    recovery_file->set_type(pkgmgr_->GetRequestType());
-    if (!recovery_file->WriteAndCommitFileContent()) {
-      LOG(ERROR) << "Failed to write recovery file";
+    default:
+      LOG(ERROR) << "Unknown request type";
       return Status::CONFIG_ERROR;
-    }
-    context_->recovery_info.set(RecoveryInfo(std::move(recovery_file)));
   }
 
+  if (!CheckInvalidBackendUsage())
+    return Status::OPERATION_NOT_ALLOWED;
+
+  LOG(INFO) << "Request Type: " << GetRequestTypeString(request_type);
+
   return Status::OK;
 }
 
 Step::Status StepConfigure::precheck() {
   SetupIsPreloadRequest();
   SetupIsPreloadRWRequest();
-  if (context_->is_readonly_package.get())
-    SetupIsNoRemoval();
 
   bool is_readonly = context_->is_readonly_package.get();
   bool is_preload_rw = context_->is_preload_rw_package.get();
@@ -181,6 +172,9 @@ Step::Status StepConfigure::precheck() {
     return Status::ERROR;
   }
 
+  if (is_readonly || is_preload_rw)
+    SetupIsNoRemoval();
+
   uid_t uid = pkgmgr_->GetUid();
   context_->uid.set(uid);
   if (getuid() == 0)
@@ -198,13 +192,6 @@ Step::Status StepConfigure::precheck() {
   return Status::OK;
 }
 
-Step::Status StepConfigure::clean() {
-  // Clean up operations should not be covered by recovery
-  // as backup information is being lost during clean up
-  context_->recovery_info.get().recovery_file.reset();
-  return Status::OK;
-}
-
 bool StepConfigure::SetupRootAppDirectory() {
   if (context_->root_application_path.get().empty()) {
     std::string root_app_path =
@@ -216,7 +203,7 @@ bool StepConfigure::SetupRootAppDirectory() {
     context_->root_application_path.set(root_app_path);
   }
   if (!boost::filesystem::exists(context_->root_application_path.get())) {
-    boost::system:: error_code error;
+    boost::system::error_code error;
     boost::filesystem::create_directories(
         context_->root_application_path.get());
     if (error) {
@@ -234,7 +221,7 @@ void StepConfigure::SetupRequestMode(uid_t uid) {
 }
 
 void StepConfigure::SetupRequestType() {
-  context_->request_type.set(pkgmgr_->GetRequestType());
+  context_->request_type.set(pkgmgr_->GetRequestType(context_->index.get()));
 }
 
 void StepConfigure::SetupFileCreationMask() {
@@ -284,5 +271,66 @@ void StepConfigure::SetupDebugMode() {
   context_->debug_mode.set(pkgmgr_->GetDebugMode());
 }
 
+void StepConfigure::SetupSkipCheckReference() {
+  context_->skip_check_reference.set(pkgmgr_->GetIsSkipCheckReference());
+}
+
+void StepConfigure::SetupSkipOptimization() {
+  context_->skip_optimization.set(pkgmgr_->GetSkipOptimization());
+}
+
+void StepConfigure::SetupMoveType() {
+  int move_type = pkgmgr_->GetMoveType();
+  switch (move_type) {
+    case 0:
+      context_->move_type.set(MoveType::TO_INTERNAL);
+      break;
+    case 1:
+      context_->move_type.set(MoveType::TO_EXTERNAL);
+      break;
+    case 2:
+      context_->move_type.set(MoveType::TO_EXTENDED);
+      break;
+    default:
+      context_->move_type.set(MoveType::TO_INTERNAL);
+      break;
+  }
+}
+
+std::string StepConfigure::GetPkgIdFromFile() {
+  auto app_query_interface = pkgmgr_->GetAppQueryInterface();
+  if (!app_query_interface)
+    return "";
+
+  return app_query_interface->GetPkgId(
+      pkgmgr_->GetRequestInfo(context_->index.get()));
+}
+
+bool StepConfigure::CheckInvalidBackendUsage() {
+  if (context_->pkgid.get().empty())
+    return true;
+
+  PkgQueryInterface pkg_query(context_->pkgid.get().c_str(),
+      context_->uid.get());
+  if (!pkg_query.IsValid()) {
+    LOG(INFO) << "pkg[" << context_->pkgid.get()
+        << "] is not installed, skip checking backend with installed pkg";
+    return true;
+  }
+
+  const std::string& backend_type = context_->pkg_type.get();
+  std::string installed_pkg_type = pkg_query.Type();
+  if (installed_pkg_type == kRpmPkgType)
+    installed_pkg_type = kRpmInstaller;
+
+  if (installed_pkg_type != backend_type) {
+    LOG(ERROR) << "Wrong use of backend : package's type [" << pkg_query.Type()
+        << "] mismatched backend [" << backend_type << "]";
+    return false;
+  }
+
+  return true;
+}
+
 }  // namespace configuration
 }  // namespace common_installer