Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / plugins / plugin_manager.cc
index e260bfc..550d6d8 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "common/plugins/plugin_manager.h"
 
-#include <boost/filesystem.hpp>
+#include <pkgmgr-info.h>
 
 #include <algorithm>
 #include <string>
 #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/plugins/category_plugin.h"
+#include "common/plugins/metadata_plugin.h"
+#include "common/plugins/tag_plugin.h"
 #include "common/utils/glist_range.h"
 
+namespace {
+
+bool IsSubKey(const std::string& subkey, const std::string& key) {
+  if (subkey.find(key) != 0)
+    return false;
+  if (subkey.size() != key.size() && subkey.at(key.size()) != '/')
+    return false;
+  return true;
+}
+
+bool AddPluginInfo(std::shared_ptr<common_installer::PluginInfo> plugin_info,
+                   manifest_x* manifest) {
+  plugin_x *plugin = static_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
+  if (!plugin) {
+    LOG(ERROR) << "out of memory";
+    return false;
+  }
+  plugin->pkgid = strdup(manifest->package);
+  plugin->plugin_type = strdup(plugin_info->type().c_str());
+  plugin->plugin_name = strdup(plugin_info->name().c_str());
+  if (!plugin->pkgid || !plugin->plugin_type || !plugin->plugin_name) {
+    LOG(ERROR) << "out of memory";
+    free(plugin->pkgid);
+    free(plugin->plugin_type);
+    free(plugin->plugin_name);
+    free(plugin);
+    return false;
+  }
+
+  manifest->plugin = g_list_append(manifest->plugin, plugin);
+  return true;
+}
+
+}  // namespace
+
 namespace common_installer {
 
+bool PluginManager::IsDataRemoved(const char* data_type,
+                                  const std::string& data) {
+  PkgQueryInterface pkg_query(pkgid_, uid_);
+  return pkg_query.IsPluginExecuted(data_type, data);
+}
+
 bool PluginManager::GenerateUnknownTagList(
     std::vector<std::string>* xml_tags) {
   if (!xml_parser_.Parse()) {
@@ -43,7 +84,7 @@ bool PluginManager::GeneratePluginInfoList(
   return true;
 }
 
-bool PluginManager::LoadPlugins() {
+bool PluginManager::LoadPlugins(Plugin::ActionType action_type) {
   std::vector<std::string> xml_tags;
   if (!GenerateUnknownTagList(&xml_tags))
     return false;
@@ -71,6 +112,17 @@ bool PluginManager::LoadPlugins() {
         if (!plugin) {
           LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
                      << " Plugin has been skipped.";
+        } else {
+          if (!AddPluginInfo(plugin_info, manifest_))
+            return false;
+        }
+      } else if (action_type == Plugin::ActionType::Upgrade) {
+        if (IsDataRemoved(TagPlugin::kType, plugin_info->name())) {
+          plugin = factory.CreatePluginByPluginInfo(*plugin_info,
+              Plugin::ActionType::Removed);
+          if (!plugin)
+            LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
+                         << " Plugin has been skipped.";
         }
       }
     } else if (plugin_info->type() == MetadataPlugin::kType) {
@@ -78,12 +130,12 @@ bool PluginManager::LoadPlugins() {
       for (application_x* app : GListRange<application_x*>(
            manifest_->application)) {
         for (metadata_x* meta : GListRange<metadata_x*>(app->metadata)) {
-          if (std::string(meta->key).compare(plugin_info->name()) == 0) {
+          if (IsSubKey(meta->key, plugin_info->name())) {
             plugin = factory.CreatePluginByPluginInfo(*plugin_info);
-            if (!plugin) {
-              LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
-                         << " Plugin has been skipped.";
-            }
+            if (!plugin)
+              LOG(WARNING) << "Failed to load plugin: "
+                           << plugin_info->path()
+                           << " Plugin has been skipped.";
             done = true;
             break;
           }
@@ -91,6 +143,26 @@ bool PluginManager::LoadPlugins() {
         if (done)
           break;
       }
+      /* metadata of package, since Tizen 7.5 */
+      for (metadata_x* meta : GListRange<metadata_x*>(manifest_->metadata)) {
+        if (IsSubKey(meta->key, plugin_info->name())) {
+          plugin = factory.CreatePluginByPluginInfo(*plugin_info);
+          if (!plugin)
+            LOG(WARNING) << "Failed to load plugin: "
+                         << plugin_info->path()
+                         << " Plugin has been skipped.";
+          break;
+        }
+      }
+      if (!done && action_type == Plugin::ActionType::Upgrade &&
+          IsDataRemoved(MetadataPlugin::kType, plugin_info->name())) {
+        plugin = factory.CreatePluginByPluginInfo(*plugin_info,
+            Plugin::ActionType::Removed);
+        if (!plugin)
+          LOG(WARNING) << "Failed to load plugin: "
+                       << plugin_info->path()
+                       << " Plugin has been skipped.";
+      }
     } else if (plugin_info->type() == CategoryPlugin::kType) {
       bool done = false;
       for (application_x* app : GListRange<application_x*>(
@@ -99,8 +171,9 @@ bool PluginManager::LoadPlugins() {
           if (std::string(category).compare(plugin_info->name()) == 0) {
             plugin = factory.CreatePluginByPluginInfo(*plugin_info);
             if (!plugin) {
-              LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
-                         << " Plugin has been skipped.";
+              LOG(WARNING) << "Failed to load plugin: "
+                           << plugin_info->path()
+                           << " Plugin has been skipped.";
             }
             done = true;
             break;
@@ -109,6 +182,15 @@ bool PluginManager::LoadPlugins() {
         if (done)
           break;
       }
+      if (!done && action_type == Plugin::ActionType::Upgrade &&
+          IsDataRemoved(CategoryPlugin::kType, plugin_info->name())) {
+        plugin = factory.CreatePluginByPluginInfo(*plugin_info,
+            Plugin::ActionType::Removed);
+        if (!plugin)
+          LOG(WARNING) << "Failed to load plugin: "
+                       << plugin_info->path()
+                       << " Plugin has been skipped.";
+      }
     }
 
     if (plugin) {
@@ -119,13 +201,24 @@ bool PluginManager::LoadPlugins() {
   return true;
 }
 
-void PluginManager::RunPlugins(Plugin::ActionType action_type) {
+bool 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);
+    auto& plugin_info = plugin->plugin_info();
+    LOG(INFO) << "Running plugin: " << plugin_info.path();
+    bool success = plugin->Run(xml_parser_.doc_ptr(), manifest_, action_type);
+    if (!success) {
+      bool vitalness = plugin_info.vitalness();
+      if (vitalness) {
+        LOG(ERROR) << plugin_info.path() << " fails";
+        return false;
+      } else {
+        LOG(ERROR) << plugin_info.path()
+                   << " fails but installation is ongoing";
+      }
+    }
   }
+  return true;
 }
 
 }  // namespace common_installer