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/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;
84 void initSession(int widgetHandle);
85 void startSession(int widgetHandle,
86 JSGlobalContextRef context,
88 const char* encodedBundle,
91 void stopSession(JSGlobalContextRef context);
93 void performLibrariesUnload();
95 bool loadPluginOnDemand(const WrtDB::DbPluginHandle &pluginHandle,
96 JavaScriptObject& parentObject,
97 JSGlobalContextRef context);
99 void loadFrame(JSGlobalContextRef context);
100 void unloadFrame(JSGlobalContextRef context);
102 void setCustomProperties(JSGlobalContextRef ctx,
104 const char* encodedBundle,
107 void dispatchJavaScriptEvent(JSGlobalContextRef ctx,
108 CustomEventType eventType,
111 static bool s_sanityCheck;
114 IMPLEMENT_SINGLETON(PluginLogic);
116 bool PluginLogic::Impl::s_sanityCheck = false;
118 #define PLUGIN_LOGIC_SANITY_CHECK \
119 if (!s_sanityCheck) \
121 LogError("Object is not available. Wrong flow occured"); \
125 PluginLogic::Impl::Impl()
127 s_sanityCheck = true;
129 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_PLUGINS");
130 LogDebug("Initializing Plugin Logic...");
131 m_pluginsSupport = PluginContainerSupportPtr(new PluginContainerSupport());
133 // explicit call to keep singleton's lifetime until calling destructor.
134 JsFunctionManagerSingleton::Instance();
135 JavaScriptInterfaceSingleton::Instance();
138 PluginLogic::Impl::~Impl()
142 s_sanityCheck = false;
144 FOREACH(it, m_sessions)
146 LogError("Must stop widget session before exit!");
147 it->second->stopSession();
150 LogDebug("Deinitializing plugin Logic...");
153 void PluginLogic::initSession(int widgetHandle)
155 m_impl->initSession(widgetHandle);
158 void PluginLogic::startSession(int widgetHandle,
159 JSGlobalContextRef ctx,
161 const char* encodedBundle,
164 m_impl->startSession(widgetHandle, ctx, scaleFactor, encodedBundle, theme);
167 void PluginLogic::stopSession(JSGlobalContextRef context)
169 m_impl->stopSession(context);
172 void PluginLogic::performLibrariesUnload()
174 LogError("Libraries unload TURNED OFF");
175 // m_impl->performLibrariesUnload();
178 bool PluginLogic::loadPluginOnDemand(
179 const WrtDB::DbPluginHandle &pluginHandle,
180 JavaScriptObject& parentObject,
181 JSGlobalContextRef context)
183 return m_impl->loadPluginOnDemand(pluginHandle, parentObject, context);
186 void PluginLogic::loadPluginsIntoIframes(JSGlobalContextRef /*context*/)
188 LogError("This function is Deprecated");
191 void PluginLogic::setCustomProperties(double /*scaleFactor*/,
192 const char* /*encodedBundle*/,
193 const char* /*theme*/)
195 LogError("This function is DEPRECATED");
198 void PluginLogic::setCustomProperties(JSGlobalContextRef context,
200 const char* encodedBundle,
203 m_impl->setCustomProperties(context, scaleFactor, encodedBundle, theme);
206 void PluginLogic::dispatchJavaScriptEvent(CustomEventType /*eventType*/)
208 LogError("This function is DEPRECATED");
211 void PluginLogic::dispatchJavaScriptEvent(JSGlobalContextRef context,
212 CustomEventType eventType,
215 m_impl->dispatchJavaScriptEvent(context, eventType, data);
218 void PluginLogic::loadFrame(JSGlobalContextRef context)
220 m_impl->loadFrame(context);
223 void PluginLogic::unloadFrame(JSGlobalContextRef context)
225 m_impl->unloadFrame(context);
228 PluginLogic::PluginLogic() : m_impl(new PluginLogic::Impl())
231 PluginLogic::~PluginLogic()
234 void PluginLogic::Impl::initSession(int widgetHandle)
236 LogInfo("init pluginLogic...");
238 m_pluginsSupport->Initialize(widgetHandle);
240 //add standard objects
241 LogDebug("Preload plugins so file");
243 PluginContainerSupport::PluginsList pluginList =
244 m_pluginsSupport->getPluginsList();
246 FOREACH(it, pluginList)
248 PluginModelPtr& pluginModel = *it;
250 if (!pluginModel->LibraryDependencies.Get()->empty()) {
255 PluginPtr pluginLib = pluginModel->LibraryInstance.Get();
258 std::string path = pluginModel->LibraryPath.Get() +
259 std::string(LIBRARY_PATH_SEPARATOR) +
260 pluginModel->LibraryName.Get();
262 pluginLib = Plugin::LoadFromFile(path);
265 LogError("Loading library failed");
267 pluginModel->LibraryInstance.Set(pluginLib);
270 "pluginModel->LibraryInstance.Set() : " <<
271 pluginLib->GetFileName());
274 LogDebug("Already loaded");
278 LogDebug("Preload plugins so file_done");
281 void PluginLogic::Impl::startSession(int widgetHandle,
282 JSGlobalContextRef context,
284 const char* encodedBundle,
287 LogInfo("Starting widget session...");
289 if (!m_pluginsSupport->isInitialized()) {
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 LogWarning("Session already started!");
300 auto newSession = JSPageSessionPtr(new JSPageSession(m_pluginsSupport));
301 newSession->startSession(widgetHandle,
307 m_sessions[context] = newSession;
310 void PluginLogic::Impl::stopSession(JSGlobalContextRef context)
312 LogInfo("Stopping widget session...");
314 auto sessionIt = m_sessions.find(context);
315 if (sessionIt == m_sessions.end()) {
316 LogError("Session not exist!");
320 sessionIt->second->stopSession();
321 m_sessions.erase(sessionIt);
323 LogInfo("Widget session stopped.");
326 bool PluginLogic::Impl::loadPluginOnDemand(
327 const WrtDB::DbPluginHandle &pluginHandle,
328 JavaScriptObject& parentObject,
329 JSGlobalContextRef context
332 LogInfo("Load plugin on demand");
334 auto sessionIt = m_sessions.find(context);
335 if (sessionIt == m_sessions.end()) {
336 LogWarning("Session not exist!");
340 return sessionIt->second->loadPluginOnDemand(pluginHandle,
345 void PluginLogic::Impl::loadFrame(JSGlobalContextRef context)
347 LogDebug("Load a frame");
349 PLUGIN_LOGIC_SANITY_CHECK
351 auto sessionIt = m_sessions.find(context);
352 if (sessionIt == m_sessions.end()) {
353 LogWarning("Session not exist!");
357 sessionIt->second->loadFrame(context);
360 void PluginLogic::Impl::unloadFrame(JSGlobalContextRef context)
362 LogDebug("Unload a frame");
364 PLUGIN_LOGIC_SANITY_CHECK
366 auto sessionIt = m_sessions.find(context);
367 if (sessionIt == m_sessions.end()) {
368 LogWarning("Session not exist!");
372 sessionIt->second->unloadFrame(context);
374 // I don't know why this session should be removed here.
375 // session list is removed also from stopSession().
376 //m_sessions.erase(sessionIt);
379 void PluginLogic::Impl::setCustomProperties(JSGlobalContextRef context,
381 const char* encodedBundle,
385 "set properties of window object " << scaleFactor << ", "
386 << encodedBundle << ", " <<
389 PLUGIN_LOGIC_SANITY_CHECK
391 auto sessionIt = m_sessions.find(context);
392 if (sessionIt == m_sessions.end()) {
393 LogWarning("Session not exist!");
397 sessionIt->second->setCustomProperties(scaleFactor,
402 void PluginLogic::Impl::dispatchJavaScriptEvent(JSGlobalContextRef context,
403 CustomEventType eventType,
406 LogDebug("Dispatch event");
408 PLUGIN_LOGIC_SANITY_CHECK
410 auto sessionIt = m_sessions.find(context);
411 if (sessionIt == m_sessions.end()) {
412 LogWarning("Session not exist!");
416 sessionIt->second->dispatchJavaScriptEvent(eventType, data);