2 * Copyright (c) 2013 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 AppBoxRenderView.cpp
18 * @author Yunchan Cho (yunchan.cho@samsung.com)
24 #include <livebox-service.h>
25 #include <i_runnable_widget_object.h>
26 #include <core_module.h>
27 #include <dpl/fast_delegate.h>
28 #include <Core/View/IRenderView.h>
29 #include <Core/View/IPdHelper.h>
30 #include <Core/View/PdHelper.h>
31 #include <Core/Util/Log.h>
32 #include "AppBoxObserver.h"
33 #include "AppBoxRenderBuffer.h"
34 #include "AppBoxRenderView.h"
36 #define RENDER_MAX_TIME 10.0
38 AppBoxRenderView::AppBoxRenderView(
39 std::string boxId, std::string instanceId,
40 Evas_Object* boxWin, EwkContextPtr ewkContext)
43 , m_instanceId(instanceId)
52 , m_ewkContext(ewkContext)
55 m_appId = getAppId(m_boxId);
56 if (m_appId.empty()) {
57 throw; //exception throw!
60 evas_object_show(m_boxWin);
61 m_renderBuffer = AppBoxObserver::Instance()->getRenderBuffer(m_instanceId);
62 AppBoxObserver::Instance()->registerRenderView(m_instanceId, this);
65 AppBoxRenderView::~AppBoxRenderView()
68 evas_object_hide(m_boxWin);
69 AppBoxObserver::Instance()->unregisterRenderView(m_instanceId);
72 void AppBoxRenderView::showBox(RenderInfoPtr renderInfo)
76 // delete already running timer
80 if (livebox_service_mouse_event(m_boxId.c_str())) {
81 m_renderBuffer->deleteTouchTimer();
85 m_startUrl = getStartUrl(URL_TYPE_BOX, renderInfo->defaultUrlParams);
88 LogD("can't create view instance");
92 // in case of showing box by request of pd open
94 m_pdHelper->setBaseWebView(m_baseWebView);
97 // resize webview fitted to width, height of Box
104 m_renderBuffer->startCanvasUpdate();
106 m_renderInfo = renderInfo;
109 bool AppBoxRenderView::createView()
116 m_baseWebView = NULL;
119 m_view = WRT::CoreModuleSingleton::
120 Instance().getRunnableWidgetObject(m_appId);
123 if (m_startUrl.empty()) {
124 LogD("no start url");
127 m_view->PrepareView(m_startUrl, m_boxWin, m_ewkContext.get());
128 m_view->CheckBeforeLaunch();
130 // set callback functions of RunnableWidgetObject
131 WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
132 cbs->loadStart = DPL::MakeDelegate(this, &AppBoxRenderView::startLoadCallback);
133 cbs->loadFinish = DPL::MakeDelegate(this, &AppBoxRenderView::finishLoadCallback);
134 cbs->bufferSet = DPL::MakeDelegate(this, &AppBoxRenderView::setBufferCallback);
135 cbs->bufferUnset = DPL::MakeDelegate(this, &AppBoxRenderView::unsetBufferCallback);
136 cbs->windowCreateBefore = DPL::MakeDelegate(this, &AppBoxRenderView::createWindowBeforeCallback);
137 cbs->windowCreateAfter = DPL::MakeDelegate(this, &AppBoxRenderView::createWindowAfterCallback);
138 m_view->SetUserDelegates(cbs);
141 m_baseWebView = m_view->GetCurrentWebview();
143 // To support transparent background
144 evas_object_color_set(m_baseWebView, 0, 0, 0, 0);
145 evas_object_layer_set(m_baseWebView, EVAS_LAYER_MAX);
149 bool AppBoxRenderView::destroyView()
153 m_renderBuffer->stopCanvasUpdate();
154 ecore_idler_add(destroyViewIdlerCallback, this);
158 void AppBoxRenderView::hideBox()
164 void AppBoxRenderView::pauseBox()
169 void AppBoxRenderView::resumeBox()
174 void AppBoxRenderView::showPd(Evas_Object* pdWin, RenderInfoPtr renderInfo)
179 std::string pdStartUrl = getStartUrl(URL_TYPE_PD, renderInfo->defaultUrlParams);
180 m_pdHelper = PdHelper::create(pdWin, pdStartUrl, renderInfo);
183 evas_object_show(pdWin);
184 showBox(m_renderInfo);
187 void AppBoxRenderView::hidePd()
194 // destory box webview to stop rendering
195 evas_object_show(getCurrentSnapShot());
199 std::string AppBoxRenderView::getAppId(std::string& boxId)
201 // TODO more exact and safe parsing is needed
202 std::string temp = std::string(boxId);
203 int found = temp.find_last_of(".");
204 if (found == std::string::npos) {
205 return std::string();
208 temp.assign(temp, 0, found);
212 std::string AppBoxRenderView::getStartUrl(UrlType type, std::string& defaultParams)
217 url = livebox_service_lb_script_path(m_boxId.c_str());
220 url = livebox_service_pd_script_path(m_boxId.c_str());
223 LogD("no available type");
226 // add default parameters to start url
227 url += defaultParams;
232 Evas_Object* AppBoxRenderView::getCurrentSnapShot()
236 m_snapshot = m_renderBuffer->getSnapshot();
237 //evas_object_layer_set(m_snapshot, EVAS_LAYER_MAX);
242 void AppBoxRenderView::clearSnapShot()
246 evas_object_layer_set(m_snapshot, EVAS_LAYER_MIN);
247 //evas_object_hide(m_snapshot);
248 evas_object_del(m_snapshot);
253 void AppBoxRenderView::addRenderTimer()
256 if (m_fireRenderTimer) {
260 m_fireRenderTimer = ecore_timer_add(
262 fireRenderTimerCallback,
266 void AppBoxRenderView::deleteRenderTimer()
269 if (m_fireRenderTimer) {
270 ecore_timer_del(m_fireRenderTimer);
271 m_fireRenderTimer = NULL;
275 Eina_Bool AppBoxRenderView::fireRenderTimerCallback(void* data)
279 AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
280 This->m_fireRenderTimer = NULL;
282 This->m_renderBuffer->stopCanvasUpdate();
283 if (livebox_service_mouse_event(This->m_boxId.c_str())) {
285 This->m_renderBuffer->deleteTouchTimer();
286 This->m_view->Suspend();
288 // Before webview should be removed,
289 // new evas object with last render data should be created
290 // otherwise, after webview is removed, box is white screen.
291 evas_object_show(This->getCurrentSnapShot());
292 ecore_idler_add(destroyViewIdlerCallback, This);
295 return ECORE_CALLBACK_CANCEL;
298 Eina_Bool AppBoxRenderView::destroyViewIdlerCallback(void* data)
302 AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
304 This->m_view->Hide();
305 This->m_view.reset();
306 This->m_baseWebView = NULL;
309 return ECORE_CALLBACK_CANCEL;
312 Eina_Bool AppBoxRenderView::openPdIdlerCallback(void* data)
315 AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
316 if (This && This->m_pdHelper) {
317 This->m_pdHelper->startOpen();
319 return ECORE_CALLBACK_CANCEL;
323 void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
328 void AppBoxRenderView::finishLoadCallback(Evas_Object* webview)
331 ewk_view_visibility_set(webview, EINA_TRUE);
334 // start render timer
337 if (!(m_pdHelper->isPdOpened()) &&
338 webview == m_pdHelper->getBaseWebView())
341 ecore_idler_add(openPdIdlerCallback, this);
346 void AppBoxRenderView::createWindowBeforeCallback(Evas** canvas, Evas_Object* parent)
351 if (!(m_pdHelper->isPdOpened()) &&
352 parent == m_pdHelper->getBaseWebView())
354 LogD("pd canvas is used");
355 *canvas = m_pdHelper->getPdCanvas();
360 LogD("canvas of this webview is used");
361 *canvas = evas_object_evas_get(parent);
364 void AppBoxRenderView::createWindowAfterCallback(Evas_Object* parent, Evas_Object* child)
368 // To support transparent background
369 evas_object_color_set(child, 0, 0, 0, 0);
372 Evas* parentCanvas = evas_object_evas_get(parent);
373 Evas* childCanvas = evas_object_evas_get(child);
375 if (parentCanvas != childCanvas) {
376 evas_object_show(parent);
377 m_pdHelper->finishOpen(child);
381 evas_object_show(child);
384 void AppBoxRenderView::setBufferCallback(Evas_Object* webview)
387 evas_object_show(webview);
388 evas_object_focus_set(webview, EINA_TRUE);
391 void AppBoxRenderView::unsetBufferCallback(Evas_Object* webview)
394 evas_object_hide(webview);