Update wrt-plugins-common_0.3.60
[platform/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     if (!m_pluginsSupport->isInitialized())
224         m_pluginsSupport->readAllowedPlugins(widgetHandle);
225
226     auto sessionIt = m_sessions.find(context);
227
228     // Check if corresponding session if not already created
229     if (sessionIt != m_sessions.end())
230     {
231         LogWarning("Session already started!");
232         return;
233     }
234
235     auto newSession = JSPageSessionPtr(new JSPageSession(m_pluginsSupport));
236     newSession->startSession(widgetHandle,
237                              context,
238                              scaleFactor,
239                              encodedBundle,
240                              theme);
241
242     m_sessions[context] = newSession;
243 }
244
245 void PluginLogic::Impl::stopSession(JSGlobalContextRef context)
246 {
247     LogInfo("Stopping widget session...");
248
249     auto sessionIt = m_sessions.find(context);
250     if (sessionIt == m_sessions.end())
251     {
252         LogError("Session not exist!");
253         return;
254     }
255
256     sessionIt->second->stopSession();
257     m_sessions.erase(sessionIt);
258
259     LogInfo("Widget session stopped.");
260 }
261
262 bool PluginLogic::Impl::loadPluginOnDemand(
263     const WrtDB::DbPluginHandle &pluginHandle,
264     JavaScriptObject& parentObject,
265     JSGlobalContextRef context
266     )
267 {
268     LogInfo("Load plugin on demand");
269
270     auto sessionIt = m_sessions.find(context);
271     if (sessionIt == m_sessions.end())
272     {
273         LogWarning("Session not exist!");
274         return false;
275     }
276
277     return sessionIt->second->loadPluginOnDemand(pluginHandle,
278                                                  parentObject,
279                                                  context);
280 }
281
282 void PluginLogic::Impl::loadFrame(JSGlobalContextRef context)
283 {
284     LogDebug("Load a frame");
285     auto sessionIt = m_sessions.find(context);
286     if (sessionIt == m_sessions.end())
287     {
288         LogWarning("Session not exist!");
289         return;
290     }
291
292     sessionIt->second->loadFrame(context);
293 }
294
295 void PluginLogic::Impl::unloadFrame(JSGlobalContextRef context)
296 {
297     LogDebug("Unload a frame");
298
299     auto sessionIt = m_sessions.find(context);
300     if (sessionIt == m_sessions.end())
301     {
302         LogWarning("Session not exist!");
303         return;
304     }
305
306     sessionIt->second->unloadFrame(context);
307 }
308
309 void PluginLogic::Impl::setCustomProperties(JSGlobalContextRef context,
310                                             double scaleFactor,
311                                             const char* encodedBundle,
312                                             const char* theme)
313 {
314     LogInfo("set properties of window object " << scaleFactor << ", "
315             << encodedBundle << ", " << theme);
316
317     auto sessionIt = m_sessions.find(context);
318     if (sessionIt == m_sessions.end())
319     {
320         LogWarning("Session not exist!");
321         return;
322     }
323
324     sessionIt->second->setCustomProperties(scaleFactor,
325                                            encodedBundle,
326                                            theme);
327
328 }
329
330 void PluginLogic::Impl::dispatchJavaScriptEvent(JSGlobalContextRef context,
331                                                 CustomEventType eventType)
332 {
333     LogDebug("Dispatch event");
334
335     auto sessionIt = m_sessions.find(context);
336     if (sessionIt == m_sessions.end())
337     {
338         LogWarning("Session not exist!");
339         return;
340     }
341
342     sessionIt->second->dispatchJavaScriptEvent(eventType);
343
344
345 }