1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include "application_manager/plugin_manager/rpc_plugin_manager_impl.h"
#include <dlfcn.h>
#include "utils/file_system.h"
namespace application_manager {
namespace plugin_manager {
CREATE_LOGGERPTR_GLOBAL(logger_, "PluginManager")
RPCPluginManagerImpl::RPCPluginManagerImpl(
ApplicationManager& app_manager,
rpc_service::RPCService& rpc_service,
HMICapabilities& hmi_capabilities,
policy::PolicyHandlerInterface& policy_handler)
: app_manager_(app_manager)
, rpc_service_(rpc_service)
, hmi_capabilities_(hmi_capabilities)
, policy_handler_(policy_handler) {}
bool IsLibraryFile(const std::string& file_path) {
size_t pos = file_path.find_last_of(".");
if (std::string::npos == pos) {
return false;
}
if (file_path.substr(pos + 1).compare("so") != 0) {
return false;
}
return true;
}
RPCPluginPtr LoadPlugin(const std::string& full_plugin_path) {
if (!IsLibraryFile(full_plugin_path)) {
LOG4CXX_DEBUG(logger_, "Skip loading " << full_plugin_path);
return RPCPluginPtr();
}
void* plugin_dll = dlopen(full_plugin_path.c_str(), RTLD_LAZY);
if (nullptr == plugin_dll) {
LOG4CXX_ERROR(logger_,
"Failed to open dll " << full_plugin_path << " : "
<< dlerror());
return RPCPluginPtr();
}
typedef RPCPlugin* (*Create)();
Create create_plugin = reinterpret_cast<Create>(dlsym(plugin_dll, "Create"));
char* error_string = dlerror();
if (nullptr != error_string) {
LOG4CXX_ERROR(logger_,
"Failed to export dll's " << full_plugin_path
<< " symbols : " << error_string);
dlclose(plugin_dll);
return RPCPluginPtr();
}
RPCPlugin* plugin = create_plugin();
dlclose(plugin_dll);
return RPCPluginPtr(plugin);
}
uint32_t RPCPluginManagerImpl::LoadPlugins(const std::string& plugins_path) {
LOG4CXX_INFO(logger_, "Loading plugins from " << plugins_path);
std::vector<std::string> plugin_files = file_system::ListFiles(plugins_path);
for (auto& plugin_file : plugin_files) {
std::string full_name = plugins_path + '/' + plugin_file;
auto plugin = LoadPlugin(full_name);
if (!plugin) {
continue;
}
LOG4CXX_DEBUG(logger_,
"Loaded " << plugin->PluginName() << " plugin from "
<< full_name);
if (plugin->Init(
app_manager_, rpc_service_, hmi_capabilities_, policy_handler_)) {
loaded_plugins_.push_back(std::move(plugin));
} else {
LOG4CXX_ERROR(logger_,
"Initialisation of " << plugin->PluginName()
<< " plugin from " << full_name
<< " failed");
}
}
return loaded_plugins_.size();
}
std::vector<RPCPluginPtr>& RPCPluginManagerImpl::GetPlugins() {
return loaded_plugins_;
}
utils::Optional<RPCPlugin> RPCPluginManagerImpl::FindPluginToProcess(
const int32_t function_id,
const commands::Command::CommandSource message_source) {
typedef utils::Optional<RPCPlugin> PluginOptional;
for (auto& plugin : loaded_plugins_) {
if (plugin->IsAbleToProcess(function_id, message_source)) {
return PluginOptional(*plugin);
}
}
return PluginOptional(PluginOptional::EMPTY,
std::string("Plugin for processing RPC not found"));
}
void RPCPluginManagerImpl::ForEachPlugin(
std::function<void(RPCPlugin&)> functor) {
for (auto& plugin : loaded_plugins_) {
functor(*plugin);
}
}
} // namespace plugin_manager
} // namespace application_manager
|