Update wrt-plugins-common_0.3.53
[framework/web/wrt-plugins-common.git] / src / plugin-loading / plugin_logic.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_logic.cpp
18  * @author      Piotr Fatyga (p.fatyga@samsung.com)
19  * @author      Grzegorz Krawczyk (g.krawczyk@samsung.com)
20  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
21  * @version     1.0
22  * @brief       This file is the implementation file of plugin and
23  *              feature loading routines
24  * @brief       This code is intended to work behind view controller
25  */
26
27 #include "plugin_logic.h"
28
29 #include <dpl/assert.h>
30 #include <dpl/scoped_array.h>
31 #include <dpl/log/log.h>
32 #include <dpl/foreach.h>
33 #include <dpl/singleton_impl.h>
34 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
35 #include <dpl/wrt-dao-ro/common_dao_types.h>
36 #include <dpl/wrt-dao-ro/global_config.h>
37
38 #include <JavaScriptCore/JavaScript.h>
39
40 #include <string>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <dirent.h>
44 #include <errno.h>
45 #include <fstream>
46 #include <map>
47 #include <list>
48 #include <vector>
49 #include <algorithm>
50 #include <cstring>
51
52 #include <wrt_plugin_export.h>
53 #include <js_overlay_types.h>
54
55 #include "explorer.h"
56 #include "plugin.h"
57 #include "plugin_model.h"
58 #include "javascript_interface.h"
59 #include "js_function_manager.h"
60 #include "plugin_container_support.h"
61
62 #include "js_page_session.h"
63
64 using namespace std;
65 using namespace WrtDB;
66 using namespace WrtPlugins::W3C;
67
68 namespace {
69 const char *LIBRARY_PATH_SEPARATOR = "/";
70 const char* FEATURE_WAC20_DEVICAPIS_NAME = "http://wacapps.net/api/deviceapis";
71 }
72
73 class PluginLogic::Impl
74 {
75     PluginContainerSupportPtr m_pluginsSupport;
76
77     typedef std::map<JSContextRef, JSPageSessionPtr> PagesSessionsSet;
78     PagesSessionsSet m_sessions;
79
80
81   public:
82     Impl();
83     ~Impl();
84
85     // Widget session
86     void startSession(int widgetHandle,
87                       JSGlobalContextRef context,
88                       double scaleFactor,
89                       const char* encodedBundle,
90                       const char* theme);
91
92     void stopSession(JSGlobalContextRef context);
93
94     void performLibrariesUnload();
95
96     bool loadPluginOnDemand(const WrtDB::DbPluginHandle &pluginHandle,
97                             JavaScriptObject& parentObject,
98                             JSGlobalContextRef context);
99
100     void loadFrame(JSGlobalContextRef context);
101     void unloadFrame(JSGlobalContextRef context);
102
103     void setCustomProperties(JSGlobalContextRef ctx,
104                              double scaleFactor,
105                              const char* encodedBundle,
106                              const char* theme);
107
108     void dispatchJavaScriptEvent(JSGlobalContextRef ctx,
109                                  CustomEventType eventType);
110
111 };
112
113 IMPLEMENT_SINGLETON(PluginLogic);
114
115 PluginLogic::Impl::Impl()
116 {
117     DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_PLUGINS");
118     LogDebug("Initializing Plugin Logic...");
119     m_pluginsSupport = PluginContainerSupportPtr(new PluginContainerSupport());
120
121     // explicit call to keep singleton's lifetime until calling destructor.
122     JsFunctionManagerSingleton::Instance();
123     JavaScriptInterfaceSingleton::Instance();
124 }
125
126 PluginLogic::Impl::~Impl()
127 {
128     FOREACH(it, m_sessions)
129     {
130         LogError("Must stop widget session before exit!");
131         it->second->stopSession();
132     }
133
134     LogDebug("Deinitializing plugin Logic...");
135 }
136
137
138 void PluginLogic::startSession(int widgetHandle,
139                                JSGlobalContextRef ctx,
140                                double scaleFactor,
141                                const char* encodedBundle,
142                                const char* theme)
143 {
144     m_impl->startSession(widgetHandle, ctx, scaleFactor, encodedBundle, theme);
145 }
146
147 void PluginLogic::stopSession(JSGlobalContextRef context)
148 {
149     m_impl->stopSession(context);
150 }
151
152 void PluginLogic::performLibrariesUnload()
153 {
154     LogError("Libraries unload TURNED OFF");
155 //    m_impl->performLibrariesUnload();
156 }
157
158 bool PluginLogic::loadPluginOnDemand(
159     const WrtDB::DbPluginHandle &pluginHandle,
160     JavaScriptObject& parentObject,
161     JSGlobalContextRef context)
162 {
163     return m_impl->loadPluginOnDemand(pluginHandle, parentObject, context);
164 }
165
166 void PluginLogic::loadPluginsIntoIframes(JSGlobalContextRef context)
167 {
168     LogError("This function is Deprecated");
169 }
170
171 void PluginLogic::setCustomProperties(double scaleFactor,
172                                       const char* encodedBundle,
173                                       const char* theme)
174 {
175     LogError("This function is DEPRECATED");
176 }
177
178 void PluginLogic::setCustomProperties(JSGlobalContextRef context,
179                                       double scaleFactor,
180                                       const char* encodedBundle,
181                                       const char* theme)
182 {
183     m_impl->setCustomProperties(context, scaleFactor, encodedBundle, theme);
184 }
185
186 void PluginLogic::dispatchJavaScriptEvent(CustomEventType eventType)
187 {
188     LogError("This function is DEPRECATED");
189 }
190
191 void PluginLogic::dispatchJavaScriptEvent(JSGlobalContextRef context,
192                                           CustomEventType eventType)
193 {
194     m_impl->dispatchJavaScriptEvent(context, eventType);
195 }
196
197 void PluginLogic::loadFrame(JSGlobalContextRef context)
198 {
199     m_impl->loadFrame(context);
200 }
201
202 void PluginLogic::unloadFrame(JSGlobalContextRef context)
203 {
204     m_impl->unloadFrame(context);
205 }
206
207 PluginLogic::PluginLogic() : m_impl(new PluginLogic::Impl())
208 {
209 }
210
211 PluginLogic::~PluginLogic()
212 {
213 }
214
215 void PluginLogic::Impl::startSession(int widgetHandle,
216                                      JSGlobalContextRef context,
217                                      double scaleFactor,
218                                      const char* encodedBundle,
219                                      const char* theme)
220 {
221     LogInfo("Starting widget session...");
222
223     auto sessionIt = m_sessions.find(context);
224
225     // Check if corresponding session if not already created
226     if (sessionIt != m_sessions.end())
227     {
228         LogWarning("Session already started!");
229         return;
230     }
231
232     auto newSession = JSPageSessionPtr(new JSPageSession(m_pluginsSupport));
233     newSession->startSession(widgetHandle,
234                              context,
235                              scaleFactor,
236                              encodedBundle,
237                              theme);
238
239     m_sessions[context] = newSession;
240 }
241
242 void PluginLogic::Impl::stopSession(JSGlobalContextRef context)
243 {
244     LogInfo("Stopping widget session...");
245
246     auto sessionIt = m_sessions.find(context);
247     if (sessionIt == m_sessions.end())
248     {
249         LogError("Session not exist!");
250         return;
251     }
252
253     sessionIt->second->stopSession();
254     m_sessions.erase(sessionIt);
255
256     LogInfo("Widget session stopped.");
257 }
258
259 bool PluginLogic::Impl::loadPluginOnDemand(
260     const WrtDB::DbPluginHandle &pluginHandle,
261     JavaScriptObject& parentObject,
262     JSGlobalContextRef context
263     )
264 {
265     LogInfo("Load plugin on demand");
266
267     auto sessionIt = m_sessions.find(context);
268     if (sessionIt == m_sessions.end())
269     {
270         LogWarning("Session not exist!");
271         return false;
272     }
273
274     return sessionIt->second->loadPluginOnDemand(pluginHandle,
275                                                  parentObject,
276                                                  context);
277 }
278
279 void PluginLogic::Impl::loadFrame(JSGlobalContextRef context)
280 {
281     LogDebug("Load a frame");
282     auto sessionIt = m_sessions.find(context);
283     if (sessionIt == m_sessions.end())
284     {
285         LogWarning("Session not exist!");
286         return;
287     }
288
289     sessionIt->second->loadFrame(context);
290 }
291
292 void PluginLogic::Impl::unloadFrame(JSGlobalContextRef context)
293 {
294     LogDebug("Unload a frame");
295
296     auto sessionIt = m_sessions.find(context);
297     if (sessionIt == m_sessions.end())
298     {
299         LogWarning("Session not exist!");
300         return;
301     }
302
303     sessionIt->second->unloadFrame(context);
304 }
305
306 void PluginLogic::Impl::setCustomProperties(JSGlobalContextRef context,
307                                             double scaleFactor,
308                                             const char* encodedBundle,
309                                             const char* theme)
310 {
311     LogInfo("set properties of window object " << scaleFactor << ", "
312             << encodedBundle << ", " << theme);
313
314     auto sessionIt = m_sessions.find(context);
315     if (sessionIt == m_sessions.end())
316     {
317         LogWarning("Session not exist!");
318         return;
319     }
320
321     sessionIt->second->setCustomProperties(scaleFactor,
322                                            encodedBundle,
323                                            theme);
324
325 }
326
327 void PluginLogic::Impl::dispatchJavaScriptEvent(JSGlobalContextRef context,
328                                                 CustomEventType eventType)
329 {
330     LogDebug("Dispatch event");
331
332     auto sessionIt = m_sessions.find(context);
333     if (sessionIt == m_sessions.end())
334     {
335         LogWarning("Session not exist!");
336         return;
337     }
338
339     sessionIt->second->dispatchJavaScriptEvent(eventType);
340
341
342 }