#include <algorithm>
#include <map>
#include <set>
+#include <utility>
#include "common/utils/glist_range.h"
free(meta);
}
+GList* GetMetadataListForKey(GList* list, const std::string& key) {
+ // 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*>(list)) {
+ if (meta->key && meta->value &&
+ std::string(meta->key).find(key) == 0) {
+ __metadata_t* md = reinterpret_cast<__metadata_t*>(
+ calloc(1, sizeof(__metadata_t)));
+ if (!md) {
+ LOG(ERROR) << "Out of memory";
+ g_list_free_full(md_list, &ClearMetadataDetail);
+ return nullptr;
+ }
+ md->key = strdup(meta->key);
+ if (!md->key) {
+ LOG(ERROR) << "Out of memory";
+ free(md);
+ g_list_free_full(md_list, &ClearMetadataDetail);
+ return nullptr;
+ }
+ md->value = strdup(meta->value);
+ if (!md->value) {
+ LOG(ERROR) << "Out of memory";
+ ClearMetadataDetail(md);
+ g_list_free_full(md_list, &ClearMetadataDetail);
+ return nullptr;
+ }
+ md_list = g_list_append(md_list, md);
+ }
+ }
+ return md_list;
+}
+
} // namespace
namespace common_installer {
return false;
}
plugin->pkgid = strdup(manifest->package);
- plugin->appid = strdup(appid);
+ plugin->appid = appid ? strdup(appid) : strdup("");
plugin->plugin_type = strdup(plugin_info_.type().c_str());
plugin->plugin_name = strdup(plugin_info_.name().c_str());
if (!plugin->pkgid || !plugin->appid |
return pos->second;
}
+bool MetadataPlugin::LoadPluginInfo(manifest_x* manifest) {
+ if (pkgmgrinfo_plugininfo_foreach_plugininfo(manifest->package,
+ MetadataPlugin::kType,
+ plugin_info_.name().c_str(),
+ [](const char* pkgid, const char* appid, const char*,
+ const char*, void* user_data) -> int {
+ auto* set = static_cast<std::set<PkgAppPair>*>(user_data);
+ set->emplace(std::string(pkgid), std::string(appid));
+ return PMINFO_R_OK;
+ },
+ &pkg_app_set_) != PMINFO_R_OK) {
+ LOG(ERROR) << "Failed to get previous execution info";
+ return false;
+ }
+ return true;
+}
+
+bool MetadataPlugin::ExecutePlugin(const std::string& name,
+ const char* pkgid, const char* appid, GList* md_list) {
+ int result = 0;
+ Exec(name, &result, pkgid, appid, md_list);
+ if (result) {
+ LOG(ERROR) << "Function: " << name << " of plugin "
+ << plugin_info_.path() << " failed";
+ return false;
+ }
+ return true;
+}
+
bool MetadataPlugin::Run(xmlDocPtr /*doc_ptr*/, manifest_x* manifest,
ActionType action_type) {
std::string name;
if (tag.empty())
return false;
- std::set<std::string> appid_list;
if (action_type == ActionType::Upgrade) {
- if (pkgmgrinfo_plugininfo_foreach_plugininfo(manifest->package,
- MetadataPlugin::kType,
- plugin_info_.name().c_str(),
- [](const char*, const char* appid, const char*,
- const char*, void* user_data) -> int {
- auto* list = static_cast<std::set<std::string>*>(user_data);
- list->emplace(std::string(appid));
- return PMINFO_R_OK;
- },
- &appid_list) != PMINFO_R_OK) {
- LOG(ERROR) << "Failed to get previous execution info";
+ // Load previous execution info. If some element left in pkg_app_set_
+ // at the end of this method, it means that the plugin was not executed for
+ // this pkg or app. (need to invoke PKGMGR_MDPARSER_PLUGIN_REMOVED)
+ if (!LoadPluginInfo(manifest))
return false;
- }
}
- 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)) {
- const 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)));
- if (!md) {
- LOG(ERROR) << "Out of memory";
- g_list_free_full(md_list, &ClearMetadataDetail);
- return false;
- }
- md->key = strdup(meta->key);
- if (!md->key) {
- LOG(ERROR) << "Out of memory";
- free(md);
- g_list_free_full(md_list, &ClearMetadataDetail);
- return false;
- }
- md->value = strdup(meta->value);
- if (!md->value) {
- LOG(ERROR) << "Out of memory";
- ClearMetadataDetail(md);
- g_list_free_full(md_list, &ClearMetadataDetail);
- return false;
- }
- md_list = g_list_append(md_list, md);
- }
+ bool result;
+ GList* md_list = GetMetadataListForKey(manifest->metadata,
+ plugin_info_.name());
+ if (md_list) {
+ name = GetFunctionName(action_type);
+ if (!AddPluginInfo(manifest, nullptr)) {
+ g_list_free_full(md_list, &ClearMetadataDetail);
+ return false;
}
+ pkg_app_set_.erase(
+ std::make_pair<std::string, std::string>(manifest->package, ""));
+ result = ExecutePlugin(name, manifest->package, nullptr, md_list);
+ g_list_free_full(md_list, &ClearMetadataDetail);
+ if (!result)
+ return false;
+ }
+ for (application_x* app : GListRange<application_x*>(manifest->application)) {
+ md_list = GetMetadataListForKey(app->metadata, plugin_info_.name());
// skip application if it has no given metadata
if (!md_list) {
continue;
g_list_free_full(md_list, &ClearMetadataDetail);
return false;
}
- appid_list.erase(app->appid);
- }
- int result = 0;
- Exec(name, &result, manifest->package, app->appid, md_list);
- if (result) {
- LOG(ERROR) << "Function: " << name << " of plugin "
- << plugin_info_.path() << " failed";
- g_list_free_full(md_list, &ClearMetadataDetail);
- return false;
+ pkg_app_set_.erase(
+ std::make_pair<std::string, std::string>(
+ manifest->package, app->appid));
}
+ result = ExecutePlugin(name, manifest->package, app->appid, md_list);
g_list_free_full(md_list, &ClearMetadataDetail);
+ if (!result)
+ return false;
}
- if (action_type == ActionType::Clean ||
- action_type == ActionType::Undo)
+ if (action_type == ActionType::Clean || action_type == ActionType::Undo)
name = GetFunctionName(action_type);
else
name = GetFunctionName(ActionType::Removed);
- for (const auto& appid : appid_list) {
- int result = 0;
- Exec(name, &result, manifest->package, appid.c_str(), nullptr);
- if (result) {
- LOG(ERROR) << "Function: " << name << " of plugin "
- << plugin_info_.path() << " failed";
+
+ for (const auto& pkg_app : pkg_app_set_) {
+ result = ExecutePlugin(name, pkg_app.first.c_str(),
+ pkg_app.second.empty() ? nullptr : pkg_app.second.c_str(), nullptr);
+ if (!result)
return false;
- }
}
return true;
}