2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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)
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
27 #include "plugin_logic.h"
29 #include <dpl/assert.h>
30 #include <dpl/scoped_array.h>
31 #include <dpl/log/secure_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>
38 #include <JavaScriptCore/JavaScript.h>
41 #include <sys/types.h>
52 #include <wrt_plugin_export.h>
53 #include <js_overlay_types.h>
57 #include "plugin_model.h"
58 #include "javascript_interface.h"
59 #include "js_function_manager.h"
60 #include "plugin_container_support.h"
62 #include "js_page_session.h"
65 using namespace WrtDB;
66 using namespace WrtPlugins::W3C;
69 const char *LIBRARY_PATH_SEPARATOR = "/";
72 class PluginLogic::Impl
74 PluginContainerSupportPtr m_pluginsSupport;
76 typedef std::map<JSContextRef, JSPageSessionPtr> PagesSessionsSet;
77 PagesSessionsSet m_sessions;
78 unsigned int m_windowHandle;
85 void initSession(int widgetHandle);
86 void startSession(int widgetHandle,
87 JSGlobalContextRef context,
89 const char* encodedBundle,
92 void stopSession(JSGlobalContextRef context);
94 void performLibrariesUnload();
96 bool loadPluginOnDemand(const WrtDB::DbPluginHandle &pluginHandle,
97 JavaScriptObject& parentObject,
98 JSGlobalContextRef context);
100 void loadFrame(JSGlobalContextRef context);
101 void unloadFrame(JSGlobalContextRef context);
103 void setCustomProperties(JSGlobalContextRef ctx,
105 const char* encodedBundle,
108 void dispatchJavaScriptEvent(JSGlobalContextRef ctx,
109 CustomEventType eventType,
112 unsigned int windowHandle() const;
113 void setWindowHandle(unsigned int handle);
115 static bool s_sanityCheck;
118 IMPLEMENT_SINGLETON(PluginLogic);
120 bool PluginLogic::Impl::s_sanityCheck = false;
122 #define PLUGIN_LOGIC_SANITY_CHECK \
123 if (!s_sanityCheck) \
125 _E("Object is not available. Wrong flow occured"); \
129 PluginLogic::Impl::Impl() :
132 s_sanityCheck = true;
134 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_PLUGINS");
135 _D("Initializing Plugin Logic...");
136 m_pluginsSupport = PluginContainerSupportPtr(new PluginContainerSupport());
138 // explicit call to keep singleton's lifetime until calling destructor.
139 JsFunctionManagerSingleton::Instance();
140 JavaScriptInterfaceSingleton::Instance();
143 PluginLogic::Impl::~Impl()
147 s_sanityCheck = false;
149 FOREACH(it, m_sessions)
151 _W("Must stop widget session before exit!");
152 it->second->stopSession();
156 void PluginLogic::initSession(int widgetHandle)
158 m_impl->initSession(widgetHandle);
161 void PluginLogic::startSession(int widgetHandle,
162 JSGlobalContextRef ctx,
164 const char* encodedBundle,
167 m_impl->startSession(widgetHandle, ctx, scaleFactor, encodedBundle, theme);
170 void PluginLogic::stopSession(JSGlobalContextRef context)
172 m_impl->stopSession(context);
175 void PluginLogic::performLibrariesUnload()
177 _W("This function is DEPRECATED");
178 // m_impl->performLibrariesUnload();
181 bool PluginLogic::loadPluginOnDemand(
182 const WrtDB::DbPluginHandle &pluginHandle,
183 JavaScriptObject& parentObject,
184 JSGlobalContextRef context)
186 return m_impl->loadPluginOnDemand(pluginHandle, parentObject, context);
189 void PluginLogic::loadPluginsIntoIframes(JSGlobalContextRef /*context*/)
191 _W("This function is DEPRECATED");
194 void PluginLogic::setCustomProperties(double /*scaleFactor*/,
195 const char* /*encodedBundle*/,
196 const char* /*theme*/)
198 _W("This function is DEPRECATED");
201 void PluginLogic::setCustomProperties(JSGlobalContextRef context,
203 const char* encodedBundle,
206 m_impl->setCustomProperties(context, scaleFactor, encodedBundle, theme);
209 void PluginLogic::dispatchJavaScriptEvent(CustomEventType /*eventType*/)
211 _W("This function is DEPRECATED");
214 void PluginLogic::dispatchJavaScriptEvent(JSGlobalContextRef context,
215 CustomEventType eventType,
218 m_impl->dispatchJavaScriptEvent(context, eventType, data);
221 void PluginLogic::loadFrame(JSGlobalContextRef context)
223 m_impl->loadFrame(context);
226 void PluginLogic::unloadFrame(JSGlobalContextRef context)
228 m_impl->unloadFrame(context);
231 unsigned int PluginLogic::windowHandle() const
233 return m_impl->windowHandle();
236 void PluginLogic::setWindowHandle(unsigned int handle)
238 m_impl->setWindowHandle(handle);
241 PluginLogic::PluginLogic() : m_impl(new PluginLogic::Impl())
244 PluginLogic::~PluginLogic()
247 void PluginLogic::Impl::initSession(int widgetHandle)
249 _D(">---------------------[init session START]---------------------<");
251 m_pluginsSupport->Initialize(widgetHandle);
252 PluginContainerSupport::PluginsList rootPluginList =
253 m_pluginsSupport->getRootPlugins();
255 FOREACH(it, rootPluginList)
257 PluginModelPtr& pluginModel = *it;
258 PluginPtr pluginLib = pluginModel->LibraryInstance.Get();
261 std::string path = pluginModel->LibraryPath.Get() +
262 std::string(LIBRARY_PATH_SEPARATOR) +
263 pluginModel->LibraryName.Get();
265 pluginLib = Plugin::LoadFromFile(path);
268 _W("Loading library failed");
270 pluginModel->LibraryInstance.Set(pluginLib);
271 _D("pluginModel->LibraryInstance.Set() : %s",
272 pluginLib->GetFileName().c_str());
275 _D("Already loaded");
278 _D("========== init session END ==========");
281 void PluginLogic::Impl::startSession(int widgetHandle,
282 JSGlobalContextRef context,
284 const char* encodedBundle,
287 _D("========== start session START ==========");
289 if (!m_pluginsSupport->isInitialized(widgetHandle)) {
290 m_pluginsSupport->Initialize(widgetHandle);
292 auto sessionIt = m_sessions.find(context);
294 // Check if corresponding session if not already created
295 if (sessionIt != m_sessions.end()) {
296 _W("Session already started!");
298 auto newSession = JSPageSessionPtr(new JSPageSession(m_pluginsSupport));
299 newSession->startSession(widgetHandle,
305 m_sessions[context] = newSession;
307 _D("========== start session END ==========");
310 void PluginLogic::Impl::stopSession(JSGlobalContextRef context)
312 _D("========== stop session START ==========");
314 auto sessionIt = m_sessions.find(context);
315 if (sessionIt == m_sessions.end()) {
316 _W("Session not exist!");
318 sessionIt->second->stopSession();
319 m_sessions.erase(sessionIt);
321 _D("========== stop session END ==========");
324 bool PluginLogic::Impl::loadPluginOnDemand(
325 const WrtDB::DbPluginHandle &pluginHandle,
326 JavaScriptObject& parentObject,
327 JSGlobalContextRef context
330 _D("========== load ondemand plugin ==========");
332 auto sessionIt = m_sessions.find(context);
333 if (sessionIt == m_sessions.end()) {
334 _W("Session not exist!");
338 return sessionIt->second->loadPluginOnDemand(pluginHandle,
343 void PluginLogic::Impl::loadFrame(JSGlobalContextRef context)
345 _D("========== load frame START ==========");
346 PLUGIN_LOGIC_SANITY_CHECK
348 auto sessionIt = m_sessions.find(context);
349 if (sessionIt == m_sessions.end()) {
350 _W("Session not exist!");
352 sessionIt->second->loadFrame(context);
354 _D("========== load frame END ==========");
357 void PluginLogic::Impl::unloadFrame(JSGlobalContextRef context)
359 _D("========== unload frame START ==========");
360 PLUGIN_LOGIC_SANITY_CHECK
362 auto sessionIt = m_sessions.find(context);
363 if (sessionIt == m_sessions.end()) {
364 LogWarning("Session not exist!");
366 sessionIt->second->unloadFrame(context);
368 // I don't know why this session should be removed here.
369 // session list is removed also from stopSession().
370 //m_sessions.erase(sessionIt);
372 _D("========== unload frame END ==========");
375 void PluginLogic::Impl::setCustomProperties(JSGlobalContextRef context,
377 const char* encodedBundle,
380 PLUGIN_LOGIC_SANITY_CHECK
382 auto sessionIt = m_sessions.find(context);
383 if (sessionIt == m_sessions.end()) {
384 _W("Session not exist!");
388 sessionIt->second->setCustomProperties(scaleFactor,
393 void PluginLogic::Impl::dispatchJavaScriptEvent(JSGlobalContextRef context,
394 CustomEventType eventType,
397 PLUGIN_LOGIC_SANITY_CHECK
399 auto sessionIt = m_sessions.find(context);
400 if (sessionIt == m_sessions.end()) {
401 _W("Session not exist!");
405 sessionIt->second->dispatchJavaScriptEvent(eventType, data);
408 unsigned int PluginLogic::Impl::windowHandle() const
410 if (!s_sanityCheck) {
411 LogError("Object is not available. Wrong flow occured");
413 return m_windowHandle;
416 void PluginLogic::Impl::setWindowHandle(unsigned int handle)
418 PLUGIN_LOGIC_SANITY_CHECK
419 m_windowHandle = handle;