Fix backup plugin info 64/310364/11
authorIlho Kim <ilho159.kim@samsung.com>
Fri, 26 Apr 2024 04:03:45 +0000 (13:03 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Mon, 29 Apr 2024 11:40:20 +0000 (20:40 +0900)
In the undo operation of StepRunParserPlugin, there is a process of
rolling back with the plugin information peviously performed
When undo is executed, there is a problem that the old manifest value
does not exist in some request types

Change-Id: I3cf364ea877e3902794f2e89119a785328ca9930
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
src/common/installer/app_installer.cc
src/common/installer_context.h
src/common/step/backup/step_backup_plugin_info.cc [new file with mode: 0644]
src/common/step/backup/step_backup_plugin_info.h [new file with mode: 0644]
src/common/step/configuration/step_parse_manifest.cc
src/common/step/pkgmgr/step_run_parser_plugins.cc
src/common/step/pkgmgr/step_run_parser_plugins.h

index f575c8c..2eaa429 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "common/step/backup/step_backup_icons.h"
 #include "common/step/backup/step_backup_manifest.h"
+#include "common/step/backup/step_backup_plugin_info.h"
 #include "common/step/backup/step_copy_backup.h"
 #include "common/step/configuration/step_block_cross_update.h"
 #include "common/step/configuration/step_check_install_location.h"
@@ -383,6 +384,7 @@ void AppInstaller::UpdateSteps() {
   AddStep<ci::security::StepPrivacyPrivilege>(
       ci::security::StepPrivacyPrivilege::ActionType::Update);
   AddStep<ci::security::StepUpdateSecurity>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::pkgmgr::StepRunParserPlugin>(ci::Plugin::ActionType::Upgrade);
   AddStep<ci::filesystem::StepUpdateStorageDirectories>();
@@ -401,6 +403,7 @@ void AppInstaller::UninstallSteps() {
       ci::configuration::StepParseManifest::StoreLocation::NORMAL);
   AddStep<ci::configuration::StepCheckInstallLocation>();
   AddStep<ci::pkgmgr::StepKillApps>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepRunParserPlugin>(ci::Plugin::ActionType::Uninstall);
   AddStep<ci::filesystem::StepRemoveGlobalAppSymlinks>();
   AddStep<ci::filesystem::StepOptionalAcquireExternalStorage>();
@@ -448,6 +451,7 @@ void AppInstaller::ReinstallSteps() {
   AddStep<ci::security::StepPrivacyPrivilege>(
       ci::security::StepPrivacyPrivilege::ActionType::Update);
   AddStep<ci::security::StepUpdateSecurity>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::pkgmgr::StepRunParserPlugin>(ci::Plugin::ActionType::Upgrade);
   AddStep<ci::filesystem::StepUpdateStorageDirectories>();
@@ -491,6 +495,7 @@ void AppInstaller::DeltaSteps() {
   AddStep<ci::security::StepPrivacyPrivilege>(
       ci::security::StepPrivacyPrivilege::ActionType::Update);
   AddStep<ci::security::StepUpdateSecurity>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::pkgmgr::StepRunParserPlugin>(ci::Plugin::ActionType::Upgrade);
   AddStep<ci::filesystem::StepUpdateStorageDirectories>();
@@ -592,6 +597,7 @@ void AppInstaller::MountUpdateSteps() {
   AddStep<ci::security::StepPrivacyPrivilege>(
       ci::security::StepPrivacyPrivilege::ActionType::Update);
   AddStep<ci::security::StepUpdateSecurity>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::pkgmgr::StepRunParserPlugin>(ci::Plugin::ActionType::Upgrade);
   AddStep<ci::mount::StepUnmount>();
@@ -639,6 +645,7 @@ void AppInstaller::ManifestDirectUpdateSteps() {
   AddStep<ci::pkgmgr::StepKillApps>();
   AddStep<ci::filesystem::StepRemoveGlobalAppSymlinks>();
   AddStep<ci::filesystem::StepCreateResControlDirectories>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::security::StepRegisterTrustAnchor>(
       ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE);
@@ -680,6 +687,7 @@ void AppInstaller::ManifestPartialUpdateSteps() {
   AddStep<ci::security::StepCheckOldCertificate>();
   AddStep<ci::filesystem::StepRemoveGlobalAppSymlinks>();
   AddStep<ci::pkgmgr::StepKillApps>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::security::StepRegisterTrustAnchor>(
       ci::security::StepRegisterTrustAnchor::RegisterType::UPDATE);
@@ -703,6 +711,7 @@ void AppInstaller::PartialUninstallSteps() {
   AddStep<ci::filesystem::StepOptionalAcquireExternalStorage>();
   AddStep<ci::filesystem::StepRemovePerUserStorageDirectories>();
   AddStep<ci::pkgmgr::StepRemovePrivSharedres>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUnregisterApplication>();
   AddStep<ci::security::StepUnregisterTrustAnchor>();
   AddStep<ci::security::StepPrivacyPrivilege>(
@@ -742,6 +751,7 @@ void AppInstaller::ReadonlyUpdateInstallSteps() {
   AddStep<ci::security::StepPrivacyPrivilege>(
       ci::security::StepPrivacyPrivilege::ActionType::Update);
   AddStep<ci::security::StepUpdateSecurity>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::pkgmgr::StepRunParserPlugin>(ci::Plugin::ActionType::Upgrade);
   AddStep<ci::filesystem::StepUpdateStorageDirectories>();
@@ -778,6 +788,7 @@ void AppInstaller::ReadonlyUpdateUninstallSteps() {
   AddStep<ci::filesystem::StepRemoveUserData>();
   AddStep<ci::configuration::StepSwitchReadonlyMode>();
   AddStep<ci::security::StepUpdateSecurity>();
+  AddStep<ci::backup::StepBackupPluginInfo>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   AddStep<ci::pkgmgr::StepRemoveManifest>();
   AddStep<ci::pkgmgr::StepRunParserPlugin>(ci::Plugin::ActionType::Upgrade);
index 816a98e..2bd0aa5 100644 (file)
@@ -22,6 +22,7 @@
 #include "common/external_storage.h"
 #include "common/pkgmgr_interface.h"
 #include "common/recovery_file.h"
+#include "common/utils/pkgmgr_query.h"
 #include "common/utils/property.h"
 #include "common/utils/request.h"
 
@@ -420,6 +421,12 @@ class InstallerContext {
    * @brief Index of current request
    */
   Property<int> index;
+
+  /**
+   * @brief Property of vector of plugin execution information
+   *        (needed for rollback operations)
+   */
+  Property<std::vector<PkgQueryInterface::PluginInfo>> backup_plugin_info;
 };
 
 }  // namespace common_installer
diff --git a/src/common/step/backup/step_backup_plugin_info.cc b/src/common/step/backup/step_backup_plugin_info.cc
new file mode 100644 (file)
index 0000000..9a6d1e5
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/backup/step_backup_plugin_info.h"
+
+namespace common_installer {
+namespace backup {
+
+Step::Status StepBackupPluginInfo::precheck() {
+  if (context_->pkgid.get().empty()) {
+    LOG(ERROR) << "pkgid attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  return Step::Status::OK;
+}
+
+Step::Status StepBackupPluginInfo::process() {
+  PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
+  if (!pkg_query.PluginExecutionInfo(&context_->backup_plugin_info.get()))
+    return Step::Status::PACKAGE_NOT_FOUND;
+
+  return Step::Status::OK;
+}
+
+}  // namespace backup
+}  // namespace common_installer
diff --git a/src/common/step/backup/step_backup_plugin_info.h b/src/common/step/backup/step_backup_plugin_info.h
new file mode 100644 (file)
index 0000000..adbbadf
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_BACKUP_STEP_BACKUP_PLUGIN_INFO_H_
+#define COMMON_STEP_BACKUP_STEP_BACKUP_PLUGIN_INFO_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include <vector>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+#include "common/utils/pkgmgr_query.h"
+
+namespace common_installer {
+namespace backup {
+
+class StepBackupPluginInfo : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override { return Status::OK; };
+  Status undo() override { return Status::OK; };
+  Status precheck() override;
+
+ private:
+  std::vector<PkgQueryInterface::PluginInfo> backup_plugin_info_;
+
+  STEP_NAME(BackupPluginInfo)
+};
+
+}  // namespace backup
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_BACKUP_STEP_BACKUP_PLUGIN_INFO_H_
index 915a679..b843efa 100644 (file)
@@ -272,28 +272,6 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
     }
   }
 
-  // retrieve and set plugin execution info if exists
-  if (store_location_ == StoreLocation::BACKUP && (
-      manifest_location_ == ManifestLocation::INSTALLED ||
-      manifest_location_ == ManifestLocation::RECOVERY)) {
-    std::vector<PkgQueryInterface::PluginInfo> plugin_list;
-    pkg_query.PluginExecutionInfo(&plugin_list);
-
-    for (const auto& plugin_info : plugin_list) {
-      plugin_x* plugin =
-          reinterpret_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
-      if (!plugin) {
-        LOG(ERROR) << "Out of memory";
-        return false;
-      }
-
-      plugin->pkgid = strdup(manifest->package);
-      plugin->appid = strdup(std::get<1>(plugin_info).c_str());
-      plugin->plugin_type = strdup(std::get<2>(plugin_info).c_str());
-      plugin->plugin_name = strdup(std::get<3>(plugin_info).c_str());
-      manifest->plugin = g_list_append(manifest->plugin, plugin);
-    }
-  }
   return true;
 }
 
index 8542331..0f54d7c 100644 (file)
 #include "common/pkgmgr_registration.h"
 #include "common/plugins/plugin_manager.h"
 
+namespace {
+
+void FreePluginX(plugin_x* plugin) {
+  if (!plugin)
+    return;
+  if (plugin->pkgid)
+    free(plugin->pkgid);
+  if (plugin->appid)
+    free(plugin->appid);
+  if (plugin->plugin_type)
+    free(plugin->plugin_type);
+  if (plugin->plugin_name)
+    free(plugin->plugin_name);
+  free(plugin);
+}
+
+}  //namespace
+
 namespace common_installer {
 namespace pkgmgr {
 
@@ -90,6 +108,44 @@ Step::Status StepRunParserPlugin::process() {
   return Step::Status::OK;
 }
 
+bool StepRunParserPlugin::ReplacePluginInfo() {
+  manifest_x* manifest = context_->manifest_data.get();
+  if (manifest == nullptr || manifest->package == nullptr) {
+    LOG(ERROR) << "Invalid manifest";
+    return false;
+  }
+
+  g_list_free_full(
+      manifest->plugin,
+      [](gpointer data) {
+        FreePluginX(reinterpret_cast<plugin_x*>(data));
+      }
+  );
+  manifest->plugin = nullptr;
+
+  for (const auto& plugin_info : context_->backup_plugin_info.get()) {
+    plugin_x* plugin =
+        reinterpret_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
+    if (!plugin) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
+
+    plugin->pkgid = strdup(manifest->package);
+    plugin->appid = strdup(std::get<1>(plugin_info).c_str());
+    plugin->plugin_type = strdup(std::get<2>(plugin_info).c_str());
+    plugin->plugin_name = strdup(std::get<3>(plugin_info).c_str());
+    if (!plugin->pkgid || !plugin->appid ||
+        !plugin->plugin_type || !plugin->plugin_name) {
+      FreePluginX(plugin);
+      return false;
+    }
+    manifest->plugin = g_list_append(manifest->plugin, plugin);
+  }
+
+  return true;
+}
+
 Step::Status StepRunParserPlugin::undo() {
   Step::Status ret = Status::OK;
   switch (action_type_) {
@@ -108,8 +164,8 @@ Step::Status StepRunParserPlugin::undo() {
         LOG(ERROR) << "Failed to revert plugin execution info";
         ret = Step::Status::REGISTER_ERROR;
       }
-
-      if (!RegisterPluginInfo(context_->old_manifest_data.get(),
+      if (!ReplacePluginInfo() ||
+          !RegisterPluginInfo(context_->manifest_data.get(),
                               context_->uid.get(),
                               context_->request_mode.get())) {
         LOG(ERROR) << "Failed to revert plugin execution info";
@@ -117,7 +173,8 @@ Step::Status StepRunParserPlugin::undo() {
       }
       break;
     case Plugin::ActionType::Uninstall:
-      if (!RegisterPluginInfo(context_->manifest_data.get(),
+      if (!ReplacePluginInfo() ||
+          !RegisterPluginInfo(context_->manifest_data.get(),
                               context_->uid.get(),
                               context_->request_mode.get())) {
         LOG(ERROR) << "Failed to remove plugin execution info";
index e8d409c..ace2950 100644 (file)
@@ -39,6 +39,8 @@ class StepRunParserPlugin : public Step {
   bool InitPluginManager(const std::filesystem::path& xml_path,
                          manifest_x* manifest, uid_t uid);
 
+  bool ReplacePluginInfo();
+
   Plugin::ActionType action_type_;
   std::unique_ptr<PluginManager> plugin_manager_;