2 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file src/common/plugin/PluginManager.cpp
18 * @author Zofia Abramowska <z.abramowska@samsung.com>
19 * @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
21 * @brief Definition of PluginManager class
33 #include <exceptions/UnknownPolicyTypeException.h>
36 #include "PluginManager.h"
40 int pluginFilter(const struct dirent *ent) {
41 #ifdef _DIRENT_HAVE_D_TYPE
42 if (ent->d_type != DT_REG) {
46 if (ent->d_name[0] == '.') {
55 PluginManager::PluginManager(const std::string &pluginDir) : m_dir(pluginDir) {
58 PluginManager::~PluginManager(void) {
59 // We have to be sure, that external objects will be destroyed
60 // before handles to libraries are closed.
61 for (auto &plugin : m_plugins) {
62 plugin.second.reset();
66 ExternalPluginPtr PluginManager::getPlugin(PolicyType pType) {
67 return m_plugins[pType];
70 std::vector<PolicyDescription> PluginManager::getPolicyDescriptions(void) const {
71 std::vector<PolicyDescription> descriptions;
72 descriptions.reserve(m_plugins.size());
73 for (auto &plugin : m_plugins) {
74 descriptions.push_back(plugin.first);
79 void PluginManager::invalidateAll(void) {
80 for (auto &plugin : m_plugins) {
81 plugin.second->invalidate();
85 void PluginManager::checkPolicyType(PolicyType pType) const {
86 const auto it = m_plugins.find(pType);
87 if (it == m_plugins.end() || it->second == nullptr)
88 throw UnknownPolicyTypeException(pType);
91 void PluginManager::loadPlugins(void) {
92 struct dirent **nameList = NULL;
93 int fileAmount = scandir(m_dir.c_str(), &nameList, pluginFilter, alphasort);
96 auto error = strerror(errno);
97 LOGE("Couldn't scan for plugins in <%s> : <%s>", m_dir.c_str(), error);
101 std::unique_ptr<dirent*, std::function<void(dirent**)>> direntPtr(nameList,
102 [fileAmount](dirent** dirs) {
103 for (int i = 0; i < fileAmount; i++) {
108 for (int i = 0; i < fileAmount; i++) {
109 openPlugin(m_dir + nameList[i]->d_name);
113 void PluginManager::openPlugin(const std::string &path) {
114 LOGD("Loading plugin: <%s>", path.c_str());
116 void *handle = dlopen(path.c_str(), RTLD_LAZY);
119 LOGW("File could not be dlopened <%s> : <%s>", path.c_str(), dlerror());
122 PluginLibPtr handlePtr(handle, std::ptr_fun(dlclose));
124 //Flush any previous errors
126 create_t creator = reinterpret_cast<create_t>(dlsym(handle, "create"));
129 if ((error = dlerror()) != NULL) {
130 LOGE("Couldn't resolve symbol <create> from lib <%s> : <%s>", path.c_str(), error);
134 destroy_t destroyer = reinterpret_cast<destroy_t>(dlsym(handle, "destroy"));
135 if ((error = dlerror()) != NULL) {
136 LOGE("Couldn't resolve symbol <destroy> from lib <%s> : <%s>", path.c_str(), error);
140 ExternalPluginPtr pluginPtr(creator(), destroyer);
143 LOGE("Couldn't create plugin for <%s>", path.c_str());
147 auto policies = pluginPtr->getSupportedPolicyDescr();
148 if (policies.empty()) {
149 LOGE("Plugin <%s> does not support any type!", path.c_str());
152 for (auto &desc : policies) {
153 if (!m_plugins.insert(std::make_pair(desc, pluginPtr)).second) {
154 LOGW("Policy: type [%" PRIu16 "] name <%s> was already supported.",
155 desc.type, desc.name.c_str());
157 LOGD("Supported policy: type [%" PRIu16 "] name <%s>", desc.type, desc.name.c_str());
161 m_pluginLibs.push_back(std::move(handlePtr));
164 } // namespace Cynara