Tizen 2.1 base
[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
37 namespace {
38 const char* DLL_ENTRY_POINT_NAME = "dll_api";
39 }
40
41 namespace WrtPluginsApi
42 {
43
44 void PluginRegistry::AddPlugin(const std::string& libraryName,
45                                Plugin& plugin)
46 {
47     LogDebug("Adding plugin for library: " << libraryName);
48
49     auto libraryIt = m_plugins.find(libraryName);
50     if (m_plugins.end() == libraryIt)
51     {
52         m_plugins[libraryName] = &plugin;
53     }
54 }
55
56 Plugin* PluginRegistry::GetPlugin(const std::string& libraryName)
57 {
58     auto it = m_plugins.find(libraryName);
59     if (it == m_plugins.end())
60     {
61         if (!LoadFromFile(libraryName))
62         {
63            LogError("Failed to load lib" << libraryName);
64            ThrowMsg(PluginNotFound, "Failed to load plugin");
65         }
66
67         return m_plugins[libraryName];
68     }
69
70     return it->second;
71 }
72
73 void PluginRegistry::RemovePlugin(const std::string& libraryName,
74                                   Plugin& plugin)
75 {
76     auto it = m_plugins.find(libraryName);
77     if (it != m_plugins.end())
78     {
79         if (&plugin == it->second)
80         {
81             m_plugins.erase(it);
82         }
83     }
84 }
85
86 void PluginRegistry::UnloadAll()
87 {
88     LogDebug("Unload all plugins");
89
90     typedef void (*UnregisterFunction) (PluginRegistration&, Plugin&);
91
92     FOREACH(libraryIt, m_libraries)
93     {
94         auto pluginIt = m_plugins.find(libraryIt->first);
95         if (m_plugins.end() != pluginIt)
96         {
97             void* handle = dlopen(libraryIt->first.c_str(), RTLD_NOW);
98             if (!handle) {
99                 LogError("Error: " << dlerror());
100                 continue;
101             }
102
103             ExportedApi* entryPoint =
104                 static_cast<ExportedApi*>
105                     (dlsym(handle, GetExportedSymbolName()));
106             if (NULL == entryPoint)
107             {
108                 LogError("Error: " << dlerror());
109                 continue;
110             }
111             if (entryPoint->Unregister == NULL)
112             {
113                 LogError("Error Unregister function not set");
114                 continue;
115             }
116
117             PluginRegistration registration(
118                 new PluginRegistration::Impl(*this, libraryIt->first));
119
120             entryPoint->Unregister(registration, (pluginIt->second));
121
122             m_plugins.erase(pluginIt);
123         }
124         dlclose(libraryIt->second);
125     }
126 }
127
128 bool PluginRegistry::LoadFromFile(const std::string& libraryName)
129 {
130     void* handle = dlopen(libraryName.c_str(), RTLD_NOW);
131     if (!handle) {
132         LogError("Error: " << dlerror());
133         return false;
134     }
135     m_libraries[libraryName] = handle;
136
137     ExportedApi* entryPoint =
138         static_cast<ExportedApi*>(dlsym(handle, GetExportedSymbolName()));
139     if (NULL == entryPoint)
140     {
141         LogError("Error: " << dlerror());
142         return false;
143     }
144
145     if (entryPoint->Register == NULL)
146     {
147         LogError("Error Register function not set");
148         return false;
149     }
150     if (entryPoint->Unregister== NULL)
151     {
152         LogError("Error Unregister function not set");
153         return false;
154     }
155
156     PluginRegistration registration(
157             new PluginRegistration::Impl(*this, libraryName));
158     entryPoint->Register(registration);
159
160     return true;
161 }
162
163
164 PluginRegistry::~PluginRegistry()
165 {
166     //TODO discuss ... when the unload should be called
167 //    UnloadAll();
168 }
169
170 }