2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 AppBoxRenderView.cpp
18 * @author Yunchan Cho (yunchan.cho@samsung.com)
27 #include <livebox-service.h>
28 #include <i_runnable_widget_object.h>
29 #include <core_module.h>
30 #include <dpl/fast_delegate.h>
31 #include <Core/BoxSchemeHandler.h>
32 #include <Core/View/IRenderView.h>
33 #include <Core/View/IPdHelper.h>
34 #include <Core/View/PdHelper.h>
35 #include <API/web_provider_livebox_info.h>
36 #include <Core/Util/Log.h>
37 #include "AppBoxObserver.h"
38 #include "AppBoxRenderBuffer.h"
39 #include "AppBoxRenderView.h"
41 #define RENDER_MAX_TIME 10.0
43 // injection javascript file regarding creating js object used by box and pd
44 static const std::string injectionFile("/usr/share/web-provider/injection.js");
46 AppBoxRenderView::AppBoxRenderView(
47 std::string boxId, std::string instanceId,
48 Evas_Object* boxWin, EwkContextPtr ewkContext)
51 , m_instanceId(instanceId)
60 , m_ewkContext(ewkContext)
63 m_appId = getAppId(m_boxId);
64 if (m_appId.empty()) {
65 throw; //exception throw!
68 evas_object_show(m_boxWin);
69 m_renderBuffer = AppBoxObserver::Instance()->getRenderBuffer(m_instanceId);
70 AppBoxObserver::Instance()->registerRenderView(m_instanceId, this);
73 AppBoxRenderView::~AppBoxRenderView()
76 evas_object_hide(m_boxWin);
77 AppBoxObserver::Instance()->unregisterRenderView(m_instanceId);
80 void AppBoxRenderView::showBox(RenderInfoPtr renderInfo)
84 // delete already running timer
88 if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
89 m_renderBuffer->deleteTouchTimer();
93 m_startUrl = getStartUrl(URL_TYPE_BOX, renderInfo->defaultUrlParams);
96 LogD("can't create view instance");
100 // in case of showing box by request of pd open
102 m_pdHelper->setBaseWebView(m_baseWebView);
105 // resize webview fitted to width, height of Box
112 m_renderBuffer->startCanvasUpdate();
114 m_renderInfo = renderInfo;
117 bool AppBoxRenderView::createView()
124 m_baseWebView = NULL;
126 #ifdef MULTIPROCESS_SERVICE_SUPPORT
127 m_view = WRT::CoreModuleSingleton::
128 Instance().getRunnableWidgetObject(m_appId, DPL::Optional<unsigned>());
130 m_view = WRT::CoreModuleSingleton::
131 Instance().getRunnableWidgetObject(m_appId);
134 if (m_startUrl.empty()) {
135 LogD("no start url");
138 m_view->PrepareView(m_startUrl, m_boxWin, m_ewkContext.get());
139 m_view->CheckBeforeLaunch();
141 // set callback functions of RunnableWidgetObject
142 WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
143 cbs->loadStart = DPL::MakeDelegate(this, &AppBoxRenderView::startLoadCallback);
144 cbs->loadFinish = DPL::MakeDelegate(this, &AppBoxRenderView::finishLoadCallback);
145 cbs->bufferSet = DPL::MakeDelegate(this, &AppBoxRenderView::setBufferCallback);
146 cbs->bufferUnset = DPL::MakeDelegate(this, &AppBoxRenderView::unsetBufferCallback);
147 cbs->windowCreateBefore = DPL::MakeDelegate(this, &AppBoxRenderView::createWindowBeforeCallback);
148 cbs->windowCreateAfter = DPL::MakeDelegate(this, &AppBoxRenderView::createWindowAfterCallback);
149 cbs->navigationDecide = DPL::MakeDelegate(this, &AppBoxRenderView::decideNavigationCallback);
150 m_view->SetUserDelegates(cbs);
153 m_baseWebView = m_view->GetCurrentWebview();
155 // To support transparent background
156 evas_object_color_set(m_baseWebView, 0, 0, 0, 0);
157 evas_object_layer_set(m_baseWebView, EVAS_LAYER_MAX);
161 bool AppBoxRenderView::destroyView()
165 m_renderBuffer->stopCanvasUpdate();
170 m_baseWebView = NULL;
176 void AppBoxRenderView::hideBox()
182 void AppBoxRenderView::pauseBox()
187 void AppBoxRenderView::resumeBox()
192 void AppBoxRenderView::showPd(Evas_Object* pdWin, RenderInfoPtr renderInfo)
197 std::string pdStartUrl = getStartUrl(URL_TYPE_PD, renderInfo->defaultUrlParams);
198 m_pdHelper = PdHelper::create(pdWin, pdStartUrl, renderInfo);
201 evas_object_show(pdWin);
202 showBox(m_renderInfo);
205 void AppBoxRenderView::hidePd()
212 // stop box webview after render timer
216 Evas_Object* AppBoxRenderView::getBoxWebView()
218 return m_baseWebView;
221 Evas_Object* AppBoxRenderView::getPdWebView()
227 return m_pdHelper->getPdWebView();
230 std::string AppBoxRenderView::getAppId(std::string& boxId)
234 const char* appId = web_provider_livebox_get_app_id(boxId.c_str());
236 LogD("no appid of %s", boxId.c_str());
237 return std::string();
240 return std::string(appId);
243 std::string AppBoxRenderView::getStartUrl(UrlType type, std::string& defaultParams)
248 url = livebox_service_lb_script_path(m_boxId.c_str());
251 url = livebox_service_pd_script_path(m_boxId.c_str());
254 LogD("no available type");
257 // add default parameters to start url
258 url += defaultParams;
263 Evas_Object* AppBoxRenderView::getCurrentSnapShot()
267 m_snapshot = m_renderBuffer->getSnapshot();
268 //evas_object_layer_set(m_snapshot, EVAS_LAYER_MAX);
273 void AppBoxRenderView::clearSnapShot()
277 evas_object_layer_set(m_snapshot, EVAS_LAYER_MIN);
278 //evas_object_hide(m_snapshot);
279 evas_object_del(m_snapshot);
284 void AppBoxRenderView::addRenderTimer()
287 if (m_fireRenderTimer) {
291 m_fireRenderTimer = ecore_timer_add(
293 fireRenderTimerCallback,
297 void AppBoxRenderView::deleteRenderTimer()
300 if (m_fireRenderTimer) {
301 ecore_timer_del(m_fireRenderTimer);
302 m_fireRenderTimer = NULL;
306 Eina_Bool AppBoxRenderView::fireRenderTimerCallback(void* data)
310 AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
311 This->m_fireRenderTimer = NULL;
313 This->m_renderBuffer->stopCanvasUpdate();
314 if (web_provider_livebox_get_mouse_event(This->m_boxId.c_str())) {
316 This->m_renderBuffer->deleteTouchTimer();
317 This->m_view->Suspend();
319 // Before webview should be removed,
320 // new evas object with last render data should be created
321 // otherwise, after webview is removed, box is white screen.
322 evas_object_show(This->getCurrentSnapShot());
326 return ECORE_CALLBACK_CANCEL;
329 Eina_Bool AppBoxRenderView::openPdIdlerCallback(void* data)
332 AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
333 if (This && This->m_pdHelper) {
334 This->m_pdHelper->startOpen();
336 return ECORE_CALLBACK_CANCEL;
339 void AppBoxRenderView::executeScriptCallback(
340 Evas_Object* webview, const char* result, void* data)
343 std::string resultStr(result ? result : "null");
344 LogD("result: %s", resultStr.c_str());
347 void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
350 // execute injection for creating js objects
351 std::ifstream jsFile(injectionFile);
352 std::string script((std::istreambuf_iterator<char>(jsFile)),
353 std::istreambuf_iterator<char>());
355 LogD("injected js code: %s", script.c_str());
356 ewk_view_script_execute(webview, script.c_str(), executeScriptCallback, this);
359 void AppBoxRenderView::finishLoadCallback(Evas_Object* webview)
362 ewk_view_visibility_set(webview, EINA_TRUE);
365 // start render timer
368 if (!(m_pdHelper->isPdOpened()) &&
369 webview == m_pdHelper->getBaseWebView())
372 ecore_idler_add(openPdIdlerCallback, this);
377 void AppBoxRenderView::createWindowBeforeCallback(Evas** canvas, Evas_Object* parent)
382 if (!(m_pdHelper->isPdOpened()) &&
383 parent == m_pdHelper->getBaseWebView())
385 LogD("pd canvas is used");
386 *canvas = m_pdHelper->getPdCanvas();
391 LogD("canvas of this webview is used");
392 *canvas = evas_object_evas_get(parent);
395 void AppBoxRenderView::createWindowAfterCallback(Evas_Object* parent, Evas_Object* child)
399 // To support transparent background
400 evas_object_color_set(child, 0, 0, 0, 0);
403 Evas* parentCanvas = evas_object_evas_get(parent);
404 Evas* childCanvas = evas_object_evas_get(child);
406 if (parentCanvas != childCanvas) {
407 // wrt-core change visibility value to false internally
408 // So plugin should reset this value to true for painting parent webview
409 ewk_view_visibility_set(parent, EINA_TRUE);
410 evas_object_show(parent);
411 m_pdHelper->finishOpen(child);
415 ewk_view_visibility_set(child, EINA_TRUE);
416 evas_object_show(child);
419 void AppBoxRenderView::setBufferCallback(Evas_Object* webview)
422 evas_object_show(webview);
423 evas_object_focus_set(webview, EINA_TRUE);
426 void AppBoxRenderView::unsetBufferCallback(Evas_Object* webview)
429 evas_object_hide(webview);
432 void AppBoxRenderView::decideNavigationCallback(Evas_Object* webview, std::string& uri)
436 // navigation of box scheme should be ignored
437 if(BoxSchemeHandler::Instance()->isBoxScheme(uri)) {
439 BoxSchemeHandler::Instance()->process(m_instanceId, uri);