Initialize Tizen 2.3
[framework/web/wrt-plugins-common.git] / src_wearable / plugin-loading / plugin.cpp
1 /*
2  * Copyright (c) 2011 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        plugin.cpp
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of plugin
21  */
22 #include "plugin.h"
23 #include <dpl/log/secure_log.h>
24 #include <dpl/assert.h>
25 #include <dlfcn.h>
26
27 Plugin::Plugin(const std::string &fileName,
28                void *libHandle,
29                on_widget_start_proc *apiOnWidgetStart,
30                on_widget_init_proc *apiOnWidgetInit,
31                on_widget_stop_proc *apiOnWidgetStop,
32                on_frame_load_proc* apiOnFrameLoad,
33                on_frame_unload_proc* apiOnFrameUnload,
34                const ClassPtrList &apiClassList) :
35     m_fileName(fileName),
36     m_libHandle(libHandle),
37     m_apiOnWidgetStart(apiOnWidgetStart),
38     m_apiOnWidgetInit(apiOnWidgetInit),
39     m_apiOnWidgetStop(apiOnWidgetStop),
40     m_apiOnFrameLoad(apiOnFrameLoad),
41     m_apiOnFrameUnload(apiOnFrameUnload),
42     m_apiClassList(apiClassList)
43 {}
44
45 Plugin::~Plugin()
46 {
47     _D("Unloading plugin library: %s", m_fileName.c_str());
48
49     // Unload library
50     if (dlclose(m_libHandle) != 0) {
51         _E("Cannot close plugin handle");
52     } else {
53         _D("Library is unloaded");
54     }
55 }
56
57 PluginPtr Plugin::LoadFromFile(const std::string& fileName)
58 {
59     static bool logEnable = (getenv("WRT_LOAD_PLUGINS_LOG_ENABLE") != NULL);
60
61     _D("LoadFromFile %s", fileName.c_str());
62
63     void *dllHandle;
64     dllHandle = dlopen(fileName.c_str(), RTLD_LAZY);
65
66     _D("dlopen() done!");
67
68     if (dllHandle == NULL) {
69         const char* error = (const char*)dlerror();
70         _E("Failed to load plugin: %s. Reason: %s",
71            fileName.c_str(),
72            (error != NULL ? error : "unknown"));
73         PluginPtr empty;
74         return empty;
75     }
76
77     // Load new plugin API
78     on_widget_start_proc *onWidgetStartProcPtr = NULL;
79     on_widget_stop_proc *onWidgetStopProcPtr = NULL;
80     on_widget_init_proc *onWidgetInitProcPtr = NULL;
81     on_frame_load_proc *onFrameLoadProcPtr = NULL;
82     on_frame_unload_proc *onFrameUnloadProcPtr = NULL;
83
84     const js_entity_definition_t *rawClassList = NULL;
85     get_widget_entity_map_proc *getWidgetEntityMapProcPtr = NULL;
86
87     onWidgetStartProcPtr =
88         reinterpret_cast<on_widget_start_proc *>(
89             dlsym(dllHandle, PLUGIN_WIDGET_START_PROC_NAME));
90     onWidgetInitProcPtr =
91         reinterpret_cast<on_widget_init_proc *>(
92             dlsym(dllHandle, PLUGIN_WIDGET_INIT_PROC_NAME));
93     onWidgetStopProcPtr =
94         reinterpret_cast<on_widget_stop_proc *>(
95             dlsym(dllHandle, PLUGIN_WIDGET_STOP_PROC_NAME));
96     onFrameLoadProcPtr =
97         reinterpret_cast<on_frame_load_proc *>(
98             dlsym(dllHandle, PLUGIN_FRAME_LOAD_PROC_NAME));
99     onFrameUnloadProcPtr =
100         reinterpret_cast<on_frame_unload_proc *>(
101             dlsym(dllHandle, PLUGIN_FRAME_UNLOAD_PROC_NAME));
102     getWidgetEntityMapProcPtr =
103         reinterpret_cast<get_widget_entity_map_proc *>(
104             dlsym(dllHandle, PLUGIN_GET_CLASS_MAP_PROC_NAME));
105
106     if (getWidgetEntityMapProcPtr) {
107         rawClassList = (*getWidgetEntityMapProcPtr)();
108
109         if (logEnable) {
110             _D("rawClassList : %p by getWidgetClassMapProcPtr()",
111                rawClassList);
112         }
113     } else {
114         rawClassList =
115             static_cast<const js_entity_definition_t *>(dlsym(dllHandle,
116                                                               PLUGIN_CLASS_MAP_NAME));
117         if (logEnable) { _D("rawClassList : %p", rawClassList); }
118     }
119
120     if (NULL == onWidgetStartProcPtr || NULL == onWidgetStopProcPtr ||
121         /*NULL == onWidgetInitProcPtr ||*/ NULL == rawClassList)
122     {
123         if (logEnable) {
124             _W("#####");
125             _W("##### Warning: The following plugin does not support new plugin API.");
126             _W("##### Old plugin API is deprecated. Please update it to new API");
127             _W("#####");
128             _W("##### Plugin: %s has got deprecated or invalid API", fileName.c_str());
129             _W("#####");
130         }
131
132         // Will not load plugin
133         dlclose(dllHandle);
134
135         PluginPtr empty;
136         return empty;
137     }
138
139     if (logEnable) {
140         _D("#####");
141         _D("##### Plugin: %s supports new plugin API", fileName.c_str());
142         _D("#####");
143         _D("##### $onWidgetStartProc: %p", onWidgetStartProcPtr);
144         _D("##### $onWidgetInitProc: %p", onWidgetInitProcPtr);
145         _D("##### $onWidgetStopProc %p", onWidgetStopProcPtr);
146         _D("##### $onFrameLoadProc %p", onFrameLoadProcPtr);
147         _D("##### $onFrameUnloadProc %p", onFrameUnloadProcPtr);
148         _D("##### $classMap: %p", reinterpret_cast<const void *>(rawClassList));
149         _D("##### ");
150         _D("##### Class map:");
151     }
152
153     const js_entity_definition_t *rawEntityListIterator = rawClassList;
154     ClassPtrList classList(new Plugin::ClassList());
155
156     // Parse all class definitions
157     while (rawEntityListIterator->parent_name != NULL &&
158            rawEntityListIterator->object_name != NULL)
159     {
160         if (logEnable)
161         {
162             // Logging
163             _D("#####");
164             _D("##### [%s]", rawEntityListIterator->object_name);
165             _D("##### Interface: %s", rawEntityListIterator->interface_name);
166             _D("##### Parent: %s", rawEntityListIterator->parent_name);
167         }
168
169         // Register class
170         classList->push_back(ClassPtr(new Class(rawEntityListIterator)));
171
172         // Go to next class
173         ++rawEntityListIterator;
174     }
175
176     // Load export table
177     _D("Plugin successfuly loaded");
178
179     // Insert to loaded modules list
180
181     PluginPtr instance(new Plugin(fileName,
182                                   dllHandle,
183                                   onWidgetStartProcPtr,
184                                   onWidgetInitProcPtr,
185                                   onWidgetStopProcPtr,
186                                   onFrameLoadProcPtr,
187                                   onFrameUnloadProcPtr,
188                                   classList));
189
190     return instance;
191 }
192
193 std::string Plugin::GetFileName() const
194 {
195     return m_fileName;
196 }
197
198 void Plugin::OnWidgetStart(int widgetId)
199 {
200     if (NULL != m_apiOnWidgetStart) {
201         (*m_apiOnWidgetStart)(widgetId);
202         _D("Called!");
203     }
204 }
205
206 void Plugin::OnWidgetInit(feature_mapping_interface_t* mapping)
207 {
208     AssertMsg(NULL != mapping, "NULL mapping interface provided");
209     if (NULL != m_apiOnWidgetInit) {
210         (*m_apiOnWidgetInit)(mapping);
211         _D("Called!");
212     }
213 }
214
215 void Plugin::OnWidgetStop(int widgetId)
216 {
217     if (NULL != m_apiOnWidgetStop) {
218         (*m_apiOnWidgetStop)(widgetId);
219         _D("Called!");
220     }
221 }
222
223 void Plugin::OnFrameLoad(java_script_context_t context)
224 {
225     if (NULL != m_apiOnFrameLoad) {
226         (*m_apiOnFrameLoad)(context);
227         _D("Called!");
228     }
229 }
230
231 void Plugin::OnFrameUnload(java_script_context_t context)
232 {
233     if (NULL != m_apiOnFrameUnload) {
234         (*m_apiOnFrameUnload)(context);
235         _D("Called!");
236     }
237 }
238
239 const Plugin::ClassPtrList Plugin::GetClassList() const
240 {
241     return m_apiClassList;
242 }