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>
14 #include "common/plugins/plugin_factory.h"
15 #include "common/plugins/plugin_list_parser.h"
16 #include "common/plugins/plugin_xml_parser.h"
17 #include "common/plugins/category_plugin.h"
18 #include "common/plugins/metadata_plugin.h"
19 #include "common/plugins/tag_plugin.h"
20 #include "common/utils/glist_range.h"
24 bool IsSubKey(const std::string& subkey, const std::string& key) {
25 if (subkey.find(key) != 0)
27 if (subkey.size() != key.size() && subkey.at(key.size()) != '/')
32 bool AddPluginInfo(std::shared_ptr<common_installer::PluginInfo> plugin_info,
33 manifest_x* manifest) {
34 plugin_x *plugin = static_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
36 LOG(ERROR) << "out of memory";
39 plugin->pkgid = strdup(manifest->package);
40 plugin->plugin_type = strdup(plugin_info->type().c_str());
41 plugin->plugin_name = strdup(plugin_info->name().c_str());
42 if (!plugin->pkgid || !plugin->plugin_type || !plugin->plugin_name) {
43 LOG(ERROR) << "out of memory";
45 free(plugin->plugin_type);
46 free(plugin->plugin_name);
51 manifest->plugin = g_list_append(manifest->plugin, plugin);
57 namespace common_installer {
59 bool PluginManager::IsDataRemoved(const char* data_type,
60 const std::string& data) {
61 PkgQueryInterface pkg_query(pkgid_, uid_);
62 return pkg_query.IsPluginExecuted(data_type, data);
65 bool PluginManager::GenerateUnknownTagList(
66 std::vector<std::string>* xml_tags) {
67 if (!xml_parser_.Parse()) {
68 LOG(ERROR) << "Parse xml function error";
72 *xml_tags = xml_parser_.tags_list();
76 bool PluginManager::GeneratePluginInfoList(
77 PluginManager::PluginInfoList* plugin_info_list) {
78 if (!list_parser_.Parse()) {
79 LOG(ERROR) << "Parse list function error";
83 *plugin_info_list = list_parser_.PluginInfoList();
87 bool PluginManager::LoadPlugins(Plugin::ActionType action_type) {
88 std::vector<std::string> xml_tags;
89 if (!GenerateUnknownTagList(&xml_tags))
92 PluginInfoList plugin_info_list;
93 if (!GeneratePluginInfoList(&plugin_info_list))
96 PluginFactory factory;
98 std::sort(xml_tags.begin(), xml_tags.end());
100 // This loop loads plugin which are needed according to manifest file
101 // Different pkgmgr plugin types have different condition upon which they
103 LOG(DEBUG) << "Loading pkgmgr plugins...";
104 for (std::shared_ptr<PluginInfo> plugin_info : plugin_info_list) {
105 std::unique_ptr<Plugin> plugin;
106 if (plugin_info->type() == TagPlugin::kType) {
107 // load tag plugin only if tag exists in manifest file
108 auto iter = std::lower_bound(xml_tags.begin(), xml_tags.end(),
109 plugin_info->name());
110 if (iter != xml_tags.end() && *iter == plugin_info->name()) {
111 plugin = factory.CreatePluginByPluginInfo(*plugin_info);
113 LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
114 << " Plugin has been skipped.";
116 if (!AddPluginInfo(plugin_info, manifest_))
119 } else if (action_type == Plugin::ActionType::Upgrade) {
120 if (IsDataRemoved(TagPlugin::kType, plugin_info->name())) {
121 plugin = factory.CreatePluginByPluginInfo(*plugin_info,
122 Plugin::ActionType::Removed);
124 LOG(WARNING) << "Failed to load plugin: " << plugin_info->path()
125 << " Plugin has been skipped.";
128 } else if (plugin_info->type() == MetadataPlugin::kType) {
130 for (application_x* app : GListRange<application_x*>(
131 manifest_->application)) {
132 for (metadata_x* meta : GListRange<metadata_x*>(app->metadata)) {
133 if (IsSubKey(meta->key, plugin_info->name())) {
134 plugin = factory.CreatePluginByPluginInfo(*plugin_info);
136 LOG(WARNING) << "Failed to load plugin: "
137 << plugin_info->path()
138 << " Plugin has been skipped.";
146 /* metadata of package, since Tizen 7.5 */
147 for (metadata_x* meta : GListRange<metadata_x*>(manifest_->metadata)) {
148 if (IsSubKey(meta->key, plugin_info->name())) {
149 plugin = factory.CreatePluginByPluginInfo(*plugin_info);
151 LOG(WARNING) << "Failed to load plugin: "
152 << plugin_info->path()
153 << " Plugin has been skipped.";
157 if (!done && action_type == Plugin::ActionType::Upgrade &&
158 IsDataRemoved(MetadataPlugin::kType, plugin_info->name())) {
159 plugin = factory.CreatePluginByPluginInfo(*plugin_info,
160 Plugin::ActionType::Removed);
162 LOG(WARNING) << "Failed to load plugin: "
163 << plugin_info->path()
164 << " Plugin has been skipped.";
166 } else if (plugin_info->type() == CategoryPlugin::kType) {
168 for (application_x* app : GListRange<application_x*>(
169 manifest_->application)) {
170 for (const char* category : GListRange<char*>(app->category)) {
171 if (std::string(category).compare(plugin_info->name()) == 0) {
172 plugin = factory.CreatePluginByPluginInfo(*plugin_info);
174 LOG(WARNING) << "Failed to load plugin: "
175 << plugin_info->path()
176 << " Plugin has been skipped.";
185 if (!done && action_type == Plugin::ActionType::Upgrade &&
186 IsDataRemoved(CategoryPlugin::kType, plugin_info->name())) {
187 plugin = factory.CreatePluginByPluginInfo(*plugin_info,
188 Plugin::ActionType::Removed);
190 LOG(WARNING) << "Failed to load plugin: "
191 << plugin_info->path()
192 << " Plugin has been skipped.";
197 loaded_plugins_.push_back(std::move(plugin));
198 LOG(DEBUG) << "Loaded plugin: " << plugin_info->path();
204 bool PluginManager::RunPlugins(Plugin::ActionType action_type) {
205 LOG(DEBUG) << "Running pkgmgr plugins...";
206 for (auto& plugin : loaded_plugins_) {
207 auto& plugin_info = plugin->plugin_info();
208 LOG(INFO) << "Running plugin: " << plugin_info.path();
209 bool success = plugin->Run(xml_parser_.doc_ptr(), manifest_, action_type);
211 bool vitalness = plugin_info.vitalness();
213 LOG(ERROR) << plugin_info.path() << " fails";
216 LOG(ERROR) << plugin_info.path()
217 << " fails but installation is ongoing";
224 } // namespace common_installer