merge with master
[platform/framework/web/wrt-plugins-common.git] / src / plugins-api-support / PluginRegistry.cpp
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /**
17  * @file    PluginRegistry.h
18  * @author  Grzegorz Krawczyk (g.krawczyk@samgsung.com)
19  * @version
20  * @brief
21  */
22 #include "PluginRegistry.h"
23 #include "PluginRegistration.h"
24 #include "PluginRegistrationImpl.h"
25 #include "ExportedApi.h"
26
27 #include <dlfcn.h>
28 #include <cstdio>
29 #include <cstdlib>
30 #include <string>
31 #include <algorithm>
32
33 #include <dpl/log/log.h>
34 #include <dpl/foreach.h>
35
36 namespace WrtPluginsApi {
37 void PluginRegistry::AddPlugin(const std::string& libraryName,
38                                Plugin& plugin)
39 {
40     LogDebug("Adding plugin for library: " << libraryName);
41
42     auto libraryIt = m_plugins.find(libraryName);
43     if (m_plugins.end() == libraryIt) {
44         m_plugins[libraryName] = &plugin;
45     }
46 }
47
48 Plugin* PluginRegistry::GetPlugin(const std::string& libraryName)
49 {
50     auto it = m_plugins.find(libraryName);
51     if (it == m_plugins.end()) {
52         if (!LoadFromFile(libraryName)) {
53             LogError("Failed to load lib" << libraryName);
54             ThrowMsg(PluginNotFound, "Failed to load plugin");
55         }
56
57         return m_plugins[libraryName];
58     }
59
60     return it->second;
61 }
62
63 void PluginRegistry::RemovePlugin(const std::string& libraryName,
64                                   Plugin& plugin)
65 {
66     auto it = m_plugins.find(libraryName);
67     if (it != m_plugins.end()) {
68         if (&plugin == it->second) {
69             m_plugins.erase(it);
70         }
71     }
72 }
73
74 void PluginRegistry::UnloadAll()
75 {
76     LogDebug("Unload all plugins");
77
78     typedef void (*UnregisterFunction)(PluginRegistration&, Plugin&);
79
80     FOREACH(libraryIt, m_libraries)
81     {
82         auto pluginIt = m_plugins.find(libraryIt->first);
83         if (m_plugins.end() != pluginIt) {
84             void* handle = dlopen(libraryIt->first.c_str(), RTLD_NOW);
85             if (!handle) {
86                 LogError("Error: " << dlerror());
87                 continue;
88             }
89
90             ExportedApi* entryPoint =
91                 static_cast<ExportedApi*>
92                 (dlsym(handle, GetExportedSymbolName()));
93             if (NULL == entryPoint) {
94                 LogError("Error: " << dlerror());
95                 continue;
96             }
97             if (entryPoint->Unregister == NULL) {
98                 LogError("Error Unregister function not set");
99                 continue;
100             }
101
102             PluginRegistration registration(
103                 new PluginRegistration::Impl(*this, libraryIt->first));
104
105             entryPoint->Unregister(registration, (pluginIt->second));
106
107             m_plugins.erase(pluginIt);
108         }
109         dlclose(libraryIt->second);
110     }
111 }
112
113 bool PluginRegistry::LoadFromFile(const std::string& libraryName)
114 {
115     void* handle = dlopen(libraryName.c_str(), RTLD_NOW);
116     if (!handle) {
117         LogError("Error: " << dlerror());
118         return false;
119     }
120     m_libraries[libraryName] = handle;
121
122     ExportedApi* entryPoint =
123         static_cast<ExportedApi*>(dlsym(handle, GetExportedSymbolName()));
124     if (NULL == entryPoint) {
125         LogError("Error: " << dlerror());
126         return false;
127     }
128
129     if (entryPoint->Register == NULL) {
130         LogError("Error Register function not set");
131         return false;
132     }
133     if (entryPoint->Unregister == NULL) {
134         LogError("Error Unregister function not set");
135         return false;
136     }
137
138     PluginRegistration registration(
139         new PluginRegistration::Impl(*this, libraryName));
140     entryPoint->Register(registration);
141
142     return true;
143 }
144
145 PluginRegistry::~PluginRegistry()
146 {
147     //TODO discuss ... when the unload should be called
148     //    UnloadAll();
149 }
150 }