Integrating StepRunParserPlugin with PluginsLauncher/DynamicLibHandle 63/58363/17 accepted/tizen/mobile/20160212.002400 accepted/tizen/tv/20160212.002415 accepted/tizen/wearable/20160212.002442 submit/tizen/20160211.093134
authorLukasz Wartalowicz <l.wartalowic@samsung.com>
Fri, 29 Jan 2016 14:17:59 +0000 (15:17 +0100)
committerTomasz Iwanek <t.iwanek@samsung.com>
Thu, 11 Feb 2016 09:14:16 +0000 (10:14 +0100)
Change-Id: Iaaf1c62250d01573d1960cb1ff5ecdb9cfcf3850

13 files changed:
src/common/plugins_launcher.cc
src/common/plugins_launcher.h
src/common/plugins_list.txt.in
src/common/step/step_run_parser_plugins.cc
src/common/step/step_run_parser_plugins.h
src/common/utils/dynamic_lib_handle.cc
src/common/utils/dynamic_lib_handle.h
src/common/utils/plugin_list_parser.cc
src/common/utils/plugin_list_parser.h
src/common/utils/plugin_manager.cc
src/common/utils/plugin_manager.h
src/common/utils/plugin_xml_parser.cc
src/common/utils/plugin_xml_parser.h

index b9ed627..21e4705 100644 (file)
 
 namespace common_installer {
 
-bool PluginsLauncher::LaunchPlugin(const boost::filesystem::path& plugin_path,
-                                   xmlDocPtr docPtr, ActionType action,
-                                   const std::string& pkgId, int* result) {
-  LOG(DEBUG) << "Installing plugin: " << plugin_path;
-
-  std::unique_ptr<DynamicLibHandle> dl_handle =
-      DynamicLibHandle::Create(plugin_path, RTLD_LAZY | RTLD_LOCAL);
-  if (!dl_handle) {
+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.Create(plugin_path, RTLD_LAZY | RTLD_LOCAL)) {
     LOG(ERROR) << "Failed to create library handle";
-    return false;
+    return Error::FailedLibHandle;
   }
 
-  if (!RunPluginFunction(dl_handle.get(), ProcessType::PreInstall, action,
-                         pkgId.c_str(), result)) {
-    LOG(ERROR) << "Preinstall failed";
-    return false;
+  bool is_supported = false;
+
+  if (ExecPlugin(dlh, ProcessType::PreInstall, action, pkgId.c_str(),
+                  result)) {
+    is_supported = true;
   }
 
-  if (!RunPluginFunction(dl_handle.get(), ProcessType::Install, action,
-                         docPtr, pkgId.c_str(), result)) {
-    LOG(ERROR) << "Install failed";
-    return false;
+  if (ExecPlugin(dlh, ProcessType::Install, action, docPtr, pkgId.c_str(),
+                  result)) {
+    is_supported = true;
   }
-  if (!RunPluginFunction(dl_handle.get(), ProcessType::PostInstall, action,
-                         pkgId.c_str(), result)) {
-    LOG(ERROR) << "Postinstall failed";
-    return false;
+
+  if (ExecPlugin(dlh, ProcessType::PostInstall, action, pkgId.c_str(),
+                  result)) {
+    is_supported = true;
   }
-  return true;
+
+  if (!is_supported) {
+    return Error::ActionNotSupported;
+  }
+
+  return Error::Success;
 }
 
-bool PluginsLauncher::GetName(ProcessType process, ActionType action,
+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::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
+    {{ActionType::Uninstall, ProcessType::PostInstall}, "PKGMGR_PARSER_PLUGIN_POST_UNINSTALL"} // NOLINT
   };
 
   auto pos = names.find(std::make_pair(action, process));
@@ -65,18 +70,16 @@ bool PluginsLauncher::GetName(ProcessType process, ActionType action,
   return true;
 }
 
-bool PluginsLauncher::RunPluginFunction(DynamicLibHandle* dl_handle,
-                                        ProcessType process, ActionType action,
-                                        const char* pkgId, int* result) {
-  return RunPluginFunctionImpl(dl_handle, process, action, result, pkgId);
+bool PluginsLauncher::ExecPlugin(DynamicLibHandle& dlh, ProcessType process,
+                                 ActionType action, const char* pkgId,
+                                 int* result) {
+  return ExecPluginImpl(dlh, process, action, result, pkgId);
 }
 
-bool PluginsLauncher::RunPluginFunction(DynamicLibHandle* dl_handle,
-                                        ProcessType process, ActionType action,
-                                        xmlDocPtr docPtr, const char* pkgId,
-                                        int* result) {
-  return RunPluginFunctionImpl(dl_handle, process, action, result, docPtr,
-                               pkgId);
+bool PluginsLauncher::ExecPlugin(DynamicLibHandle& dlh, ProcessType process,
+                                 ActionType action, xmlDocPtr docPtr,
+                                 const char* pkgId, int* result) {
+  return ExecPluginImpl(dlh, process, action, result, docPtr, pkgId);
 }
 
 }  // namespace common_installer
index 9849ae5..2aa0d59 100644 (file)
 #include <string>
 #include <memory>
 
-#include "utils/dynamic_lib_handle.h"
+#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 };
 
-  bool LaunchPlugin(const boost::filesystem::path& plugin_path,
-                    xmlDocPtr docPtr, ActionType action,
-                    const std::string& pkgId, int* result);
+  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:
-  std::string GetPath(const std::string& plugin);
-  bool GetName(ProcessType process, ActionType action, std::string* result);
+  bool FunctionName(ProcessType process, ActionType action,
+                    std::string* result);
 
-  bool RunPluginFunction(DynamicLibHandle* dl_handle, ProcessType process,
-                         ActionType action, const char *pkgId, int *result);
+  bool ExecPlugin(DynamicLibHandle& dlh, ProcessType process, ActionType action,
+                  const char* pkgId, int* result);
 
-  bool RunPluginFunction(DynamicLibHandle* dl_handle, ProcessType process,
-                         ActionType action, xmlDocPtr docPtr, const char* pkgId,
-                         int *result);
+  bool ExecPlugin(DynamicLibHandle& dlh, ProcessType process, ActionType action,
+                  xmlDocPtr docPtr, const char* pkgId, int* result);
 
   template <typename... Args>
-  bool RunPluginFunctionImpl(DynamicLibHandle* dl_handle, ProcessType process,
-                             ActionType action, int *result, Args&&... args) {
+  bool ExecPluginImpl(DynamicLibHandle& dlh, ProcessType process,
+                      ActionType action, int* result, Args&&... args) {
     std::string name;
-    if (!GetName(process, action, &name)) {
+    if (!FunctionName(process, action, &name)) {
       LOG(ERROR) << "Error during getting function name";
       return false;
     }
-    return dl_handle->run(name, result, std::forward<Args>(args)...);
+    return dlh.Exec(name, result, std::forward<Args>(args)...);
   }
 
   SCOPE_LOG_TAG(PluginsLauncher)
index 2355da3..2d7f8ac 100644 (file)
@@ -1,8 +1,8 @@
-flag="0x00000001";type="tag";name="shortcut-list";path="/usr/etc/package-manager/parserlib/libshortcut-list.so"
-flag="0x00000002";type="tag";name="account";path="/usr/etc/package-manager/parserlib/libaccount.so"
-flag="0x00000004";type="tag";name="notifications";path="/usr/etc/package-manager/parserlib/libnotifications.so"
-flag="0x00000008";type="tag";name="privileges";path="/usr/etc/package-manager/parserlib/libprivileges.so"
-flag="0x00000010";type="tag";name="ime";path="/usr/etc/package-manager/parserlib/libime.so"
+flag="0x00000001";type="tag";name="shortcut-list";path="/etc/package-manager/parserlib/libshortcut-list.so"
+flag="0x00000002";type="tag";name="account";path="/etc/package-manager/parserlib/libaccount.so"
+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"
@@ -11,6 +11,6 @@ flag="0x00000200";type="metadata";name="http://developer.samsung.com/tizen/metad
 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="0x00002000";type="tag";name="livebox";path="/usr/etc/package-manager/parserlib/liblivebox.so"
-flag="0x00004000";type="tag";name="watch-application";path="/usr/etc/package-manager/parserlib/libwatch-application.so"
-flag="0x00008000";type="tag";name="widget-application";path="/usr/etc/package-manager/parserlib/libwidget-application.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"
index a1b9945..4bd40a7 100644 (file)
 namespace common_installer {
 namespace pkgmgr {
 
-StepRunParserPlugin::StepRunParserPlugin(InstallerContext* context,
-                                         ActionType action_type)
+StepRunParserPlugin::StepRunParserPlugin(
+    InstallerContext* context, PluginsLauncher::ActionType action_type)
     : Step(context), action_type_(action_type) {}
 
-Step::Status StepRunParserPlugin::ProcessingPlugins(
+Step::Status StepRunParserPlugin::ProcessPlugins(
     const boost::filesystem::path& xml_path) {
   // PLUGINS_LIST_FILE_PATH path generated from cmake
   const std::string listPath(PLUGINS_LIST_INSTALL_FILE_PATH);
@@ -28,19 +28,19 @@ Step::Status StepRunParserPlugin::ProcessingPlugins(
     return Status::ERROR;
   }
 
-  std::vector<std::shared_ptr<PluginInfo>> plugins =
-      plugin_manager_->UnknownTagList();
+  const PluginManager::TagList& plugins = plugin_manager_->UnknownTagList();
 
   for (const std::shared_ptr<PluginInfo>& plugin : plugins) {
-    if (!plugin_manager_->Launch(plugin->path(), action_type_,
+    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();
-      return Status::ERROR;
-    }
-    // add plugin to array for undo process
-    if (action_type_ == ActionType::Install) {
-      installed_plugins_.push_back(plugin);
+      // 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);
+      }
     }
   }
 
@@ -49,29 +49,37 @@ Step::Status StepRunParserPlugin::ProcessingPlugins(
 }
 
 Step::Status StepRunParserPlugin::process() {
-  return ProcessingPlugins(context_->xml_path.get());
+  return ProcessPlugins(context_->xml_path.get());
 }
 
 Step::Status StepRunParserPlugin::undo() {
-  if (action_type_ == ActionType::Install) {
-    if (installed_plugins_.empty()) {
-      // no installed plugins
-      return Status::OK;
-    }
+  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(), ActionType::Uninstall,
-                                   context_->pkgid.get())) {
-        LOG(ERROR) << "Error during uninstall tag name: " << plugin->name()
-                   << " path: " << plugin->path();
+      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;
     }
-  } else if (action_type_ == ActionType::Upgrade) {
-    return ProcessingPlugins(context_->backup_xml_path.get());
-  } else if (action_type_ == ActionType::Uninstall) {
-    return ProcessingPlugins(context_->xml_path.get());
+    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;
   }
-  return Status::OK;
+
+  // never happen only to avoid compilation warning
+  return Status::ERROR;
 }
 
 }  // namespace pkgmgr
index 9d5fb6e..009601a 100644 (file)
@@ -18,7 +18,7 @@ namespace pkgmgr {
 class StepRunParserPlugin : public Step {
  public:
   explicit StepRunParserPlugin(InstallerContext* context,
-                               ActionType action_type);
+                               PluginsLauncher::ActionType action_type);
 
   Step::Status process() override;
   Step::Status clean() { return Status::OK; }
@@ -28,8 +28,8 @@ class StepRunParserPlugin : public Step {
   SCOPE_LOG_TAG(RunParserPlugin)
 
  private:
-  Step::Status ProcessingPlugins(const boost::filesystem::path& xml_path);
-  ActionType action_type_;
+  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_;
 };
index 7cdb4b4..50a0fee 100644 (file)
@@ -10,17 +10,11 @@ namespace common_installer {
 
 DynamicLibHandle::DynamicLibHandle() : lib_handle_(nullptr) {}
 
-std::unique_ptr<DynamicLibHandle> DynamicLibHandle::Create(
-    const boost::filesystem::path& path, int flags) {
-  std::unique_ptr<DynamicLibHandle> new_handle(new DynamicLibHandle);
-  if (!new_handle->CreateImpl(path, flags)) {
-    return nullptr;
+bool DynamicLibHandle::Create(const boost::filesystem::path& path, int flags) {
+  if (lib_handle_) {
+    return true;
   }
-  return new_handle;
-}
 
-bool DynamicLibHandle::CreateImpl(const boost::filesystem::path& path,
-                                  int flags) {
   lib_handle_ = dlopen(path.c_str(), flags);
   if (!lib_handle_) {
     LOG(ERROR) << "Failed to open library: " << path << " (" << dlerror()
@@ -34,6 +28,10 @@ void* DynamicLibHandle::GetSymbol(const std::string& name) {
   return dlsym(lib_handle_, name.c_str());
 }
 
-DynamicLibHandle::~DynamicLibHandle() { dlclose(lib_handle_); }
+DynamicLibHandle::~DynamicLibHandle() {
+  if (lib_handle_) {
+    dlclose(lib_handle_);
+  }
+}
 
 }  // namespace common_installer
index 0dbafc7..642273f 100644 (file)
@@ -17,34 +17,34 @@ namespace common_installer {
 
 class DynamicLibHandle {
  public:
-  static std::unique_ptr<DynamicLibHandle> Create(
-      const boost::filesystem::path& path, int flags);
+  DynamicLibHandle();
+  bool Create(const boost::filesystem::path& path, int flags);
 
   template <typename Ret, typename... Args>
-  bool run(const std::string& name, Ret* result, Args&&... args) {
+  bool Exec(const std::string& name, Ret* result, Args... args) {
     using PluginFunctionPtr = Ret (*)(Args...);
-    auto function = reinterpret_cast<PluginFunctionPtr>(GetSymbol(name));
+    PluginFunctionPtr function =
+        reinterpret_cast<PluginFunctionPtr>(GetSymbol(name));
 
     if (!function) {
-      LOG(ERROR) << "Failed to get symbol: " << name <<" (" << dlerror() << ")";
+      LOG(WARNING) << "Failed to get symbol: " << name << " (" << dlerror()
+                   << ")";
       return false;
     }
 
-    *result = function(std::forward<Args>(args)...);
+    LOG(DEBUG) << "Execute plugin function: " << name << "...";
+    *result = function(args...);
     return true;
   }
 
   DynamicLibHandle(DynamicLibHandle&&) = default;
   DynamicLibHandle& operator=(DynamicLibHandle&&) = default;
 
-  ~DynamicLibHandle();
+  virtual ~DynamicLibHandle();
 
   SCOPE_LOG_TAG(DynamicLibHandle)
 
  private:
-  DynamicLibHandle();
-  bool CreateImpl(const boost::filesystem::path& path, int flags);
-
   void* GetSymbol(const std::string& name);
   void* lib_handle_;
 };
index c3f99b2..ddb458d 100644 (file)
@@ -125,8 +125,7 @@ bool PluginsListParser::Parse() {
   return true;
 }
 
-const std::vector<std::shared_ptr<PluginInfo>>&
-PluginsListParser::PluginInfoList() {
+const PluginsListParser::PluginList& PluginsListParser::PluginInfoList() {
   return plugin_info_list_;
 }
 
index 6deed4d..88c4181 100644 (file)
@@ -45,10 +45,11 @@ class PluginInfo {
 /** this class parse plugin file */
 class PluginsListParser {
  public:
+  using PluginList = std::vector<std::shared_ptr<PluginInfo>>;
   explicit PluginsListParser(const std::string& path) : path_(path) {}
 
   bool Parse();
-  const std::vector<std::shared_ptr<PluginInfo>>& PluginInfoList();
+  const PluginList& PluginInfoList();
 
  private:
   enum Column { Flag, Type, Name, Path };
index 7a41bfe..36d2114 100644 (file)
@@ -28,7 +28,7 @@ bool PluginManager::GenerateUnknownTagList() {
     return false;
   }
 
-  const std::vector<std::shared_ptr<PluginInfo>> pluginInfoList =
+  const PluginsListParser::PluginList& pluginInfoList =
       list_parser_.PluginInfoList();
 
   for (std::shared_ptr<PluginInfo> pluginInfo : pluginInfoList) {
@@ -60,19 +60,63 @@ bool PluginManager::GenerateUnknownTagList() {
   return true;
 }
 
-const std::vector<std::shared_ptr<PluginInfo>>&
-PluginManager::UnknownTagList() {
-  return tags_;
+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));
+    }
+  }
+  xmlSetTreeDoc(plugin_root_node, plugin_doc_ptr);
+  return plugin_doc_ptr;
 }
 
 bool PluginManager::Launch(const boost::filesystem::path& plugin_path,
-                           ActionType action_type, const std::string& pkg_Id) {
-  // TODO(l.wartalowic) add implementation
+                           const std::string& tag_name,
+                           PluginsLauncher::ActionType action_type,
+                           const std::string& pkg_Id) {
   LOG(INFO) << "Launching plugin path:" << plugin_path << " pkgId: " << pkg_Id;
-  (void)plugin_path;
-  (void)action_type;
-  (void)pkg_Id;
-  return true;
+
+  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;
+  }
 }
 
 }  // namespace common_installer
index 425bf09..0365d36 100644 (file)
 
 #include "common/utils/plugin_xml_parser.h"
 #include "common/utils/plugin_list_parser.h"
+#include "common/plugins_launcher.h"
 
 namespace common_installer {
 
-enum class ActionType { Install, Upgrade, Uninstall };
-
 /** 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) {}
 
   bool GenerateUnknownTagList();
-  const std::vector<std::shared_ptr<PluginInfo>>& UnknownTagList();
-  bool Launch(const boost::filesystem::path& pluginPath, ActionType actionType,
-              const std::string& pkgId);
+  const TagList& UnknownTagList();
+  bool Launch(const boost::filesystem::path& pluginPath,
+              const std::string& tag_name,
+              PluginsLauncher::ActionType actionType, const std::string& pkgId);
 
  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_;
   PluginsXmlParser xml_parser_;
   PluginsListParser list_parser_;
+  PluginsLauncher plugins_launcher_;
 };
 }  // namespace common_installer
 
index a92e6da..1661e53 100644 (file)
@@ -12,9 +12,14 @@ bool PluginsXmlParser::Parse() {
     return false;
   }
 
+  doc_ptr_ = xmlReadFile(path_.c_str(), nullptr, 0);
+  if (!doc_ptr_) {
+    return false;
+  }
+
   WrapperXMLReader obj_reader;
 
-  xmlTextReaderPtr reader = obj_reader.Create(path_.c_str());
+  xmlTextReaderPtr reader = obj_reader.Create(doc_ptr_);
 
   if (!reader) {
     return false;
@@ -41,13 +46,6 @@ bool PluginsXmlParser::Parse() {
 
   tags_.assign(tags.begin(), tags.end());
 
-  // get here, after end of a "reading" file
-  doc_ptr_ = xmlTextReaderCurrentDoc(reader);
-
-  if (!doc_ptr_) {
-    return false;
-  }
-
   return true;
 }
 
index 112960d..97d193e 100644 (file)
@@ -33,8 +33,8 @@ class PluginsXmlParser {
    public:
     WrapperXMLReader() : reader_(nullptr) {}
 
-    xmlTextReaderPtr Create(const std::string& path) {
-      reader_ = xmlReaderForFile(path.c_str(), nullptr, 0);
+    xmlTextReaderPtr Create(const xmlDocPtr doc_ptr_) {
+      reader_ = xmlReaderWalker(doc_ptr_);
       return reader_;
     }
     virtual ~WrapperXMLReader() {