From: Tomasz Iwanek Date: Fri, 5 Feb 2016 12:39:21 +0000 (+0100) Subject: Implement launching 'metadata' and 'category' plugin X-Git-Tag: accepted/tizen/common/20160304.194918^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=37c8300c56ffcdd7edbe6d65c1403c7f4684de50;p=platform%2Fcore%2Fappfw%2Fapp-installers.git Implement launching 'metadata' and 'category' plugin Implementation of loading other types of plugins of pkgmgr than 'tag': - DynamicLibHandle was reworked to be base class of all plugins types, - add factory for plugin and common interface for them. Following changes should be submitted together: - https://review.tizen.org/gerrit/#/c/59029/ - https://review.tizen.org/gerrit/#/c/59028/ - https://review.tizen.org/gerrit/#/c/59030/ - https://review.tizen.org/gerrit/#/c/59031/ Change-Id: I7f6bd50e364bedac2ee18626db0b02cda4865e31 --- diff --git a/packaging/app-installers.spec b/packaging/app-installers.spec index 041b4d2..249b46b 100644 --- a/packaging/app-installers.spec +++ b/packaging/app-installers.spec @@ -85,6 +85,7 @@ make %{?_smp_mflags} %files devel %{_includedir}/app-installers/common/*.h %{_includedir}/app-installers/common/*/*.h +%{_includedir}/app-installers/common/*/*/*.h %{_libdir}/pkgconfig/app-installers.pc %files tests diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index a194ecc..b5c5efc 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -3,10 +3,15 @@ SET(SRCS app_installer.cc backup_paths.cc installer_context.cc - plugins/plugins_launcher.cc + plugins/plugin_factory.cc plugins/plugin_manager.cc plugins/plugin_list_parser.cc plugins/plugin_xml_parser.cc + plugins/plugin_factory.cc + plugins/plugin.cc + plugins/types/category_plugin.cc + plugins/types/metadata_plugin.cc + plugins/types/tag_plugin.cc pkgmgr_interface.cc pkgmgr_registration.cc pkgmgr_signal.cc @@ -58,7 +63,6 @@ SET(SRCS step/step_update_tep.cc step/step_remove_manifest.cc utils/base64.cc - utils/dynamic_lib_handle.cc utils/file_util.cc utils/subprocess.cc ) diff --git a/src/common/plugins/plugin.cc b/src/common/plugins/plugin.cc new file mode 100644 index 0000000..212857b --- /dev/null +++ b/src/common/plugins/plugin.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by a apache 2.0 license that can be +// found in the LICENSE file. + +#include "common/plugins/plugin.h" + +#include + +#include + +namespace common_installer { + +Plugin::Plugin(const PluginInfo& plugin_info) + : plugin_info_(plugin_info), + lib_handle_(nullptr) {} + +bool Plugin::Load() { + if (lib_handle_) { + return true; + } + + lib_handle_ = dlopen(plugin_info_.path().c_str(), RTLD_LAZY | RTLD_LOCAL); + if (!lib_handle_) { + LOG(ERROR) << "Failed to open library: " << plugin_info_.path().c_str() + << " (" << dlerror() << ")"; + return false; + } + return true; +} + +void* Plugin::GetSymbol(const std::string& name) const { + return dlsym(lib_handle_, name.c_str()); +} + +Plugin::~Plugin() { + if (lib_handle_) { + dlclose(lib_handle_); + } +} + +int ActionTypeToPkgmgrActionType(common_installer::Plugin::ActionType action) { + switch (action) { + case Plugin::ActionType::Install: + return ACTION_INSTALL; + case Plugin::ActionType::Upgrade: + return ACTION_UPGRADE; + case Plugin::ActionType::Uninstall: + return ACTION_UNINSTALL; + default: + LOG(ERROR) << "Failed to get correct action type"; + return -1; + } +} + +} // namespace common_installer diff --git a/src/common/plugins/plugin.h b/src/common/plugins/plugin.h new file mode 100644 index 0000000..d9be7f6 --- /dev/null +++ b/src/common/plugins/plugin.h @@ -0,0 +1,84 @@ +// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by a apache 2.0 license that can be +// found in the LICENSE file. + +#ifndef COMMON_PLUGINS_PLUGIN_H_ +#define COMMON_PLUGINS_PLUGIN_H_ + +#include +#include +#include +#include +#include + +#include +#include + +#include "common/plugins/plugin_list_parser.h" + +namespace common_installer { + +/** + * @brief The Plugin class + * Represents pkgmgr plugin object handling internally managing loading + * of .so shared object from file system. Run() function is being + * overloaded in subclasses to accommodate plugin differences. + */ +class Plugin { + public: + enum class ActionType { Install, Upgrade, Uninstall }; + enum class ProcessType { Pre, Main, Post }; + + virtual ~Plugin(); + + template + bool Exec(const std::string& name, Ret* result, Args... args) { + using PluginFunctionPtr = Ret (*)(Args...); + PluginFunctionPtr function = + reinterpret_cast(GetSymbol(name)); + + if (!function) { + LOG(WARNING) << "Failed to get symbol: " << name << " (" << dlerror() + << ")"; + return false; + } + + LOG(DEBUG) << "Execute plugin function: " << name << " of " + << plugin_info_.path() << "..."; + *result = function(args...); + return true; + } + + virtual bool Run(xmlDocPtr doc_ptr, manifest_x* manifest, + ActionType action_type) = 0; + + Plugin(Plugin&&) = default; + Plugin& operator=(Plugin&&) = default; + + protected: + explicit Plugin(const PluginInfo& plugin_info); + bool Load(); + + PluginInfo plugin_info_; + + private: + void* GetSymbol(const std::string& name) const; + + void* lib_handle_; + + SCOPE_LOG_TAG(Plugin) +}; + +/** + * @brief ActionTypeToPkgmgrActionType + * Helper function to convert app-installer ActionType to pkgmgr action + * type for 'category' and 'metadata' plugins. + * + * @param action input action type + * @return pkgmgr action type or -1 if error + */ +int ActionTypeToPkgmgrActionType(common_installer::Plugin::ActionType action); + +} // namespace common_installer + +#endif // COMMON_PLUGINS_PLUGIN_H_ diff --git a/src/common/plugins/plugin_factory.cc b/src/common/plugins/plugin_factory.cc new file mode 100644 index 0000000..9862142 --- /dev/null +++ b/src/common/plugins/plugin_factory.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#include "common/plugins/plugin_factory.h" + +#include + +#include "common/plugins/types/category_plugin.h" +#include "common/plugins/types/metadata_plugin.h" +#include "common/plugins/types/tag_plugin.h" + +namespace common_installer { + +std::unique_ptr PluginFactory::CreatePluginByPluginInfo( + const PluginInfo& plugin_info) { + if (plugin_info.type() == TagPlugin::kType) { + return TagPlugin::Create(plugin_info); + } else if (plugin_info.type() == MetadataPlugin::kType) { + return MetadataPlugin::Create(plugin_info); + } else if (plugin_info.type() == CategoryPlugin::kType) { + return CategoryPlugin::Create(plugin_info); + } else { + LOG(ERROR) << "Unknown plugin type: " << plugin_info.type(); + return nullptr; + } +} + +} // namespace common_installer diff --git a/src/common/plugins/plugin_factory.h b/src/common/plugins/plugin_factory.h new file mode 100644 index 0000000..6798c36 --- /dev/null +++ b/src/common/plugins/plugin_factory.h @@ -0,0 +1,23 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#ifndef COMMON_PLUGINS_PLUGIN_FACTORY_H_ +#define COMMON_PLUGINS_PLUGIN_FACTORY_H_ + +#include + +#include "common/plugins/plugin.h" +#include "common/plugins/plugin_list_parser.h" + +namespace common_installer { + +class PluginFactory { + public: + std::unique_ptr CreatePluginByPluginInfo( + const PluginInfo& plugin_info); +}; + +} // namespace common_installer + +#endif // COMMON_PLUGINS_PLUGIN_FACTORY_H_ diff --git a/src/common/plugins/plugin_list_parser.cc b/src/common/plugins/plugin_list_parser.cc index ce59262..b0b05c2 100644 --- a/src/common/plugins/plugin_list_parser.cc +++ b/src/common/plugins/plugin_list_parser.cc @@ -125,7 +125,7 @@ bool PluginsListParser::Parse() { return true; } -const PluginsListParser::PluginList& PluginsListParser::PluginInfoList() { +const PluginsListParser::PluginList& PluginsListParser::PluginInfoList() const { return plugin_info_list_; } diff --git a/src/common/plugins/plugin_list_parser.h b/src/common/plugins/plugin_list_parser.h index ef85e42..a18f7cf 100644 --- a/src/common/plugins/plugin_list_parser.h +++ b/src/common/plugins/plugin_list_parser.h @@ -49,14 +49,12 @@ class PluginsListParser { explicit PluginsListParser(const std::string& path) : path_(path) {} bool Parse(); - const PluginList& PluginInfoList(); + const PluginList& PluginInfoList() const; private: enum Column { Flag, Type, Name, Path }; PluginsListParser() {} - const std::string path_; - std::vector> plugin_info_list_; bool ReadLinesFromFile(std::vector* lines); bool ParsePluginsRawData(const std::vector& lines); @@ -72,6 +70,9 @@ class PluginsListParser { bool ValidType(const std::string& type); bool ValidName(const std::string& name); bool ValidPath(const std::string& path); + + const std::string path_; + std::vector> plugin_info_list_; }; } // namespace common_installer diff --git a/src/common/plugins/plugin_manager.cc b/src/common/plugins/plugin_manager.cc index 9650221..766efc0 100644 --- a/src/common/plugins/plugin_manager.cc +++ b/src/common/plugins/plugin_manager.cc @@ -6,117 +6,124 @@ #include +#include #include #include +#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/utils/glist_range.h" namespace common_installer { -bool PluginManager::GenerateUnknownTagList() { - tags_.clear(); - +bool PluginManager::GenerateUnknownTagList( + std::vector* xml_tags) { if (!xml_parser_.Parse()) { LOG(ERROR) << "Parse xml function error"; return false; } - std::vector xmlTags = xml_parser_.tags_list(); + *xml_tags = xml_parser_.tags_list(); + return true; +} +bool PluginManager::GeneratePluginInfoList( + PluginManager::PluginInfoList* plugin_info_list) { if (!list_parser_.Parse()) { LOG(ERROR) << "Parse list function error"; return false; } - const PluginsListParser::PluginList& pluginInfoList = - list_parser_.PluginInfoList(); - - for (std::shared_ptr pluginInfo : pluginInfoList) { - // find only tags - if (pluginInfo->type() == "tag") { - // check if a file exist - if (boost::filesystem::exists(pluginInfo->path())) { - for (const std::string& xmlTag : xmlTags) { - // if system tags included in xml tags - if (pluginInfo->name() == xmlTag) { - tags_.push_back(pluginInfo); - LOG(DEBUG) << "Tag: " << pluginInfo->name() - << " path: " << pluginInfo->path() << "has been added"; + *plugin_info_list = list_parser_.PluginInfoList(); + return true; +} + +bool PluginManager::LoadPlugins() { + std::vector xml_tags; + if (!GenerateUnknownTagList(&xml_tags)) + return false; + + PluginInfoList plugin_info_list; + if (!GeneratePluginInfoList(&plugin_info_list)) + return false; + + PluginFactory factory; + + std::sort(xml_tags.begin(), xml_tags.end()); + + // This loop loads plugin which are needed according to manifest file + // Different pkgmgr plugin types have different condition upon which they + // are being loaded + LOG(DEBUG) << "Loading pkgmgr plugins..."; + for (std::shared_ptr plugin_info : plugin_info_list) { + std::unique_ptr plugin; + if (plugin_info->type() == TagPlugin::kType) { + // load tag plugin only if tag exists in manifest file + auto iter = std::lower_bound(xml_tags.begin(), xml_tags.end(), + plugin_info->name()); + if (iter != xml_tags.end() && *iter == plugin_info->name()) { + plugin = factory.CreatePluginByPluginInfo(*plugin_info); + if (!plugin) { + LOG(ERROR) << "Failed to load plugin: " << plugin_info->path() + << " Plugin has been skipped."; + } + } + } else if (plugin_info->type() == MetadataPlugin::kType) { + bool done = false; + for (application_x* app : GListRange( + manifest_->application)) { + for (metadata_x* meta : GListRange(app->metadata)) { + if (std::string(meta->key).find(plugin_info->name()) == 0) { + plugin = factory.CreatePluginByPluginInfo(*plugin_info); + if (!plugin) { + LOG(ERROR) << "Failed to load plugin: " << plugin_info->path() + << " Plugin has been skipped."; + } + done = true; + break; + } + } + if (done) + break; + } + } else if (plugin_info->type() == CategoryPlugin::kType) { + bool done = false; + for (application_x* app : GListRange( + manifest_->application)) { + for (const char* category : GListRange(app->category)) { + if (std::string(category).find(plugin_info->name()) == 0) { + plugin = factory.CreatePluginByPluginInfo(*plugin_info); + if (!plugin) { + LOG(ERROR) << "Failed to load plugin: " << plugin_info->path() + << " Plugin has been skipped."; + } + done = true; break; } } - } else { - LOG(WARNING) << "Tag: " << pluginInfo->name() - << " path: " << pluginInfo->path() - << " exist in plugin list but no exist in system."; + if (done) + break; } } - } - - if (tags_.empty()) { - LOG(INFO) << "No tags to processing"; - } - - return true; -} -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(child->name)) { - xmlAddChild(plugin_root_node, xmlCopyNode(child, 1)); + if (plugin) { + loaded_plugins_.push_back(std::move(plugin)); + LOG(DEBUG) << "Loaded plugin: " << plugin_info->path(); } } - xmlSetTreeDoc(plugin_root_node, plugin_doc_ptr); - return plugin_doc_ptr; + return true; } -bool PluginManager::Launch(const boost::filesystem::path& plugin_path, - const std::string& tag_name, - PluginsLauncher::ActionType action_type, - const std::string& pkg_Id) { - LOG(INFO) << "Launching plugin path:" << plugin_path << " pkgId: " << pkg_Id; - - 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; +void 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); } } diff --git a/src/common/plugins/plugin_manager.h b/src/common/plugins/plugin_manager.h index 36c0fb6..f0d5a40 100644 --- a/src/common/plugins/plugin_manager.h +++ b/src/common/plugins/plugin_manager.h @@ -7,10 +7,11 @@ #include +#include #include #include -#include "common/plugins/plugins_launcher.h" +#include "common/plugins/plugin.h" #include "common/plugins/plugin_list_parser.h" #include "common/plugins/plugin_xml_parser.h" @@ -19,33 +20,28 @@ namespace common_installer { /** this class manages XML and plugin lists */ class PluginManager { public: - using TagList = std::vector>; - PluginManager(const std::string& xml_path, const std::string& list_path) - : xml_parser_(xml_path), list_parser_(list_path) {} + using PluginInfoList = std::vector>; - bool GenerateUnknownTagList(); - const TagList& UnknownTagList(); - bool Launch(const boost::filesystem::path& pluginPath, - const std::string& tag_name, - PluginsLauncher::ActionType actionType, const std::string& pkgId); + PluginManager(const std::string& xml_path, + const std::string& list_path, + manifest_x* manifest) + : xml_parser_(xml_path), + list_parser_(list_path), + manifest_(manifest) {} + + bool LoadPlugins(); + void RunPlugins(Plugin::ActionType action_type); 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> tags_; + bool GenerateUnknownTagList(std::vector* xml_tags); + bool GeneratePluginInfoList(PluginInfoList* plugin_info_list); + PluginsXmlParser xml_parser_; PluginsListParser list_parser_; - PluginsLauncher plugins_launcher_; + manifest_x* manifest_; + std::vector> loaded_plugins_; }; + } // namespace common_installer #endif // COMMON_PLUGINS_PLUGIN_MANAGER_H_ diff --git a/src/common/plugins/plugins_launcher.cc b/src/common/plugins/plugins_launcher.cc deleted file mode 100644 index 7b69898..0000000 --- a/src/common/plugins/plugins_launcher.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#include "common/plugins/plugins_launcher.h" - -#include - -#include -#include - -namespace common_installer { - -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.Load(plugin_path, RTLD_LAZY | RTLD_LOCAL)) { - LOG(ERROR) << "Failed to create library handle"; - return Error::FailedLibHandle; - } - - bool is_supported = false; - - if (ExecPlugin(dlh, ProcessType::PreInstall, action, pkgId.c_str(), - result)) { - is_supported = true; - } - - if (ExecPlugin(dlh, ProcessType::Install, action, docPtr, pkgId.c_str(), - result)) { - is_supported = true; - } - - if (ExecPlugin(dlh, ProcessType::PostInstall, action, pkgId.c_str(), - result)) { - is_supported = true; - } - - if (!is_supported) { - return Error::ActionNotSupported; - } - - return Error::Success; -} - -bool PluginsLauncher::FunctionName(ProcessType process, ActionType action, - std::string* result) { - static std::map, 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::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 - }; - - auto pos = names.find(std::make_pair(action, process)); - if (pos == names.end()) { - LOG(ERROR) << "Function name not defined"; - return false; - } - *result = pos->second; - return true; -} - -bool PluginsLauncher::ExecPlugin(const DynamicLibHandle& dlh, - ProcessType process, - ActionType action, const char* pkgId, - int* result) { - return ExecPluginImpl(dlh, process, action, result, pkgId); -} - -bool PluginsLauncher::ExecPlugin(const DynamicLibHandle& dlh, - ProcessType process, - ActionType action, xmlDocPtr docPtr, - const char* pkgId, int* result) { - return ExecPluginImpl(dlh, process, action, result, docPtr, pkgId); -} - -} // namespace common_installer diff --git a/src/common/plugins/plugins_launcher.h b/src/common/plugins/plugins_launcher.h deleted file mode 100644 index 7a1ed34..0000000 --- a/src/common/plugins/plugins_launcher.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#ifndef COMMON_PLUGINS_PLUGINS_LAUNCHER_H_ -#define COMMON_PLUGINS_PLUGINS_LAUNCHER_H_ - -#include - -#include -#include - -#include -#include - -#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 }; - - 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: - bool FunctionName(ProcessType process, ActionType action, - std::string* result); - - bool ExecPlugin(const DynamicLibHandle& dlh, ProcessType process, - ActionType action, const char* pkgId, int* result); - - bool ExecPlugin(const DynamicLibHandle& dlh, ProcessType process, - ActionType action, xmlDocPtr docPtr, - const char* pkgId, int* result); - - template - bool ExecPluginImpl(const DynamicLibHandle& dlh, ProcessType process, - ActionType action, int* result, Args&&... args) { - std::string name; - if (!FunctionName(process, action, &name)) { - LOG(ERROR) << "Error during getting function name"; - return false; - } - return dlh.Exec(name, result, std::forward(args)...); - } - - SCOPE_LOG_TAG(PluginsLauncher) -}; - -} // namespace common_installer - -#endif // COMMON_PLUGINS_PLUGINS_LAUNCHER_H_ diff --git a/src/common/plugins/plugins_list.txt.in b/src/common/plugins/plugins_list.txt.in index 2d7f8ac..d53e23c 100644 --- a/src/common/plugins/plugins_list.txt.in +++ b/src/common/plugins/plugins_list.txt.in @@ -3,14 +3,14 @@ flag="0x00000002";type="tag";name="account";path="/etc/package-manager/parserlib 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" -flag="0x00000100";type="metadata";name="http://developer.samsung.com/tizen/metadata/downloadable_filters";path="/usr/etc/package-manager/parserlib/metadata/libdownloadable_filters.so" -flag="0x00000200";type="metadata";name="http://developer.samsung.com/tizen/metadata/dictionary";path="/usr/etc/package-manager/parserlib/metadata/libdictionary.so" -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="0x00000020";type="category";name="http://tizen.org/category/downloadable_font";path="/etc/package-manager/parserlib/category/libdownloadable_font.so" +flag="0x00000040";type="metadata";name="http://developer.samsung.com/tizen/metadata/sticker";path="/etc/package-manager/parserlib/metadata/libsticker.so" +flag="0x00000080";type="metadata";name="http://developer.samsung.com/tizen/metadata/ttsengine";path="/etc/package-manager/parserlib/metadata/libttsengine.so" +flag="0x00000100";type="metadata";name="http://developer.samsung.com/tizen/metadata/downloadable_filters";path="/etc/package-manager/parserlib/metadata/libdownloadable_filters.so" +flag="0x00000200";type="metadata";name="http://developer.samsung.com/tizen/metadata/dictionary";path="/etc/package-manager/parserlib/metadata/libdictionary.so" +flag="0x00000400";type="category";name="http://tizen.org/category/antivirus";path="/etc/package-manager/parserlib/category/libantivirus.so" +flag="0x00000800";type="metadata";name="http://developer.samsung.com/tizen/metadata/profile";path="/etc/package-manager/parserlib/metadata/libtheme.so" +flag="0x00001000";type="category";name="http://tizen.org/category/tts";path="/etc/package-manager/parserlib/category/libsamsung_tts.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" diff --git a/src/common/plugins/types/category_plugin.cc b/src/common/plugins/types/category_plugin.cc new file mode 100644 index 0000000..291ee1e --- /dev/null +++ b/src/common/plugins/types/category_plugin.cc @@ -0,0 +1,89 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#include "common/plugins/types/category_plugin.h" + +#include + +#include + +#include "common/utils/glist_range.h" + +namespace { + +std::string GetCategoryName(const std::string& url) { + return url.substr(url.find_last_of('/') + 1); +} + +void ClearCategoryDetail(gpointer data) { + __category_t* category = reinterpret_cast<__category_t*>(data); + free(const_cast(category->name)); + free(category); +} + +} // namespace + +namespace common_installer { + +const char CategoryPlugin::kType[] = "category"; + +std::unique_ptr CategoryPlugin::Create( + const PluginInfo& plugin_info) { + std::unique_ptr plugin(new CategoryPlugin(plugin_info)); + if (!plugin->Load()) + return nullptr; + return plugin; +} + +std::string CategoryPlugin::GetFunctionName(ActionType action) const { + static std::map names { + {ActionType::Install, "PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL"}, + {ActionType::Upgrade, "PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE"}, + {ActionType::Uninstall, "PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL"}, + }; + + auto pos = names.find(action); + if (pos == names.end()) { + LOG(ERROR) << "Function name not defined"; + return ""; + } + return pos->second; +} + +bool CategoryPlugin::Run(xmlDocPtr /*doc_ptr*/, manifest_x* manifest, + ActionType action_type) { + std::string tag = GetCategoryName(plugin_info_.name()); + if (tag.empty()) + return false; + std::string name = GetFunctionName(action_type); + for (application_x* app : GListRange(manifest->application)) { + // pack all categories starting with key + '/' to list that will + // be sent to the plugin. + // e.g. all http://tizen.org/category/antivirus/* + // will be packed for http://tizen.org/category/antivirus + GList* category_list = nullptr; + for (const char* category : GListRange(app->category)) { + std::string sub_key_prefix = plugin_info_.name() + "/"; + if (std::string(category).find(sub_key_prefix) == 0) { + __category_t* c = reinterpret_cast<__category_t*>( + calloc(1, sizeof(__category_t))); + c->name = strdup(category); + category_list = g_list_append(category_list, c); + } + } + int result = 0; + Exec(name, &result, category_list, tag.c_str(), + ActionTypeToPkgmgrActionType(action_type), + manifest->package, app->appid); + if (result) { + LOG(ERROR) << "Function: " << name << " of plugin " + << plugin_info_.path() << " failed"; + g_list_free_full(category_list, &ClearCategoryDetail); + return false; + } + g_list_free_full(category_list, &ClearCategoryDetail); + } +} + +} // namespace common_installer diff --git a/src/common/plugins/types/category_plugin.h b/src/common/plugins/types/category_plugin.h new file mode 100644 index 0000000..833205f --- /dev/null +++ b/src/common/plugins/types/category_plugin.h @@ -0,0 +1,32 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#ifndef COMMON_PLUGINS_TYPES_CATEGORY_PLUGIN_H_ +#define COMMON_PLUGINS_TYPES_CATEGORY_PLUGIN_H_ + +#include + +#include "common/plugins/plugin.h" + +namespace common_installer { + +class CategoryPlugin : public Plugin { + public: + static const char kType[]; + + static std::unique_ptr Create(const PluginInfo& plugin_info); + bool Run(xmlDocPtr doc_ptr, manifest_x* manifest, + ActionType action_type) override; + + private: + std::string GetFunctionName(ActionType action) const; + + using Plugin::Plugin; + + SCOPE_LOG_TAG(CategoryPlugin) +}; + +} // namespace common_installer + +#endif // COMMON_PLUGINS_TYPES_CATEGORY_PLUGIN_H_ diff --git a/src/common/plugins/types/metadata_plugin.cc b/src/common/plugins/types/metadata_plugin.cc new file mode 100644 index 0000000..83ab117 --- /dev/null +++ b/src/common/plugins/types/metadata_plugin.cc @@ -0,0 +1,93 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#include "common/plugins/types/metadata_plugin.h" + +#include + +#include + +#include "common/utils/glist_range.h" + +namespace { + +std::string GetMetadataTag(const std::string& url) { + return url.substr(url.find_last_of('/') + 1); +} + +void ClearMetadataDetail(gpointer data) { + __metadata_t* meta = reinterpret_cast<__metadata_t*>(data); + free(const_cast(meta->key)); + free(const_cast(meta->value)); + free(meta); +} + +} // namespace + +namespace common_installer { + +const char MetadataPlugin::kType[] = "metadata"; + +std::unique_ptr MetadataPlugin::Create( + const PluginInfo& plugin_info) { + std::unique_ptr plugin(new MetadataPlugin(plugin_info)); + if (!plugin->Load()) + return nullptr; + return plugin; +} + +std::string MetadataPlugin::GetFunctionName(ActionType action) const { + static std::map names { + {ActionType::Install, "PKGMGR_MDPARSER_PLUGIN_INSTALL"}, + {ActionType::Upgrade, "PKGMGR_MDPARSER_PLUGIN_UPGRADE"}, + {ActionType::Uninstall, "PKGMGR_MDPARSER_PLUGIN_UNINSTALL"}, + }; + + auto pos = names.find(action); + if (pos == names.end()) { + LOG(ERROR) << "Function name not defined"; + return ""; + } + return pos->second; +} + +bool MetadataPlugin::Run(xmlDocPtr /*doc_ptr*/, manifest_x* manifest, + ActionType action_type) { + std::string tag = GetMetadataTag(plugin_info_.name()); + if (tag.empty()) + return false; + std::string name = GetFunctionName(action_type); + for (application_x* app : GListRange(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(app->metadata)) { + 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))); + md->key = strdup(meta->key); + md->value = strdup(meta->value); + md_list = g_list_append(md_list, md); + } + } + int result = 0; + Exec(name, &result, md_list, tag.c_str(), + ActionTypeToPkgmgrActionType(action_type), + manifest->package, app->appid); + if (result) { + LOG(ERROR) << "Function: " << name << " of plugin " + << plugin_info_.path() << " failed"; + g_list_free_full(md_list, &ClearMetadataDetail); + return false; + } + g_list_free_full(md_list, &ClearMetadataDetail); + } + return true; +} + +} // namespace common_installer diff --git a/src/common/plugins/types/metadata_plugin.h b/src/common/plugins/types/metadata_plugin.h new file mode 100644 index 0000000..7d09b50 --- /dev/null +++ b/src/common/plugins/types/metadata_plugin.h @@ -0,0 +1,32 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#ifndef COMMON_PLUGINS_TYPES_METADATA_PLUGIN_H_ +#define COMMON_PLUGINS_TYPES_METADATA_PLUGIN_H_ + +#include + +#include "common/plugins/plugin.h" + +namespace common_installer { + +class MetadataPlugin : public Plugin { + public: + static const char kType[]; + + static std::unique_ptr Create(const PluginInfo& plugin_info); + bool Run(xmlDocPtr doc_ptr, manifest_x* manifest, + ActionType action_type) override; + + private: + std::string GetFunctionName(ActionType action) const; + + using Plugin::Plugin; + + SCOPE_LOG_TAG(MetadataPlugin) +}; + +} // namespace common_installer + +#endif // COMMON_PLUGINS_TYPES_METADATA_PLUGIN_H_ diff --git a/src/common/plugins/types/tag_plugin.cc b/src/common/plugins/types/tag_plugin.cc new file mode 100644 index 0000000..7734312 --- /dev/null +++ b/src/common/plugins/types/tag_plugin.cc @@ -0,0 +1,106 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#include "common/plugins/types/tag_plugin.h" + +#include +#include + +namespace common_installer { + +const char TagPlugin::kType[] = "tag"; + +std::unique_ptr TagPlugin::Create(const PluginInfo& plugin_info) { + std::unique_ptr plugin(new TagPlugin(plugin_info)); + if (!plugin->Load()) + return nullptr; + return plugin; +} + +std::string TagPlugin::GetFunctionName(ProcessType process, + ActionType action) const { + static std::map, std::string> names { + {{ActionType::Install, ProcessType::Pre}, "PKGMGR_PARSER_PLUGIN_PRE_INSTALL"}, // NOLINT + {{ActionType::Upgrade, ProcessType::Pre}, "PKGMGR_PARSER_PLUGIN_PRE_UPGRADE"}, // NOLINT + {{ActionType::Uninstall, ProcessType::Pre}, "PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL"}, // NOLINT + {{ActionType::Install, ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_INSTALL"}, // NOLINT + {{ActionType::Upgrade, ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_UPGRADE"}, // NOLINT + {{ActionType::Uninstall, ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_UNINSTALL"}, // NOLINT + {{ActionType::Install, ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_INSTALL"}, // NOLINT + {{ActionType::Upgrade, ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_UPGRADE"}, // NOLINT + {{ActionType::Uninstall, ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_UNINSTALL"} // NOLINT + }; + + auto pos = names.find(std::make_pair(action, process)); + if (pos == names.end()) { + LOG(ERROR) << "Function name not defined"; + return ""; + } + return pos->second; +} + +xmlDocPtr TagPlugin::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(child->name)) { + xmlAddChild(plugin_root_node, xmlCopyNode(child, 1)); + } + } + xmlSetTreeDoc(plugin_root_node, plugin_doc_ptr); + return plugin_doc_ptr; +} + +bool TagPlugin::Run(xmlDocPtr doc_ptr, manifest_x* manifest, + ActionType action_type) { + xmlDocPtr plugin_doc_ptr = CreateDocPtrForPlugin(doc_ptr, + plugin_info_.name()); + if (!plugin_doc_ptr) + return false; + + int result = 0; + std::string pre_function = GetFunctionName(ProcessType::Pre, action_type); + Exec(pre_function, &result, manifest->package); + if (result) { + LOG(ERROR) << "Function: " << pre_function << " of plugin " + << plugin_info_.path() << " failed"; + xmlFreeDoc(plugin_doc_ptr); + return false; + } + + std::string main_function = GetFunctionName(ProcessType::Main, action_type); + Exec(main_function, &result, plugin_doc_ptr, manifest->package); + if (result) { + LOG(ERROR) << "Function: " << main_function << " of plugin " + << plugin_info_.path() << " failed"; + xmlFreeDoc(plugin_doc_ptr); + return false; + } + + std::string post_function = GetFunctionName(ProcessType::Post, action_type); + Exec(post_function, &result, manifest->package); + if (result) { + LOG(ERROR) << "Function: " << post_function << " of plugin " + << plugin_info_.path() << " failed"; + xmlFreeDoc(plugin_doc_ptr); + return false; + } + + xmlFreeDoc(plugin_doc_ptr); + return true; +} + + +} // namespace common_installer diff --git a/src/common/plugins/types/tag_plugin.h b/src/common/plugins/types/tag_plugin.h new file mode 100644 index 0000000..6d6e83d --- /dev/null +++ b/src/common/plugins/types/tag_plugin.h @@ -0,0 +1,47 @@ +// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +// Use of this source code is governed by an apache-2.0 license that can be +// found in the LICENSE file. + +#ifndef COMMON_PLUGINS_TYPES_TAG_PLUGIN_H_ +#define COMMON_PLUGINS_TYPES_TAG_PLUGIN_H_ + +#include + +#include +#include + +#include "common/plugins/plugin.h" +#include "common/plugins/plugin_list_parser.h" + +namespace common_installer { + +class TagPlugin : public Plugin { + public: + static const char kType[]; + + static std::unique_ptr Create(const PluginInfo& plugin_info); + + bool Run(xmlDocPtr doc_ptr, manifest_x* manifest, + ActionType action_type) override; + + private: + using Plugin::Plugin; + std::string GetFunctionName(ProcessType process, ActionType action) const; + + /** + * @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; + + SCOPE_LOG_TAG(TagPlugin) +}; + +} // namespace common_installer + +#endif // COMMON_PLUGINS_TYPES_TAG_PLUGIN_H_ diff --git a/src/common/step/step_run_parser_plugins.cc b/src/common/step/step_run_parser_plugins.cc index dfc123d..4dad126 100644 --- a/src/common/step/step_run_parser_plugins.cc +++ b/src/common/step/step_run_parser_plugins.cc @@ -7,79 +7,49 @@ #include #include +#include "common/plugins/plugin_manager.h" + namespace common_installer { namespace pkgmgr { StepRunParserPlugin::StepRunParserPlugin( - InstallerContext* context, PluginsLauncher::ActionType action_type) + InstallerContext* context, Plugin::ActionType action_type) : Step(context), action_type_(action_type) {} Step::Status StepRunParserPlugin::ProcessPlugins( - const boost::filesystem::path& xml_path) { + const boost::filesystem::path& xml_path, manifest_x* manifest, + Plugin::ActionType action_type) { // PLUGINS_LIST_FILE_PATH path generated from cmake const std::string listPath(PLUGINS_LIST_INSTALL_FILE_PATH); - // init plugin_manager - plugin_manager_.reset(new PluginManager(xml_path.string(), listPath)); - - if (!plugin_manager_->GenerateUnknownTagList()) { - LOG(ERROR) << "Error during generate unknown list, no exist file, path, " - "invalid data format etc, chceck log"; + PluginManager plugin_manager(xml_path.string(), listPath, manifest); + if (!plugin_manager.LoadPlugins()) { + LOG(ERROR) << "Loading plugins failed in progress"; return Status::ERROR; } + plugin_manager.RunPlugins(action_type); - const PluginManager::TagList& plugins = plugin_manager_->UnknownTagList(); - - for (const std::shared_ptr& plugin : plugins) { - 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(); - // 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); - } - } - } - - LOG(INFO) << "Successfully processing plugins"; + LOG(INFO) << "Processing plugins done"; return Status::OK; } Step::Status StepRunParserPlugin::process() { - return ProcessPlugins(context_->xml_path.get()); + return ProcessPlugins(context_->xml_path.get(), context_->manifest_data.get(), + action_type_); } Step::Status StepRunParserPlugin::undo() { - switch (action_type_) { - case PluginsLauncher::ActionType::Install: { - if (installed_plugins_.empty()) { - // no installed plugins - return Status::OK; - } - - for (const std::shared_ptr& 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; - } - 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; + // For update, we need to reread configuration of old version of widget + // so running whole process from beginning + if (action_type_ == Plugin::ActionType::Install) { + ProcessPlugins(context_->xml_path.get(), context_->manifest_data.get(), + Plugin::ActionType::Uninstall); + } else if (action_type_ == Plugin::ActionType::Upgrade) { + ProcessPlugins(context_->backup_xml_path.get(), + context_->old_manifest_data.get(), + Plugin::ActionType::Upgrade); } - - // never happen only to avoid compilation warning - return Status::ERROR; + return Status::OK; } } // namespace pkgmgr diff --git a/src/common/step/step_run_parser_plugins.h b/src/common/step/step_run_parser_plugins.h index cc2977e..6e6c608 100644 --- a/src/common/step/step_run_parser_plugins.h +++ b/src/common/step/step_run_parser_plugins.h @@ -5,11 +5,14 @@ #ifndef COMMON_STEP_STEP_RUN_PARSER_PLUGINS_H_ #define COMMON_STEP_STEP_RUN_PARSER_PLUGINS_H_ +#include + +#include + #include #include -#include "common/plugins/plugin_manager.h" -#include "manifest_parser/utils/logging.h" +#include "common/plugins/plugin.h" #include "common/step/step.h" namespace common_installer { @@ -18,20 +21,21 @@ namespace pkgmgr { class StepRunParserPlugin : public Step { public: explicit StepRunParserPlugin(InstallerContext* context, - PluginsLauncher::ActionType action_type); + Plugin::ActionType action_type); Step::Status process() override; Step::Status clean() { return Status::OK; } Step::Status undo() override; Step::Status precheck() { return Status::OK; } - SCOPE_LOG_TAG(RunParserPlugin) - private: - Step::Status ProcessPlugins(const boost::filesystem::path& xml_path); - PluginsLauncher::ActionType action_type_; - std::vector> installed_plugins_; - std::unique_ptr plugin_manager_; + Step::Status ProcessPlugins(const boost::filesystem::path& xml_path, + manifest_x* manifest, + Plugin::ActionType action_type); + + Plugin::ActionType action_type_; + + SCOPE_LOG_TAG(RunParserPlugin) }; } // namespace pkgmgr diff --git a/src/common/utils/dynamic_lib_handle.cc b/src/common/utils/dynamic_lib_handle.cc deleted file mode 100644 index 6f99fd6..0000000 --- a/src/common/utils/dynamic_lib_handle.cc +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#include "common/utils/dynamic_lib_handle.h" - -#include - -namespace common_installer { - -DynamicLibHandle::DynamicLibHandle() : lib_handle_(nullptr) {} - -bool DynamicLibHandle::Load(const boost::filesystem::path& path, int flags) { - if (lib_handle_) { - return true; - } - - lib_handle_ = dlopen(path.c_str(), flags); - if (!lib_handle_) { - LOG(ERROR) << "Failed to open library: " << path << " (" << dlerror() - << ")"; - return false; - } - return true; -} - -void* DynamicLibHandle::GetSymbol(const std::string& name) const { - return dlsym(lib_handle_, name.c_str()); -} - -DynamicLibHandle::~DynamicLibHandle() { - if (lib_handle_) { - dlclose(lib_handle_); - } -} - -} // namespace common_installer diff --git a/src/common/utils/dynamic_lib_handle.h b/src/common/utils/dynamic_lib_handle.h deleted file mode 100644 index a648aeb..0000000 --- a/src/common/utils/dynamic_lib_handle.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved -// Use of this source code is governed by a apache 2.0 license that can be -// found in the LICENSE file. - -#ifndef COMMON_UTILS_DYNAMIC_LIB_HANDLE_H_ -#define COMMON_UTILS_DYNAMIC_LIB_HANDLE_H_ - -#include - -#include -#include - -#include -#include - -namespace common_installer { - -class DynamicLibHandle { - public: - DynamicLibHandle(); - bool Load(const boost::filesystem::path& path, int flags); - - template - bool Exec(const std::string& name, Ret* result, Args... args) const { - using PluginFunctionPtr = Ret (*)(Args...); - PluginFunctionPtr function = - reinterpret_cast(GetSymbol(name)); - - if (!function) { - LOG(WARNING) << "Failed to get symbol: " << name << " (" << dlerror() - << ")"; - return false; - } - - LOG(DEBUG) << "Execute plugin function: " << name << "..."; - *result = function(args...); - return true; - } - - DynamicLibHandle(DynamicLibHandle&&) = default; - DynamicLibHandle& operator=(DynamicLibHandle&&) = default; - - virtual ~DynamicLibHandle(); - - SCOPE_LOG_TAG(DynamicLibHandle) - - private: - void* GetSymbol(const std::string& name) const; - void* lib_handle_; -}; - -} // namespace common_installer - -#endif // COMMON_UTILS_DYNAMIC_LIB_HANDLE_H_