Implement launching 'metadata' and 'category' plugin 28/59028/9 accepted/tizen/common/20160304.194918 submit/tizen/20160303.090142
authorTomasz Iwanek <t.iwanek@samsung.com>
Fri, 5 Feb 2016 12:39:21 +0000 (13:39 +0100)
committerTomasz Iwanek <t.iwanek@samsung.com>
Thu, 3 Mar 2016 09:00:09 +0000 (01:00 -0800)
Implementation of loading other types of plugins of
pkgmgr than 'tag':
 - DynamicLibHandle was reworked to be base class of all plugins types,
 - add factory for plugin and common interface for them.

Following changes should be submitted together:
 - https://review.tizen.org/gerrit/#/c/59029/
 - https://review.tizen.org/gerrit/#/c/59028/
 - https://review.tizen.org/gerrit/#/c/59030/
 - https://review.tizen.org/gerrit/#/c/59031/

Change-Id: I7f6bd50e364bedac2ee18626db0b02cda4865e31

23 files changed:
packaging/app-installers.spec
src/common/CMakeLists.txt
src/common/plugins/plugin.cc [new file with mode: 0644]
src/common/plugins/plugin.h [new file with mode: 0644]
src/common/plugins/plugin_factory.cc [new file with mode: 0644]
src/common/plugins/plugin_factory.h [new file with mode: 0644]
src/common/plugins/plugin_list_parser.cc
src/common/plugins/plugin_list_parser.h
src/common/plugins/plugin_manager.cc
src/common/plugins/plugin_manager.h
src/common/plugins/plugins_launcher.cc [deleted file]
src/common/plugins/plugins_launcher.h [deleted file]
src/common/plugins/plugins_list.txt.in
src/common/plugins/types/category_plugin.cc [new file with mode: 0644]
src/common/plugins/types/category_plugin.h [new file with mode: 0644]
src/common/plugins/types/metadata_plugin.cc [new file with mode: 0644]
src/common/plugins/types/metadata_plugin.h [new file with mode: 0644]
src/common/plugins/types/tag_plugin.cc [new file with mode: 0644]
src/common/plugins/types/tag_plugin.h [new file with mode: 0644]
src/common/step/step_run_parser_plugins.cc
src/common/step/step_run_parser_plugins.h
src/common/utils/dynamic_lib_handle.cc [deleted file]
src/common/utils/dynamic_lib_handle.h [deleted file]

index 041b4d2..249b46b 100644 (file)
@@ -85,6 +85,7 @@ make %{?_smp_mflags}
 %files devel
 %{_includedir}/app-installers/common/*.h
 %{_includedir}/app-installers/common/*/*.h
+%{_includedir}/app-installers/common/*/*/*.h
 %{_libdir}/pkgconfig/app-installers.pc
 
 %files tests
index a194ecc..b5c5efc 100644 (file)
@@ -3,10 +3,15 @@ SET(SRCS
   app_installer.cc
   backup_paths.cc
   installer_context.cc
-  plugins/plugins_launcher.cc
+  plugins/plugin_factory.cc
   plugins/plugin_manager.cc
   plugins/plugin_list_parser.cc
   plugins/plugin_xml_parser.cc
+  plugins/plugin_factory.cc
+  plugins/plugin.cc
+  plugins/types/category_plugin.cc
+  plugins/types/metadata_plugin.cc
+  plugins/types/tag_plugin.cc
   pkgmgr_interface.cc
   pkgmgr_registration.cc
   pkgmgr_signal.cc
@@ -58,7 +63,6 @@ SET(SRCS
   step/step_update_tep.cc
   step/step_remove_manifest.cc
   utils/base64.cc
-  utils/dynamic_lib_handle.cc
   utils/file_util.cc
   utils/subprocess.cc
 )
diff --git a/src/common/plugins/plugin.cc b/src/common/plugins/plugin.cc
new file mode 100644 (file)
index 0000000..212857b
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright (c) 2016 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/plugins/plugin.h"
+
+#include <pkgmgr_parser.h>
+
+#include <memory>
+
+namespace common_installer {
+
+Plugin::Plugin(const PluginInfo& plugin_info)
+    : plugin_info_(plugin_info),
+      lib_handle_(nullptr) {}
+
+bool Plugin::Load() {
+  if (lib_handle_) {
+    return true;
+  }
+
+  lib_handle_ = dlopen(plugin_info_.path().c_str(), RTLD_LAZY | RTLD_LOCAL);
+  if (!lib_handle_) {
+    LOG(ERROR) << "Failed to open library: " << plugin_info_.path().c_str()
+               << " (" << dlerror() << ")";
+    return false;
+  }
+  return true;
+}
+
+void* Plugin::GetSymbol(const std::string& name) const {
+  return dlsym(lib_handle_, name.c_str());
+}
+
+Plugin::~Plugin() {
+  if (lib_handle_) {
+    dlclose(lib_handle_);
+  }
+}
+
+int ActionTypeToPkgmgrActionType(common_installer::Plugin::ActionType action) {
+  switch (action) {
+    case Plugin::ActionType::Install:
+      return ACTION_INSTALL;
+    case Plugin::ActionType::Upgrade:
+      return ACTION_UPGRADE;
+    case Plugin::ActionType::Uninstall:
+      return ACTION_UNINSTALL;
+    default:
+      LOG(ERROR) << "Failed to get correct action type";
+      return -1;
+  }
+}
+
+}  // namespace common_installer
diff --git a/src/common/plugins/plugin.h b/src/common/plugins/plugin.h
new file mode 100644 (file)
index 0000000..d9be7f6
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (c) 2016 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_PLUGINS_PLUGIN_H_
+#define COMMON_PLUGINS_PLUGIN_H_
+
+#include <boost/filesystem/path.hpp>
+#include <dlfcn.h>
+#include <manifest_parser/utils/logging.h>
+#include <libxml2/libxml/tree.h>
+#include <pkgmgrinfo_basic.h>
+
+#include <memory>
+#include <string>
+
+#include "common/plugins/plugin_list_parser.h"
+
+namespace common_installer {
+
+/**
+ * @brief The Plugin class
+ *        Represents pkgmgr plugin object handling internally managing loading
+ *        of .so shared object from file system. Run() function is being
+ *        overloaded in subclasses to accommodate plugin differences.
+ */
+class Plugin {
+ public:
+  enum class ActionType { Install, Upgrade, Uninstall };
+  enum class ProcessType { Pre, Main, Post };
+
+  virtual ~Plugin();
+
+  template <typename Ret, typename... Args>
+  bool Exec(const std::string& name, Ret* result, Args... args) {
+    using PluginFunctionPtr = Ret (*)(Args...);
+    PluginFunctionPtr function =
+        reinterpret_cast<PluginFunctionPtr>(GetSymbol(name));
+
+    if (!function) {
+      LOG(WARNING) << "Failed to get symbol: " << name << " (" << dlerror()
+                   << ")";
+      return false;
+    }
+
+    LOG(DEBUG) << "Execute plugin function: " << name << " of "
+               << plugin_info_.path() << "...";
+    *result = function(args...);
+    return true;
+  }
+
+  virtual bool Run(xmlDocPtr doc_ptr, manifest_x* manifest,
+                   ActionType action_type) = 0;
+
+  Plugin(Plugin&&) = default;
+  Plugin& operator=(Plugin&&) = default;
+
+ protected:
+  explicit Plugin(const PluginInfo& plugin_info);
+  bool Load();
+
+  PluginInfo plugin_info_;
+
+ private:
+  void* GetSymbol(const std::string& name) const;
+
+  void* lib_handle_;
+
+  SCOPE_LOG_TAG(Plugin)
+};
+
+/**
+ * @brief ActionTypeToPkgmgrActionType
+ *        Helper function to convert app-installer ActionType to pkgmgr action
+ *        type for 'category' and 'metadata' plugins.
+ *
+ * @param action input action type
+ * @return pkgmgr action type or -1 if error
+ */
+int ActionTypeToPkgmgrActionType(common_installer::Plugin::ActionType action);
+
+}  // namespace common_installer
+
+#endif  // COMMON_PLUGINS_PLUGIN_H_
diff --git a/src/common/plugins/plugin_factory.cc b/src/common/plugins/plugin_factory.cc
new file mode 100644 (file)
index 0000000..9862142
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/plugins/plugin_factory.h"
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/plugins/types/category_plugin.h"
+#include "common/plugins/types/metadata_plugin.h"
+#include "common/plugins/types/tag_plugin.h"
+
+namespace common_installer {
+
+std::unique_ptr<Plugin> PluginFactory::CreatePluginByPluginInfo(
+    const PluginInfo& plugin_info) {
+  if (plugin_info.type() == TagPlugin::kType) {
+    return TagPlugin::Create(plugin_info);
+  } else if (plugin_info.type() == MetadataPlugin::kType) {
+    return MetadataPlugin::Create(plugin_info);
+  } else if (plugin_info.type() == CategoryPlugin::kType) {
+    return CategoryPlugin::Create(plugin_info);
+  } else {
+    LOG(ERROR) << "Unknown plugin type: " << plugin_info.type();
+    return nullptr;
+  }
+}
+
+}  // namespace common_installer
diff --git a/src/common/plugins/plugin_factory.h b/src/common/plugins/plugin_factory.h
new file mode 100644 (file)
index 0000000..6798c36
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_PLUGINS_PLUGIN_FACTORY_H_
+#define COMMON_PLUGINS_PLUGIN_FACTORY_H_
+
+#include <memory>
+
+#include "common/plugins/plugin.h"
+#include "common/plugins/plugin_list_parser.h"
+
+namespace common_installer {
+
+class PluginFactory {
+ public:
+  std::unique_ptr<Plugin> CreatePluginByPluginInfo(
+      const PluginInfo& plugin_info);
+};
+
+}  // namespace common_installer
+
+#endif  // COMMON_PLUGINS_PLUGIN_FACTORY_H_
index ce59262..b0b05c2 100644 (file)
@@ -125,7 +125,7 @@ bool PluginsListParser::Parse() {
   return true;
 }
 
-const PluginsListParser::PluginList& PluginsListParser::PluginInfoList() {
+const PluginsListParser::PluginList& PluginsListParser::PluginInfoList() const {
   return plugin_info_list_;
 }
 
index ef85e42..a18f7cf 100644 (file)
@@ -49,14 +49,12 @@ class PluginsListParser {
   explicit PluginsListParser(const std::string& path) : path_(path) {}
 
   bool Parse();
-  const PluginList& PluginInfoList();
+  const PluginList& PluginInfoList() const;
 
  private:
   enum Column { Flag, Type, Name, Path };
 
   PluginsListParser() {}
-  const std::string path_;
-  std::vector<std::shared_ptr<PluginInfo>> plugin_info_list_;
 
   bool ReadLinesFromFile(std::vector<std::string>* lines);
   bool ParsePluginsRawData(const std::vector<std::string>& lines);
@@ -72,6 +70,9 @@ class PluginsListParser {
   bool ValidType(const std::string& type);
   bool ValidName(const std::string& name);
   bool ValidPath(const std::string& path);
+
+  const std::string path_;
+  std::vector<std::shared_ptr<PluginInfo>> plugin_info_list_;
 };
 
 }  // namespace common_installer
index 9650221..766efc0 100644 (file)
 
 #include <boost/filesystem.hpp>
 
+#include <algorithm>
 #include <string>
 #include <vector>
 
+#include "common/plugins/plugin_factory.h"
 #include "common/plugins/plugin_list_parser.h"
 #include "common/plugins/plugin_xml_parser.h"
+#include "common/plugins/types/category_plugin.h"
+#include "common/plugins/types/metadata_plugin.h"
+#include "common/plugins/types/tag_plugin.h"
+#include "common/utils/glist_range.h"
 
 namespace common_installer {
 
-bool PluginManager::GenerateUnknownTagList() {
-  tags_.clear();
-
+bool PluginManager::GenerateUnknownTagList(
+    std::vector<std::string>* xml_tags) {
   if (!xml_parser_.Parse()) {
     LOG(ERROR) << "Parse xml function error";
     return false;
   }
 
-  std::vector<std::string> xmlTags = xml_parser_.tags_list();
+  *xml_tags = xml_parser_.tags_list();
+  return true;
+}
 
+bool PluginManager::GeneratePluginInfoList(
+    PluginManager::PluginInfoList* plugin_info_list) {
   if (!list_parser_.Parse()) {
     LOG(ERROR) << "Parse list function error";
     return false;
   }
 
-  const PluginsListParser::PluginList& pluginInfoList =
-      list_parser_.PluginInfoList();
-
-  for (std::shared_ptr<PluginInfo> pluginInfo : pluginInfoList) {
-    // find only tags
-    if (pluginInfo->type() == "tag") {
-      // check if a file exist
-      if (boost::filesystem::exists(pluginInfo->path())) {
-        for (const std::string& xmlTag : xmlTags) {
-          // if system tags included in xml tags
-          if (pluginInfo->name() == xmlTag) {
-            tags_.push_back(pluginInfo);
-            LOG(DEBUG) << "Tag: " << pluginInfo->name()
-                       << " path: " << pluginInfo->path() << "has been added";
+  *plugin_info_list = list_parser_.PluginInfoList();
+  return true;
+}
+
+bool PluginManager::LoadPlugins() {
+  std::vector<std::string> xml_tags;
+  if (!GenerateUnknownTagList(&xml_tags))
+    return false;
+
+  PluginInfoList plugin_info_list;
+  if (!GeneratePluginInfoList(&plugin_info_list))
+    return false;
+
+  PluginFactory factory;
+
+  std::sort(xml_tags.begin(), xml_tags.end());
+
+  // This loop loads plugin which are needed according to manifest file
+  // Different pkgmgr plugin types have different condition upon which they
+  // are being loaded
+  LOG(DEBUG) << "Loading pkgmgr plugins...";
+  for (std::shared_ptr<PluginInfo> plugin_info : plugin_info_list) {
+    std::unique_ptr<Plugin> plugin;
+    if (plugin_info->type() == TagPlugin::kType) {
+      // load tag plugin only if tag exists in manifest file
+      auto iter = std::lower_bound(xml_tags.begin(), xml_tags.end(),
+                                     plugin_info->name());
+      if (iter != xml_tags.end() && *iter == plugin_info->name()) {
+        plugin = factory.CreatePluginByPluginInfo(*plugin_info);
+        if (!plugin) {
+          LOG(ERROR) << "Failed to load plugin: " << plugin_info->path()
+                     << " Plugin has been skipped.";
+        }
+      }
+    } else if (plugin_info->type() == MetadataPlugin::kType) {
+      bool done = false;
+      for (application_x* app : GListRange<application_x*>(
+           manifest_->application)) {
+        for (metadata_x* meta : GListRange<metadata_x*>(app->metadata)) {
+          if (std::string(meta->key).find(plugin_info->name()) == 0) {
+            plugin = factory.CreatePluginByPluginInfo(*plugin_info);
+            if (!plugin) {
+              LOG(ERROR) << "Failed to load plugin: " << plugin_info->path()
+                         << " Plugin has been skipped.";
+            }
+            done = true;
+            break;
+          }
+        }
+        if (done)
+          break;
+      }
+    } else if (plugin_info->type() == CategoryPlugin::kType) {
+      bool done = false;
+      for (application_x* app : GListRange<application_x*>(
+           manifest_->application)) {
+        for (const char* category : GListRange<char*>(app->category)) {
+          if (std::string(category).find(plugin_info->name()) == 0) {
+            plugin = factory.CreatePluginByPluginInfo(*plugin_info);
+            if (!plugin) {
+              LOG(ERROR) << "Failed to load plugin: " << plugin_info->path()
+                         << " Plugin has been skipped.";
+            }
+            done = true;
             break;
           }
         }
-      } else {
-        LOG(WARNING) << "Tag: " << pluginInfo->name()
-                     << " path: " << pluginInfo->path()
-                     << " exist in plugin list but no exist in system.";
+        if (done)
+          break;
       }
     }
-  }
-
-  if (tags_.empty()) {
-    LOG(INFO) << "No tags to processing";
-  }
-
-  return true;
-}
 
-const PluginManager::TagList& PluginManager::UnknownTagList() { return tags_; }
-
-xmlDocPtr PluginManager::CreateDocPtrForPlugin(xmlDocPtr doc_ptr,
-    const std::string& tag_name) const {
-  // Make copy of document and root node
-  xmlNodePtr root_node = xmlDocGetRootElement(doc_ptr);
-  if (!root_node) {
-    LOG(ERROR) << "Original document is empty. Cannot create copy for plugin";
-    return nullptr;
-  }
-  xmlDocPtr plugin_doc_ptr = xmlCopyDoc(doc_ptr, 0);
-  xmlNodePtr plugin_root_node = xmlCopyNode(root_node, 0);
-  xmlDocSetRootElement(plugin_doc_ptr, plugin_root_node);
-
-  // Append elements that matches the tag name to new doc
-  for (xmlNodePtr child = xmlFirstElementChild(root_node);
-       child != nullptr; child = xmlNextElementSibling(child)) {
-    if (tag_name == reinterpret_cast<const char*>(child->name)) {
-      xmlAddChild(plugin_root_node, xmlCopyNode(child, 1));
+    if (plugin) {
+      loaded_plugins_.push_back(std::move(plugin));
+      LOG(DEBUG) << "Loaded plugin: " << plugin_info->path();
     }
   }
-  xmlSetTreeDoc(plugin_root_node, plugin_doc_ptr);
-  return plugin_doc_ptr;
+  return true;
 }
 
-bool PluginManager::Launch(const boost::filesystem::path& plugin_path,
-                           const std::string& tag_name,
-                           PluginsLauncher::ActionType action_type,
-                           const std::string& pkg_Id) {
-  LOG(INFO) << "Launching plugin path:" << plugin_path << " pkgId: " << pkg_Id;
-
-  int result = EPERM;
-
-  xmlDocPtr plugin_doc_ptr = CreateDocPtrForPlugin(xml_parser_.doc_ptr(),
-                                                   tag_name);
-  if (!plugin_doc_ptr)
-    return false;
-  PluginsLauncher::Error error = plugins_launcher_.LaunchPlugin(
-      plugin_path, plugin_doc_ptr, action_type, pkg_Id, &result);
-  xmlFreeDoc(plugin_doc_ptr);
-
-  switch (error) {
-    case PluginsLauncher::Error::Success: {
-      if (result != 0) {
-        LOG(ERROR) << "Error from plugin lib: " << plugin_path
-                   << " error code: " << result;
-        return false;
-      }
-      return true;
-    }
-    case PluginsLauncher::Error::ActionNotSupported:
-      return true;
-
-    case PluginsLauncher::Error::FailedLibHandle:
-    default:
-      return false;
+void PluginManager::RunPlugins(Plugin::ActionType action_type) {
+  LOG(DEBUG) << "Running pkgmgr plugins...";
+  for (auto& plugin : loaded_plugins_) {
+    // FIXME: Ignore if plugin failed for now, we need to keep installation
+    // working nevertheless plugins are broken
+    plugin->Run(xml_parser_.doc_ptr(), manifest_, action_type);
   }
 }
 
index 36c0fb6..f0d5a40 100644 (file)
@@ -7,10 +7,11 @@
 
 #include <boost/filesystem/path.hpp>
 
+#include <pkgmgrinfo_basic.h>
 #include <string>
 #include <vector>
 
-#include "common/plugins/plugins_launcher.h"
+#include "common/plugins/plugin.h"
 #include "common/plugins/plugin_list_parser.h"
 #include "common/plugins/plugin_xml_parser.h"
 
@@ -19,33 +20,28 @@ namespace common_installer {
 /** this class manages XML and plugin lists */
 class PluginManager {
  public:
-  using TagList = std::vector<std::shared_ptr<PluginInfo>>;
-  PluginManager(const std::string& xml_path, const std::string& list_path)
-      : xml_parser_(xml_path), list_parser_(list_path) {}
+  using PluginInfoList = std::vector<std::shared_ptr<PluginInfo>>;
 
-  bool GenerateUnknownTagList();
-  const TagList& UnknownTagList();
-  bool Launch(const boost::filesystem::path& pluginPath,
-              const std::string& tag_name,
-              PluginsLauncher::ActionType actionType, const std::string& pkgId);
+  PluginManager(const std::string& xml_path,
+                const std::string& list_path,
+                manifest_x* manifest)
+      : xml_parser_(xml_path),
+        list_parser_(list_path),
+        manifest_(manifest) {}
+
+  bool LoadPlugins();
+  void RunPlugins(Plugin::ActionType action_type);
 
  private:
-  /**
-   * @brief CreateDocPtrForPlugin
-   *        Create copy of xml document with nodes only matching requested
-   *        tag_name
-   * @param doc_ptr original doc ptr of document
-   * @param tag_name name of required node/nodes
-   * @return requested copy
-   */
-  xmlDocPtr CreateDocPtrForPlugin(xmlDocPtr doc_ptr,
-                                  const std::string& tag_name) const;
-
-  std::vector<std::shared_ptr<PluginInfo>> tags_;
+  bool GenerateUnknownTagList(std::vector<std::string>* xml_tags);
+  bool GeneratePluginInfoList(PluginInfoList* plugin_info_list);
+
   PluginsXmlParser xml_parser_;
   PluginsListParser list_parser_;
-  PluginsLauncher plugins_launcher_;
+  manifest_x* manifest_;
+  std::vector<std::unique_ptr<Plugin>> loaded_plugins_;
 };
+
 }  // namespace common_installer
 
 #endif  // COMMON_PLUGINS_PLUGIN_MANAGER_H_
diff --git a/src/common/plugins/plugins_launcher.cc b/src/common/plugins/plugins_launcher.cc
deleted file mode 100644 (file)
index 7b69898..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2016 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/plugins/plugins_launcher.h"
-
-#include <dlfcn.h>
-
-#include <map>
-#include <utility>
-
-namespace common_installer {
-
-PluginsLauncher::Error PluginsLauncher::LaunchPlugin(
-    const boost::filesystem::path& plugin_path, xmlDocPtr docPtr,
-    ActionType action, const std::string& pkgId, int* result) {
-  LOG(DEBUG) << "Loading plugin: " << plugin_path;
-
-  DynamicLibHandle dlh;
-
-  if (!dlh.Load(plugin_path, RTLD_LAZY | RTLD_LOCAL)) {
-    LOG(ERROR) << "Failed to create library handle";
-    return Error::FailedLibHandle;
-  }
-
-  bool is_supported = false;
-
-  if (ExecPlugin(dlh, ProcessType::PreInstall, action, pkgId.c_str(),
-                  result)) {
-    is_supported = true;
-  }
-
-  if (ExecPlugin(dlh, ProcessType::Install, action, docPtr, pkgId.c_str(),
-                  result)) {
-    is_supported = true;
-  }
-
-  if (ExecPlugin(dlh, ProcessType::PostInstall, action, pkgId.c_str(),
-                  result)) {
-    is_supported = true;
-  }
-
-  if (!is_supported) {
-    return Error::ActionNotSupported;
-  }
-
-  return Error::Success;
-}
-
-bool PluginsLauncher::FunctionName(ProcessType process, ActionType action,
-                              std::string* result) {
-  static std::map<std::pair<ActionType, ProcessType>, std::string> names {
-    {{ActionType::Install,   ProcessType::PreInstall},  "PKGMGR_PARSER_PLUGIN_PRE_INSTALL"},   // NOLINT
-    {{ActionType::Upgrade,   ProcessType::PreInstall},  "PKGMGR_PARSER_PLUGIN_PRE_UPGRADE"},   // NOLINT
-    {{ActionType::Uninstall, ProcessType::PreInstall},  "PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL"}, // NOLINT
-    {{ActionType::Install,   ProcessType::Install},     "PKGMGR_PARSER_PLUGIN_INSTALL"},       // NOLINT
-    {{ActionType::Upgrade,   ProcessType::Install},     "PKGMGR_PARSER_PLUGIN_UPGRADE"},       // NOLINT
-    {{ActionType::Uninstall, ProcessType::Install},     "PKGMGR_PARSER_PLUGIN_UNINSTALL"},     // NOLINT
-    {{ActionType::Install,   ProcessType::PostInstall}, "PKGMGR_PARSER_PLUGIN_POST_INSTALL"},  // NOLINT
-    {{ActionType::Upgrade,   ProcessType::PostInstall}, "PKGMGR_PARSER_PLUGIN_POST_UPGRADE"},  // NOLINT
-    {{ActionType::Uninstall, ProcessType::PostInstall}, "PKGMGR_PARSER_PLUGIN_POST_UNINSTALL"} // NOLINT
-  };
-
-  auto pos = names.find(std::make_pair(action, process));
-  if (pos == names.end()) {
-    LOG(ERROR) << "Function name not defined";
-    return false;
-  }
-  *result = pos->second;
-  return true;
-}
-
-bool PluginsLauncher::ExecPlugin(const DynamicLibHandle& dlh,
-                                 ProcessType process,
-                                 ActionType action, const char* pkgId,
-                                 int* result) {
-  return ExecPluginImpl(dlh, process, action, result, pkgId);
-}
-
-bool PluginsLauncher::ExecPlugin(const DynamicLibHandle& dlh,
-                                 ProcessType process,
-                                 ActionType action, xmlDocPtr docPtr,
-                                 const char* pkgId, int* result) {
-  return ExecPluginImpl(dlh, process, action, result, docPtr, pkgId);
-}
-
-}  // namespace common_installer
diff --git a/src/common/plugins/plugins_launcher.h b/src/common/plugins/plugins_launcher.h
deleted file mode 100644 (file)
index 7a1ed34..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2016 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_PLUGINS_PLUGINS_LAUNCHER_H_
-#define COMMON_PLUGINS_PLUGINS_LAUNCHER_H_
-
-#include <boost/filesystem/path.hpp>
-
-#include <libxml/tree.h>
-#include <manifest_parser/utils/logging.h>
-
-#include <string>
-#include <memory>
-
-#include "common/utils/dynamic_lib_handle.h"
-
-namespace common_installer {
-
-class PluginsLauncher {
- public:
-  enum class ActionType { Install, Upgrade, Uninstall };
-  enum class ProcessType { PreInstall, Install, PostInstall };
-
-  enum class Error { Success, FailedLibHandle, ActionNotSupported };
-
-  Error LaunchPlugin(const boost::filesystem::path& plugin_path,
-                     xmlDocPtr docPtr, ActionType action,
-                     const std::string& pkgId, int* result);
-
- private:
-  bool FunctionName(ProcessType process, ActionType action,
-                    std::string* result);
-
-  bool ExecPlugin(const DynamicLibHandle& dlh, ProcessType process,
-                  ActionType action, const char* pkgId, int* result);
-
-  bool ExecPlugin(const DynamicLibHandle& dlh, ProcessType process,
-                  ActionType action, xmlDocPtr docPtr,
-                  const char* pkgId, int* result);
-
-  template <typename... Args>
-  bool ExecPluginImpl(const DynamicLibHandle& dlh, ProcessType process,
-                      ActionType action, int* result, Args&&... args) {
-    std::string name;
-    if (!FunctionName(process, action, &name)) {
-      LOG(ERROR) << "Error during getting function name";
-      return false;
-    }
-    return dlh.Exec(name, result, std::forward<Args>(args)...);
-  }
-
-  SCOPE_LOG_TAG(PluginsLauncher)
-};
-
-}  // namespace common_installer
-
-#endif  // COMMON_PLUGINS_PLUGINS_LAUNCHER_H_
index 2d7f8ac..d53e23c 100644 (file)
@@ -3,14 +3,14 @@ flag="0x00000002";type="tag";name="account";path="/etc/package-manager/parserlib
 flag="0x00000004";type="tag";name="notifications";path="/etc/package-manager/parserlib/libnotifications.so"
 flag="0x00000008";type="tag";name="privileges";path="/etc/package-manager/parserlib/libprivileges.so"
 flag="0x00000010";type="tag";name="ime";path="/etc/package-manager/parserlib/libime.so"
-flag="0x00000020";type="category";name="http://tizen.org/category/downloadable_font";path="/usr/etc/package-manager/parserlib/category/libdownloadable_font.so"
-flag="0x00000040";type="metadata";name="http://developer.samsung.com/tizen/metadata/sticker";path="/usr/etc/package-manager/parserlib/metadata/libsticker.so"
-flag="0x00000080";type="metadata";name="http://developer.samsung.com/tizen/metadata/ttsengine";path="/usr/etc/package-manager/parserlib/metadata/libttsengine.so"
-flag="0x00000100";type="metadata";name="http://developer.samsung.com/tizen/metadata/downloadable_filters";path="/usr/etc/package-manager/parserlib/metadata/libdownloadable_filters.so"
-flag="0x00000200";type="metadata";name="http://developer.samsung.com/tizen/metadata/dictionary";path="/usr/etc/package-manager/parserlib/metadata/libdictionary.so"
-flag="0x00000400";type="category";name="http://tizen.org/category/antivirus";path="/usr/etc/package-manager/parserlib/category/libantivirus.so"
-flag="0x00000800";type="metadata";name="http://developer.samsung.com/tizen/metadata/profile";path="/usr/etc/package-manager/parserlib/metadata/libtheme.so"
-flag="0x00001000";type="category";name="http://tizen.org/category/tts";path="/usr/etc/package-manager/parserlib/category/libsamsung_tts.so"
+flag="0x00000020";type="category";name="http://tizen.org/category/downloadable_font";path="/etc/package-manager/parserlib/category/libdownloadable_font.so"
+flag="0x00000040";type="metadata";name="http://developer.samsung.com/tizen/metadata/sticker";path="/etc/package-manager/parserlib/metadata/libsticker.so"
+flag="0x00000080";type="metadata";name="http://developer.samsung.com/tizen/metadata/ttsengine";path="/etc/package-manager/parserlib/metadata/libttsengine.so"
+flag="0x00000100";type="metadata";name="http://developer.samsung.com/tizen/metadata/downloadable_filters";path="/etc/package-manager/parserlib/metadata/libdownloadable_filters.so"
+flag="0x00000200";type="metadata";name="http://developer.samsung.com/tizen/metadata/dictionary";path="/etc/package-manager/parserlib/metadata/libdictionary.so"
+flag="0x00000400";type="category";name="http://tizen.org/category/antivirus";path="/etc/package-manager/parserlib/category/libantivirus.so"
+flag="0x00000800";type="metadata";name="http://developer.samsung.com/tizen/metadata/profile";path="/etc/package-manager/parserlib/metadata/libtheme.so"
+flag="0x00001000";type="category";name="http://tizen.org/category/tts";path="/etc/package-manager/parserlib/category/libsamsung_tts.so"
 flag="0x00002000";type="tag";name="livebox";path="/etc/package-manager/parserlib/liblivebox.so"
 flag="0x00004000";type="tag";name="watch-application";path="/etc/package-manager/parserlib/libwatch-application.so"
 flag="0x00008000";type="tag";name="widget-application";path="/etc/package-manager/parserlib/libwidget-application.so"
diff --git a/src/common/plugins/types/category_plugin.cc b/src/common/plugins/types/category_plugin.cc
new file mode 100644 (file)
index 0000000..291ee1e
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/plugins/types/category_plugin.h"
+
+#include <pkgmgr_parser.h>
+
+#include <map>
+
+#include "common/utils/glist_range.h"
+
+namespace {
+
+std::string GetCategoryName(const std::string& url) {
+  return url.substr(url.find_last_of('/') + 1);
+}
+
+void ClearCategoryDetail(gpointer data) {
+  __category_t* category = reinterpret_cast<__category_t*>(data);
+  free(const_cast<char*>(category->name));
+  free(category);
+}
+
+}  // namespace
+
+namespace common_installer {
+
+const char CategoryPlugin::kType[] = "category";
+
+std::unique_ptr<CategoryPlugin> CategoryPlugin::Create(
+    const PluginInfo& plugin_info) {
+  std::unique_ptr<CategoryPlugin> plugin(new CategoryPlugin(plugin_info));
+  if (!plugin->Load())
+    return nullptr;
+  return plugin;
+}
+
+std::string CategoryPlugin::GetFunctionName(ActionType action) const {
+  static std::map<ActionType, std::string> names {
+    {ActionType::Install,  "PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL"},
+    {ActionType::Upgrade,  "PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE"},
+    {ActionType::Uninstall,  "PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL"},
+  };
+
+  auto pos = names.find(action);
+  if (pos == names.end()) {
+    LOG(ERROR) << "Function name not defined";
+    return "";
+  }
+  return pos->second;
+}
+
+bool CategoryPlugin::Run(xmlDocPtr /*doc_ptr*/, manifest_x* manifest,
+         ActionType action_type) {
+  std::string tag = GetCategoryName(plugin_info_.name());
+  if (tag.empty())
+    return false;
+  std::string name = GetFunctionName(action_type);
+  for (application_x* app : GListRange<application_x*>(manifest->application)) {
+    // pack all categories starting with key + '/' to list that will
+    // be sent to the plugin.
+    // e.g. all http://tizen.org/category/antivirus/*
+    //   will be packed for http://tizen.org/category/antivirus
+    GList* category_list = nullptr;
+    for (const char* category : GListRange<char*>(app->category)) {
+      std::string sub_key_prefix = plugin_info_.name() + "/";
+      if (std::string(category).find(sub_key_prefix) == 0) {
+        __category_t* c = reinterpret_cast<__category_t*>(
+            calloc(1, sizeof(__category_t)));
+        c->name = strdup(category);
+        category_list = g_list_append(category_list, c);
+      }
+    }
+    int result = 0;
+    Exec(name, &result, category_list, tag.c_str(),
+         ActionTypeToPkgmgrActionType(action_type),
+         manifest->package, app->appid);
+    if (result) {
+      LOG(ERROR) << "Function: " << name << " of plugin "
+                 << plugin_info_.path() << " failed";
+      g_list_free_full(category_list, &ClearCategoryDetail);
+      return false;
+    }
+    g_list_free_full(category_list, &ClearCategoryDetail);
+  }
+}
+
+}  // namespace common_installer
diff --git a/src/common/plugins/types/category_plugin.h b/src/common/plugins/types/category_plugin.h
new file mode 100644 (file)
index 0000000..833205f
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_PLUGINS_TYPES_CATEGORY_PLUGIN_H_
+#define COMMON_PLUGINS_TYPES_CATEGORY_PLUGIN_H_
+
+#include <string>
+
+#include "common/plugins/plugin.h"
+
+namespace common_installer {
+
+class CategoryPlugin : public Plugin {
+ public:
+  static const char kType[];
+
+  static std::unique_ptr<CategoryPlugin> Create(const PluginInfo& plugin_info);
+  bool Run(xmlDocPtr doc_ptr, manifest_x* manifest,
+           ActionType action_type) override;
+
+ private:
+  std::string GetFunctionName(ActionType action) const;
+
+  using Plugin::Plugin;
+
+  SCOPE_LOG_TAG(CategoryPlugin)
+};
+
+}  // namespace common_installer
+
+#endif  // COMMON_PLUGINS_TYPES_CATEGORY_PLUGIN_H_
diff --git a/src/common/plugins/types/metadata_plugin.cc b/src/common/plugins/types/metadata_plugin.cc
new file mode 100644 (file)
index 0000000..83ab117
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/plugins/types/metadata_plugin.h"
+
+#include <pkgmgr_parser.h>
+
+#include <map>
+
+#include "common/utils/glist_range.h"
+
+namespace {
+
+std::string GetMetadataTag(const std::string& url) {
+  return url.substr(url.find_last_of('/') + 1);
+}
+
+void ClearMetadataDetail(gpointer data) {
+  __metadata_t* meta = reinterpret_cast<__metadata_t*>(data);
+  free(const_cast<char*>(meta->key));
+  free(const_cast<char*>(meta->value));
+  free(meta);
+}
+
+}  // namespace
+
+namespace common_installer {
+
+const char MetadataPlugin::kType[] = "metadata";
+
+std::unique_ptr<MetadataPlugin> MetadataPlugin::Create(
+    const PluginInfo& plugin_info) {
+  std::unique_ptr<MetadataPlugin> plugin(new MetadataPlugin(plugin_info));
+  if (!plugin->Load())
+    return nullptr;
+  return plugin;
+}
+
+std::string MetadataPlugin::GetFunctionName(ActionType action) const {
+  static std::map<ActionType, std::string> names {
+    {ActionType::Install,  "PKGMGR_MDPARSER_PLUGIN_INSTALL"},
+    {ActionType::Upgrade,  "PKGMGR_MDPARSER_PLUGIN_UPGRADE"},
+    {ActionType::Uninstall,  "PKGMGR_MDPARSER_PLUGIN_UNINSTALL"},
+  };
+
+  auto pos = names.find(action);
+  if (pos == names.end()) {
+    LOG(ERROR) << "Function name not defined";
+    return "";
+  }
+  return pos->second;
+}
+
+bool MetadataPlugin::Run(xmlDocPtr /*doc_ptr*/, manifest_x* manifest,
+                         ActionType action_type) {
+  std::string tag = GetMetadataTag(plugin_info_.name());
+  if (tag.empty())
+    return false;
+  std::string name = GetFunctionName(action_type);
+  for (application_x* app : GListRange<application_x*>(manifest->application)) {
+    // pack all metadata starting with key + '/' to list that will
+    // be sent to the plugin.
+    // e.g. all http://developer.samsung.com/tizen/metadata/profile/*
+    //   will be packed for http://developer.samsung.com/tizen/metadata/profile
+    GList* md_list = nullptr;
+    for (metadata_x* meta : GListRange<metadata_x*>(app->metadata)) {
+      std::string sub_key_prefix = plugin_info_.name() + "/";
+      if (meta->key && meta->value &&
+          std::string(meta->key).find(sub_key_prefix) == 0) {
+        __metadata_t* md = reinterpret_cast<__metadata_t*>(
+            calloc(1, sizeof(__metadata_t)));
+        md->key = strdup(meta->key);
+        md->value = strdup(meta->value);
+        md_list = g_list_append(md_list, md);
+      }
+    }
+    int result = 0;
+    Exec(name, &result, md_list, tag.c_str(),
+         ActionTypeToPkgmgrActionType(action_type),
+         manifest->package, app->appid);
+    if (result) {
+      LOG(ERROR) << "Function: " << name << " of plugin "
+                 << plugin_info_.path() << " failed";
+      g_list_free_full(md_list, &ClearMetadataDetail);
+      return false;
+    }
+    g_list_free_full(md_list, &ClearMetadataDetail);
+  }
+  return true;
+}
+
+}  // namespace common_installer
diff --git a/src/common/plugins/types/metadata_plugin.h b/src/common/plugins/types/metadata_plugin.h
new file mode 100644 (file)
index 0000000..7d09b50
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_PLUGINS_TYPES_METADATA_PLUGIN_H_
+#define COMMON_PLUGINS_TYPES_METADATA_PLUGIN_H_
+
+#include <string>
+
+#include "common/plugins/plugin.h"
+
+namespace common_installer {
+
+class MetadataPlugin : public Plugin {
+ public:
+  static const char kType[];
+
+  static std::unique_ptr<MetadataPlugin> Create(const PluginInfo& plugin_info);
+  bool Run(xmlDocPtr doc_ptr, manifest_x* manifest,
+           ActionType action_type) override;
+
+ private:
+  std::string GetFunctionName(ActionType action) const;
+
+  using Plugin::Plugin;
+
+  SCOPE_LOG_TAG(MetadataPlugin)
+};
+
+}  // namespace common_installer
+
+#endif  // COMMON_PLUGINS_TYPES_METADATA_PLUGIN_H_
diff --git a/src/common/plugins/types/tag_plugin.cc b/src/common/plugins/types/tag_plugin.cc
new file mode 100644 (file)
index 0000000..7734312
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/plugins/types/tag_plugin.h"
+
+#include <map>
+#include <utility>
+
+namespace common_installer {
+
+const char TagPlugin::kType[] = "tag";
+
+std::unique_ptr<TagPlugin> TagPlugin::Create(const PluginInfo& plugin_info) {
+  std::unique_ptr<TagPlugin> plugin(new TagPlugin(plugin_info));
+  if (!plugin->Load())
+    return nullptr;
+  return plugin;
+}
+
+std::string TagPlugin::GetFunctionName(ProcessType process,
+                                       ActionType action) const {
+  static std::map<std::pair<ActionType, ProcessType>, std::string> names {
+    {{ActionType::Install,   ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_INSTALL"},   // NOLINT
+    {{ActionType::Upgrade,   ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_UPGRADE"},   // NOLINT
+    {{ActionType::Uninstall, ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL"}, // NOLINT
+    {{ActionType::Install,   ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_INSTALL"},       // NOLINT
+    {{ActionType::Upgrade,   ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_UPGRADE"},       // NOLINT
+    {{ActionType::Uninstall, ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_UNINSTALL"},     // NOLINT
+    {{ActionType::Install,   ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_INSTALL"},  // NOLINT
+    {{ActionType::Upgrade,   ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_UPGRADE"},  // NOLINT
+    {{ActionType::Uninstall, ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_UNINSTALL"} // NOLINT
+  };
+
+  auto pos = names.find(std::make_pair(action, process));
+  if (pos == names.end()) {
+    LOG(ERROR) << "Function name not defined";
+    return "";
+  }
+  return pos->second;
+}
+
+xmlDocPtr TagPlugin::CreateDocPtrForPlugin(xmlDocPtr doc_ptr,
+    const std::string& tag_name) const {
+  // Make copy of document and root node
+  xmlNodePtr root_node = xmlDocGetRootElement(doc_ptr);
+  if (!root_node) {
+    LOG(ERROR) << "Original document is empty. Cannot create copy for plugin";
+    return nullptr;
+  }
+  xmlDocPtr plugin_doc_ptr = xmlCopyDoc(doc_ptr, 0);
+  xmlNodePtr plugin_root_node = xmlCopyNode(root_node, 0);
+  xmlDocSetRootElement(plugin_doc_ptr, plugin_root_node);
+
+  // Append elements that matches the tag name to new doc
+  for (xmlNodePtr child = xmlFirstElementChild(root_node);
+       child != nullptr; child = xmlNextElementSibling(child)) {
+    if (tag_name == reinterpret_cast<const char*>(child->name)) {
+      xmlAddChild(plugin_root_node, xmlCopyNode(child, 1));
+    }
+  }
+  xmlSetTreeDoc(plugin_root_node, plugin_doc_ptr);
+  return plugin_doc_ptr;
+}
+
+bool TagPlugin::Run(xmlDocPtr doc_ptr, manifest_x* manifest,
+         ActionType action_type) {
+  xmlDocPtr plugin_doc_ptr = CreateDocPtrForPlugin(doc_ptr,
+                                                   plugin_info_.name());
+  if (!plugin_doc_ptr)
+    return false;
+
+  int result = 0;
+  std::string pre_function = GetFunctionName(ProcessType::Pre, action_type);
+  Exec(pre_function, &result, manifest->package);
+  if (result) {
+    LOG(ERROR) << "Function: " << pre_function << " of plugin "
+               << plugin_info_.path() << " failed";
+    xmlFreeDoc(plugin_doc_ptr);
+    return false;
+  }
+
+  std::string main_function = GetFunctionName(ProcessType::Main, action_type);
+  Exec(main_function, &result, plugin_doc_ptr, manifest->package);
+  if (result) {
+    LOG(ERROR) << "Function: " << main_function << " of plugin "
+               << plugin_info_.path() << " failed";
+    xmlFreeDoc(plugin_doc_ptr);
+    return false;
+  }
+
+  std::string post_function = GetFunctionName(ProcessType::Post, action_type);
+  Exec(post_function, &result, manifest->package);
+  if (result) {
+    LOG(ERROR) << "Function: " << post_function << " of plugin "
+               << plugin_info_.path() << " failed";
+    xmlFreeDoc(plugin_doc_ptr);
+    return false;
+  }
+
+  xmlFreeDoc(plugin_doc_ptr);
+  return true;
+}
+
+
+}  // namespace common_installer
diff --git a/src/common/plugins/types/tag_plugin.h b/src/common/plugins/types/tag_plugin.h
new file mode 100644 (file)
index 0000000..6d6e83d
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_PLUGINS_TYPES_TAG_PLUGIN_H_
+#define COMMON_PLUGINS_TYPES_TAG_PLUGIN_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include <memory>
+#include <string>
+
+#include "common/plugins/plugin.h"
+#include "common/plugins/plugin_list_parser.h"
+
+namespace common_installer {
+
+class TagPlugin : public Plugin {
+ public:
+  static const char kType[];
+
+  static std::unique_ptr<TagPlugin> Create(const PluginInfo& plugin_info);
+
+  bool Run(xmlDocPtr doc_ptr, manifest_x* manifest,
+           ActionType action_type) override;
+
+ private:
+  using Plugin::Plugin;
+  std::string GetFunctionName(ProcessType process, ActionType action) const;
+
+  /**
+   * @brief CreateDocPtrForPlugin
+   *        Create copy of xml document with nodes only matching requested
+   *        tag_name
+   * @param doc_ptr original doc ptr of document
+   * @param tag_name name of required node/nodes
+   * @return requested copy
+   */
+  xmlDocPtr CreateDocPtrForPlugin(xmlDocPtr doc_ptr,
+                                  const std::string& tag_name) const;
+
+  SCOPE_LOG_TAG(TagPlugin)
+};
+
+}  // namespace common_installer
+
+#endif  // COMMON_PLUGINS_TYPES_TAG_PLUGIN_H_
index dfc123d..4dad126 100644 (file)
@@ -7,79 +7,49 @@
 #include <string>
 #include <vector>
 
+#include "common/plugins/plugin_manager.h"
+
 namespace common_installer {
 namespace pkgmgr {
 
 StepRunParserPlugin::StepRunParserPlugin(
-    InstallerContext* context, PluginsLauncher::ActionType action_type)
+    InstallerContext* context, Plugin::ActionType action_type)
     : Step(context), action_type_(action_type) {}
 
 Step::Status StepRunParserPlugin::ProcessPlugins(
-    const boost::filesystem::path& xml_path) {
+    const boost::filesystem::path& xml_path, manifest_x* manifest,
+    Plugin::ActionType action_type) {
   // PLUGINS_LIST_FILE_PATH path generated from cmake
   const std::string listPath(PLUGINS_LIST_INSTALL_FILE_PATH);
 
-  // init plugin_manager
-  plugin_manager_.reset(new PluginManager(xml_path.string(), listPath));
-
-  if (!plugin_manager_->GenerateUnknownTagList()) {
-    LOG(ERROR) << "Error during generate unknown list, no exist file, path, "
-                  "invalid data format etc, chceck log";
+  PluginManager plugin_manager(xml_path.string(), listPath, manifest);
+  if (!plugin_manager.LoadPlugins()) {
+    LOG(ERROR) << "Loading plugins failed in progress";
     return Status::ERROR;
   }
+  plugin_manager.RunPlugins(action_type);
 
-  const PluginManager::TagList& plugins = plugin_manager_->UnknownTagList();
-
-  for (const std::shared_ptr<PluginInfo>& plugin : plugins) {
-    if (!plugin_manager_->Launch(plugin->path(), plugin->name(), action_type_,
-                                 context_->pkgid.get())) {
-      LOG(ERROR) << "Error during launch tag name: " << plugin->name()
-                 << " path: " << plugin->path();
-      // some plugins do not have all methods, so no return error (skip error)
-    } else {
-      // add plugin to array for undo process
-      if (action_type_ == PluginsLauncher::ActionType::Install) {
-        installed_plugins_.push_back(plugin);
-      }
-    }
-  }
-
-  LOG(INFO) << "Successfully processing plugins";
+  LOG(INFO) << "Processing plugins done";
   return Status::OK;
 }
 
 Step::Status StepRunParserPlugin::process() {
-  return ProcessPlugins(context_->xml_path.get());
+  return ProcessPlugins(context_->xml_path.get(), context_->manifest_data.get(),
+                        action_type_);
 }
 
 Step::Status StepRunParserPlugin::undo() {
-  switch (action_type_) {
-    case PluginsLauncher::ActionType::Install: {
-      if (installed_plugins_.empty()) {
-        // no installed plugins
-        return Status::OK;
-      }
-
-      for (const std::shared_ptr<PluginInfo>& plugin : installed_plugins_) {
-        if (!plugin_manager_->Launch(plugin->path(), plugin->name(),
-                                     PluginsLauncher::ActionType::Uninstall,
-                                     context_->pkgid.get())) {
-          LOG(ERROR) << "Error during uninstall tag name: " << plugin->name()
-                     << " path: " << plugin->path();
-        }
-      }
-      return Status::OK;
-    }
-    case PluginsLauncher::ActionType::Upgrade:
-      return ProcessPlugins(context_->backup_xml_path.get());
-    case PluginsLauncher::ActionType::Uninstall:
-      return ProcessPlugins(context_->xml_path.get());
-    default:
-      return Status::ERROR;
+  // For update, we need to reread configuration of old version of widget
+  // so running whole process from beginning
+  if (action_type_ == Plugin::ActionType::Install) {
+    ProcessPlugins(context_->xml_path.get(), context_->manifest_data.get(),
+                   Plugin::ActionType::Uninstall);
+  } else if (action_type_ == Plugin::ActionType::Upgrade) {
+    ProcessPlugins(context_->backup_xml_path.get(),
+                   context_->old_manifest_data.get(),
+                   Plugin::ActionType::Upgrade);
   }
-
-  // never happen only to avoid compilation warning
-  return Status::ERROR;
+  return Status::OK;
 }
 
 }  // namespace pkgmgr
index cc2977e..6e6c608 100644 (file)
@@ -5,11 +5,14 @@
 #ifndef COMMON_STEP_STEP_RUN_PARSER_PLUGINS_H_
 #define COMMON_STEP_STEP_RUN_PARSER_PLUGINS_H_
 
+#include <manifest_parser/utils/logging.h>
+
+#include <pkgmgrinfo_basic.h>
+
 #include <string>
 #include <vector>
 
-#include "common/plugins/plugin_manager.h"
-#include "manifest_parser/utils/logging.h"
+#include "common/plugins/plugin.h"
 #include "common/step/step.h"
 
 namespace common_installer {
@@ -18,20 +21,21 @@ namespace pkgmgr {
 class StepRunParserPlugin : public Step {
  public:
   explicit StepRunParserPlugin(InstallerContext* context,
-                               PluginsLauncher::ActionType action_type);
+                               Plugin::ActionType action_type);
 
   Step::Status process() override;
   Step::Status clean() { return Status::OK; }
   Step::Status undo() override;
   Step::Status precheck() { return Status::OK; }
 
-  SCOPE_LOG_TAG(RunParserPlugin)
-
  private:
-  Step::Status ProcessPlugins(const boost::filesystem::path& xml_path);
-  PluginsLauncher::ActionType action_type_;
-  std::vector<std::shared_ptr<PluginInfo>> installed_plugins_;
-  std::unique_ptr<PluginManager> plugin_manager_;
+  Step::Status ProcessPlugins(const boost::filesystem::path& xml_path,
+                              manifest_x* manifest,
+                              Plugin::ActionType action_type);
+
+  Plugin::ActionType action_type_;
+
+  SCOPE_LOG_TAG(RunParserPlugin)
 };
 
 }  // namespace pkgmgr
diff --git a/src/common/utils/dynamic_lib_handle.cc b/src/common/utils/dynamic_lib_handle.cc
deleted file mode 100644 (file)
index 6f99fd6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016 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/utils/dynamic_lib_handle.h"
-
-#include <memory>
-
-namespace common_installer {
-
-DynamicLibHandle::DynamicLibHandle() : lib_handle_(nullptr) {}
-
-bool DynamicLibHandle::Load(const boost::filesystem::path& path, int flags) {
-  if (lib_handle_) {
-    return true;
-  }
-
-  lib_handle_ = dlopen(path.c_str(), flags);
-  if (!lib_handle_) {
-    LOG(ERROR) << "Failed to open library: " << path << " (" << dlerror()
-               << ")";
-    return false;
-  }
-  return true;
-}
-
-void* DynamicLibHandle::GetSymbol(const std::string& name) const {
-  return dlsym(lib_handle_, name.c_str());
-}
-
-DynamicLibHandle::~DynamicLibHandle() {
-  if (lib_handle_) {
-    dlclose(lib_handle_);
-  }
-}
-
-}  // namespace common_installer
diff --git a/src/common/utils/dynamic_lib_handle.h b/src/common/utils/dynamic_lib_handle.h
deleted file mode 100644 (file)
index a648aeb..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2016 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_UTILS_DYNAMIC_LIB_HANDLE_H_
-#define COMMON_UTILS_DYNAMIC_LIB_HANDLE_H_
-
-#include <boost/filesystem/path.hpp>
-
-#include <dlfcn.h>
-#include <manifest_parser/utils/logging.h>
-
-#include <memory>
-#include <string>
-
-namespace common_installer {
-
-class DynamicLibHandle {
- public:
-  DynamicLibHandle();
-  bool Load(const boost::filesystem::path& path, int flags);
-
-  template <typename Ret, typename... Args>
-  bool Exec(const std::string& name, Ret* result, Args... args) const {
-    using PluginFunctionPtr = Ret (*)(Args...);
-    PluginFunctionPtr function =
-        reinterpret_cast<PluginFunctionPtr>(GetSymbol(name));
-
-    if (!function) {
-      LOG(WARNING) << "Failed to get symbol: " << name << " (" << dlerror()
-                   << ")";
-      return false;
-    }
-
-    LOG(DEBUG) << "Execute plugin function: " << name << "...";
-    *result = function(args...);
-    return true;
-  }
-
-  DynamicLibHandle(DynamicLibHandle&&) = default;
-  DynamicLibHandle& operator=(DynamicLibHandle&&) = default;
-
-  virtual ~DynamicLibHandle();
-
-  SCOPE_LOG_TAG(DynamicLibHandle)
-
- private:
-  void* GetSymbol(const std::string& name) const;
-  void* lib_handle_;
-};
-
-}  // namespace common_installer
-
-#endif  // COMMON_UTILS_DYNAMIC_LIB_HANDLE_H_