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 = "/";
70 const char* FEATURE_WAC20_DEVICAPIS_NAME = "http://wacapps.net/api/deviceapis";
73 class PluginLogic::Impl
75 PluginContainerSupportPtr m_pluginsSupport;
77 typedef std::map<JSContextRef, JSPageSessionPtr> PagesSessionsSet;
78 PagesSessionsSet m_sessions;
86 void initSession(int widgetHandle);
87 void startSession(int widgetHandle,
88 JSGlobalContextRef context,
90 const char* encodedBundle,
93 void stopSession(JSGlobalContextRef context);
95 void performLibrariesUnload();
97 bool loadPluginOnDemand(const WrtDB::DbPluginHandle &pluginHandle,
98 JavaScriptObject& parentObject,
99 JSGlobalContextRef context);
101 void loadFrame(JSGlobalContextRef context);
102 void unloadFrame(JSGlobalContextRef context);
104 void setCustomProperties(JSGlobalContextRef ctx,
106 const char* encodedBundle,
109 void dispatchJavaScriptEvent(JSGlobalContextRef ctx,
110 CustomEventType eventType,
113 static bool s_sanityCheck;
116 IMPLEMENT_SINGLETON(PluginLogic);
118 bool PluginLogic::Impl::s_sanityCheck = false;
120 #define PLUGIN_LOGIC_SANITY_CHECK \
123 LogError("Object is not available. Wrong flow occured");\
127 PluginLogic::Impl::Impl()
129 s_sanityCheck = true;
131 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_PLUGINS");
132 LogDebug("Initializing Plugin Logic...");
133 m_pluginsSupport = PluginContainerSupportPtr(new PluginContainerSupport());
135 // explicit call to keep singleton's lifetime until calling destructor.
136 JsFunctionManagerSingleton::Instance();
137 JavaScriptInterfaceSingleton::Instance();
140 PluginLogic::Impl::~Impl()
144 s_sanityCheck = false;
146 FOREACH(it, m_sessions)
148 LogError("Must stop widget session before exit!");
149 it->second->stopSession();
152 LogDebug("Deinitializing plugin Logic...");
155 void PluginLogic::initSession(int widgetHandle)
157 m_impl->initSession(widgetHandle);
160 void PluginLogic::startSession(int widgetHandle,
161 JSGlobalContextRef ctx,
163 const char* encodedBundle,
166 m_impl->startSession(widgetHandle, ctx, scaleFactor, encodedBundle, theme);
169 void PluginLogic::stopSession(JSGlobalContextRef context)
171 m_impl->stopSession(context);
174 void PluginLogic::performLibrariesUnload()
176 LogError("Libraries unload TURNED OFF");
177 // m_impl->performLibrariesUnload();
180 bool PluginLogic::loadPluginOnDemand(
181 const WrtDB::DbPluginHandle &pluginHandle,
182 JavaScriptObject& parentObject,
183 JSGlobalContextRef context)
185 return m_impl->loadPluginOnDemand(pluginHandle, parentObject, context);
188 void PluginLogic::loadPluginsIntoIframes(JSGlobalContextRef context)
190 LogError("This function is Deprecated");
193 void PluginLogic::setCustomProperties(double scaleFactor,
194 const char* encodedBundle,
197 LogError("This function is DEPRECATED");
200 void PluginLogic::setCustomProperties(JSGlobalContextRef context,
202 const char* encodedBundle,
205 m_impl->setCustomProperties(context, scaleFactor, encodedBundle, theme);
208 void PluginLogic::dispatchJavaScriptEvent(CustomEventType eventType)
210 LogError("This function is DEPRECATED");
213 void PluginLogic::dispatchJavaScriptEvent(JSGlobalContextRef context,
214 CustomEventType eventType,
217 m_impl->dispatchJavaScriptEvent(context, eventType, data);
220 void PluginLogic::loadFrame(JSGlobalContextRef context)
222 m_impl->loadFrame(context);
225 void PluginLogic::unloadFrame(JSGlobalContextRef context)
227 m_impl->unloadFrame(context);
230 PluginLogic::PluginLogic() : m_impl(new PluginLogic::Impl())
234 PluginLogic::~PluginLogic()
238 void PluginLogic::Impl::initSession(int widgetHandle)
240 LogInfo("init pluginLogic...");
242 m_pluginsSupport->Initialize(widgetHandle);
244 //add standard objects
245 LogDebug("Preload plugins so file");
247 PluginContainerSupport::PluginsList pluginList =
248 m_pluginsSupport->getPluginsList();
250 FOREACH(it, pluginList)
252 PluginModelPtr& pluginModel = *it;
254 if (!pluginModel->LibraryDependencies.Get()->empty())
260 PluginPtr pluginLib = pluginModel->LibraryInstance.Get();
264 std::string path = pluginModel->LibraryPath.Get() +
265 std::string(LIBRARY_PATH_SEPARATOR) +
266 pluginModel->LibraryName.Get();
268 pluginLib = Plugin::LoadFromFile(path);
272 LogError("Loading library failed");
275 pluginModel->LibraryInstance.Set(pluginLib);
277 LogDebug("pluginModel->LibraryInstance.Set() : " << pluginLib->GetFileName());
282 LogDebug("Already loaded");
286 LogDebug("Preload plugins so file_done");
289 void PluginLogic::Impl::startSession(int widgetHandle,
290 JSGlobalContextRef context,
292 const char* encodedBundle,
295 LogInfo("Starting widget session...");
297 if (!m_pluginsSupport->isInitialized())
299 m_pluginsSupport->Initialize(widgetHandle);
301 auto sessionIt = m_sessions.find(context);
303 // Check if corresponding session if not already created
304 if (sessionIt != m_sessions.end())
306 LogWarning("Session already started!");
310 auto newSession = JSPageSessionPtr(new JSPageSession(m_pluginsSupport));
311 newSession->startSession(widgetHandle,
317 m_sessions[context] = newSession;
320 void PluginLogic::Impl::stopSession(JSGlobalContextRef context)
322 LogInfo("Stopping widget session...");
324 auto sessionIt = m_sessions.find(context);
325 if (sessionIt == m_sessions.end())
327 LogError("Session not exist!");
331 sessionIt->second->stopSession();
332 m_sessions.erase(sessionIt);
334 LogInfo("Widget session stopped.");
337 bool PluginLogic::Impl::loadPluginOnDemand(
338 const WrtDB::DbPluginHandle &pluginHandle,
339 JavaScriptObject& parentObject,
340 JSGlobalContextRef context
343 LogInfo("Load plugin on demand");
345 auto sessionIt = m_sessions.find(context);
346 if (sessionIt == m_sessions.end())
348 LogWarning("Session not exist!");
352 return sessionIt->second->loadPluginOnDemand(pluginHandle,
357 void PluginLogic::Impl::loadFrame(JSGlobalContextRef context)
359 LogDebug("Load a frame");
361 PLUGIN_LOGIC_SANITY_CHECK
363 auto sessionIt = m_sessions.find(context);
364 if (sessionIt == m_sessions.end())
366 LogWarning("Session not exist!");
370 sessionIt->second->loadFrame(context);
373 void PluginLogic::Impl::unloadFrame(JSGlobalContextRef context)
375 LogDebug("Unload a frame");
377 PLUGIN_LOGIC_SANITY_CHECK
379 auto sessionIt = m_sessions.find(context);
380 if (sessionIt == m_sessions.end())
382 LogWarning("Session not exist!");
386 sessionIt->second->unloadFrame(context);
387 m_sessions.erase(sessionIt);
390 void PluginLogic::Impl::setCustomProperties(JSGlobalContextRef context,
392 const char* encodedBundle,
395 LogInfo("set properties of window object " << scaleFactor << ", "
396 << encodedBundle << ", " << theme);
398 PLUGIN_LOGIC_SANITY_CHECK
400 auto sessionIt = m_sessions.find(context);
401 if (sessionIt == m_sessions.end())
403 LogWarning("Session not exist!");
407 sessionIt->second->setCustomProperties(scaleFactor,
413 void PluginLogic::Impl::dispatchJavaScriptEvent(JSGlobalContextRef context,
414 CustomEventType eventType,
417 LogDebug("Dispatch event");
419 PLUGIN_LOGIC_SANITY_CHECK
421 auto sessionIt = m_sessions.find(context);
422 if (sessionIt == m_sessions.end())
424 LogWarning("Session not exist!");
428 sessionIt->second->dispatchJavaScriptEvent(eventType, data);