1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/plugins/plugin_manager.h"
7 #include <pkgmgr-info.h>
9 #include <boost/filesystem.hpp>
16 #include "common/plugins/plugin_factory.h"
17 #include "common/plugins/plugin_list_parser.h"
18 #include "common/plugins/plugin_xml_parser.h"
19 #include "common/plugins/category_plugin.h"
20 #include "common/plugins/metadata_plugin.h"
21 #include "common/plugins/tag_plugin.h"
22 #include "common/utils/glist_range.h"
26 bool IsSubKey(const std::string& subkey, const std::string& key) {
27 if (subkey.find(key) != 0)
29 if (subkey.size() != key.size() && subkey.at(key.size()) != '/')
34 bool AddPluginInfo(std::shared_ptr<common_installer::PluginInfo> plugin_info,
35 manifest_x* manifest) {
36 plugin_x *plugin = static_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
38 LOG(ERROR) << "out of memory";
41 plugin->pkgid = strdup(manifest->package);
42 plugin->plugin_type = strdup(plugin_info->type().c_str());
43 plugin->plugin_name = strdup(plugin_info->name().c_str());
44 if (!plugin->pkgid || !plugin->plugin_type || !plugin->plugin_name) {
45 LOG(ERROR) << "out of memory";
47 free(plugin->plugin_type);
48 free(plugin->plugin_name);
53 manifest->plugin = g_list_append(manifest->plugin, plugin);
59 namespace common_installer {
61 bool PluginManager::IsDataRemoved(const char* data_type,
62 const std::string& data) {
63 PkgQueryInterface pkg_query(pkgid_, uid_);
64 return pkg_query.IsPluginExecuted(data_type, data);
67 bool PluginManager::GenerateUnknownTagList(
68 std::vector<std::string>* xml_tags) {
69 if (!xml_parser_.Parse()) {
70 LOG(ERROR) << "Parse xml function error";
74 *xml_tags = xml_parser_.tags_list();
78 bool PluginManager::GeneratePluginInfoList(
79 PluginManager::PluginInfoList* plugin_info_list) {
80 if (!list_parser_.Parse()) {
81 LOG(ERROR) << "Parse list function error";
85 *plugin_info_list = list_parser_.PluginInfoList();
89 bool PluginManager::LoadPlugins(Plugin::ActionType action_type) {
90 std::vector<std::string> xml_tags;
91 if (!GenerateUnknownTagList(&xml_tags))
94 PluginInfoList plugin_info_list;
95 if (!GeneratePluginInfoList(&plugin_info_list))
98 PluginFactory factory;
100 std::sort(xml_tags.begin(), xml_tags.end());
102 // This loop loads plugin which are needed according to manifest file
103 // Different pkgmgr plugin types have different condition upon which they
105 LOG(DEBUG) << "Loading pkgmgr plugins...";
106 for (std::shared_ptr<PluginInfo> plugin_info : plugin_info_list) {
107 std::unique_ptr<Plugin> plugin;
108 if (plugin_info->type() == TagPlugin::kType) {
109 // load tag plugin only if tag exists in manifest file
110 auto iter = std::lower_bound(xml_tags.begin(), xml_tags.end(),
111 plugin_info->name());
112 if (iter != xml_tags.end() && *iter == plugin_info->name()) {
113 plugin = factory.CreatePluginByPluginInfo(*plugin_info);
115 LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
116 << " Plugin has been skipped.";
118 if (!AddPluginInfo(plugin_info, manifest_))
121 } else if (action_type == Plugin::ActionType::Upgrade) {
122 if (IsDataRemoved(TagPlugin::kType, plugin_info->name())) {
123 plugin = factory.CreatePluginByPluginInfo(*plugin_info,
124 Plugin::ActionType::Removed);
126 LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
127 << " Plugin has been skipped.";
130 } else if (plugin_info->type() == MetadataPlugin::kType) {
132 for (application_x* app : GListRange<application_x*>(
133 manifest_->application)) {
134 for (metadata_x* meta : GListRange<metadata_x*>(app->metadata)) {
135 if (IsSubKey(meta->key, plugin_info->name())) {
136 plugin = factory.CreatePluginByPluginInfo(*plugin_info);
138 LOG(WARNING) << "Failed to load plugin: "
139 << plugin_info->path()
140 << " Plugin has been skipped.";
148 if (!done && action_type == Plugin::ActionType::Upgrade &&
149 IsDataRemoved(MetadataPlugin::kType, plugin_info->name())) {
150 plugin = factory.CreatePluginByPluginInfo(*plugin_info,
151 Plugin::ActionType::Removed);
153 LOG(WARNING) << "Failed to load plugin: "
154 << plugin_info->path()
155 << " Plugin has been skipped.";
157 } else if (plugin_info->type() == CategoryPlugin::kType) {
159 for (application_x* app : GListRange<application_x*>(
160 manifest_->application)) {
161 for (const char* category : GListRange<char*>(app->category)) {
162 if (std::string(category).compare(plugin_info->name()) == 0) {
163 plugin = factory.CreatePluginByPluginInfo(*plugin_info);
165 LOG(WARNING) << "Failed to load plugin: "
166 << plugin_info->path()
167 << " Plugin has been skipped.";
176 if (!done && action_type == Plugin::ActionType::Upgrade &&
177 IsDataRemoved(CategoryPlugin::kType, plugin_info->name())) {
178 plugin = factory.CreatePluginByPluginInfo(*plugin_info,
179 Plugin::ActionType::Removed);
181 LOG(WARNING) << "Failed to load plugin: "
182 << plugin_info->path()
183 << " Plugin has been skipped.";
188 loaded_plugins_.push_back(std::move(plugin));
189 LOG(DEBUG) << "Loaded plugin: " << plugin_info->path();
195 bool PluginManager::RunPlugins(Plugin::ActionType action_type) {
196 LOG(DEBUG) << "Running pkgmgr plugins...";
197 for (auto& plugin : loaded_plugins_) {
198 bool success = plugin->Run(xml_parser_.doc_ptr(), manifest_, action_type);
200 bool vitalness = plugin->plugin_info().vitalness();
204 LOG(ERROR) << "plugin Run fail but installation is ongoing";
210 } // namespace common_installer