[Release] livebox.web-provider-1.46
[platform/framework/web/web-provider.git] / src / Plugin / AppBoxPlugin / AppBoxRenderView.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 3602bb1..ce0fbac
 #include <Eina.h>
 #include <Evas.h>
 #include <Ecore.h>
+#include <EWebKit2.h>
 #include <ewk_view.h>
 #include <ewk_context.h>
+#include <ewk_settings.h>
 #include <livebox-service.h>
 #include <i_runnable_widget_object.h>
 #include <core_module.h>
 #include "AppBoxPdHelper.h"
 #include "AppBoxRenderView.h"
 
-#define RENDER_MAX_TIME 10.0
+#define RENDER_MAX_TIME 30.0
 
 // injection javascript file regarding creating js object used by box and pd
 static const std::string injectionFile("/usr/share/web-provider/injection.js");
 
 AppBoxRenderView::AppBoxRenderView(
         std::string boxId, std::string instanceId,
-        Evas_Object* boxWin, EwkContextPtr ewkContext)
+        EwkContextPtr ewkContext)
     : m_appId()
     , m_boxId(boxId)
     , m_instanceId(instanceId)
-    , m_boxWin(boxWin)
-    , m_snapshot()
-    , m_renderInfo()
+    , m_ewkContext(ewkContext)
+    , m_boxRenderInfo()
     , m_boxWrt()
     , m_pdWrt()
+    , m_snapshot()
     , m_fireRenderTimer()
     , m_pdHelper()
     , m_pdFastOpen(false)
-    , m_ewkContext(ewkContext)
-    , m_renderBuffer()
+    , m_boxRenderBuffer()
+    , m_boxWrt_isSuspended(false)
 {
     LogD("enter");
     m_appId = getAppId(m_boxId);
@@ -68,39 +70,45 @@ AppBoxRenderView::AppBoxRenderView(
         throw; //exception throw!
     }
 
-    evas_object_show(m_boxWin);
-    m_renderBuffer = AppBoxObserver::Instance()->getRenderBuffer(m_instanceId);
-    m_pdFastOpen = web_provider_livebox_get_pd_fast_open(m_boxId.c_str()) ? true : false;
+    m_boxRenderBuffer = AppBoxObserver::Instance()->getRenderBuffer(m_instanceId);
+
+    // use fastopen to default
+    // m_pdFastOpen = web_provider_livebox_get_pd_fast_open(m_boxId.c_str()) ? true : false;
+    m_pdFastOpen = false;
     AppBoxObserver::Instance()->registerRenderView(m_instanceId, this);
 }
 
 AppBoxRenderView::~AppBoxRenderView()
 {
     LogD("enter");
-    evas_object_hide(m_boxWin);
     AppBoxObserver::Instance()->unregisterRenderView(m_instanceId);
 }
 
-void AppBoxRenderView::showBox(RenderInfoPtr renderInfo)
+void AppBoxRenderView::showBox(RenderInfoPtr boxRenderInfo)
 {
     LogD("enter");
 
+    // stop updating render buffer
+    m_boxRenderBuffer->stopCanvasUpdate();
+    clearSnapShot();
+
     // delete already running timer
     deleteRenderTimer();
 
     // stop touch timer
     if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
-        m_renderBuffer->deleteTouchTimer();
+        m_boxRenderBuffer->deleteTouchTimer();
     }
 
     // copy to url
-    std::string boxStartUrl = getStartUrl(URL_TYPE_BOX, renderInfo->defaultUrlParams);
+    std::string boxStartUrl = getStartUrl(URL_TYPE_BOX, boxRenderInfo->defaultUrlParams);
     if (m_boxWrt) {
         LogD("existing wrt core is removed");
-        destroyWrtCore(m_boxWrt);
+        destroyBoxWrtCore();
     }
 
-    m_boxWrt = createWrtCore(boxStartUrl, m_boxWin, m_ewkContext); 
+    m_boxWrt = createWrtCore(boxStartUrl, boxRenderInfo->window, m_ewkContext);
+    m_boxWrt_isSuspended = false;
 
     // in case of showing box by request of pd open
     if (m_pdHelper) {
@@ -110,11 +118,13 @@ void AppBoxRenderView::showBox(RenderInfoPtr renderInfo)
     // resize webview fitted to width, height of Box
     evas_object_resize(
             m_boxWrt->GetCurrentWebview(), 
-            renderInfo->width,
-            renderInfo->height);
+            boxRenderInfo->width,
+            boxRenderInfo->height);
+
 
+    evas_object_show(boxRenderInfo->window);
     m_boxWrt->Show();
-    m_renderInfo = renderInfo;
+    m_boxRenderInfo = boxRenderInfo;
 }
 
 AppBoxRenderView::WrtCorePtr AppBoxRenderView::createWrtCore(
@@ -153,12 +163,11 @@ AppBoxRenderView::WrtCorePtr AppBoxRenderView::createWrtCore(
 
     cbs->navigationDecide =
         DPL::MakeDelegate(this, &AppBoxRenderView::decideNavigationCallback);
+    cbs->webCrash = DPL::MakeDelegate(this, &AppBoxRenderView::crashWebProcessCallback);
     wrt->SetUserDelegates(cbs);
 
-    // To support transparent background
-    evas_object_color_set(wrt->GetCurrentWebview(), 0, 0, 0, 0);
-    evas_object_layer_set(wrt->GetCurrentWebview(), EVAS_LAYER_MAX);
-
+    // set basic webview setting
+    setWebViewBasicSetting(wrt->GetCurrentWebview());
     return wrt;
 }
 
@@ -166,10 +175,13 @@ void AppBoxRenderView::destroyBoxWrtCore()
 {
     LogD("enter");
 
-    m_renderBuffer->stopCanvasUpdate();
+    m_boxRenderBuffer->stopCanvasUpdate();
     deleteRenderTimer();
     destroyWrtCore(m_boxWrt);
     m_boxWrt.reset();
+
+    // temp
+    m_boxWrt_isSuspended = false;
 }
 
 void AppBoxRenderView::destroyPdWrtCore()
@@ -193,6 +205,9 @@ void AppBoxRenderView::hideBox()
 {
     LogD("enter");
     destroyBoxWrtCore();
+    if (m_boxRenderInfo->window) {
+        evas_object_hide(m_boxRenderInfo->window);
+    }
 }
 
 void AppBoxRenderView::pauseBox()
@@ -205,37 +220,37 @@ void AppBoxRenderView::resumeBox()
     LogD("enter");
 }
 
-void AppBoxRenderView::showPd(Evas_Object* pdWin, RenderInfoPtr renderInfo)
+void AppBoxRenderView::showPd(RenderInfoPtr pdRenderInfo, RenderInfoPtr boxRenderInfo)
 {
     LogD("enter");
 
     // create pd helper
-    std::string pdStartUrl = getStartUrl(URL_TYPE_PD, renderInfo->defaultUrlParams);
+    std::string pdStartUrl = getStartUrl(URL_TYPE_PD, pdRenderInfo->defaultUrlParams);
     if (m_pdFastOpen) {
         destroyPdWrtCore();
         // if needed, last param regarding ewk context can be set to new one.
-        m_pdWrt = createWrtCore(pdStartUrl, pdWin, m_ewkContext);
+        m_pdWrt = createWrtCore(pdStartUrl, pdRenderInfo->window, m_ewkContext);
         if (!m_pdWrt) {
             LogD("no wrt core instance");
             return;
         }
-        m_pdHelper = AppBoxPdHelper::create(pdWin);
+        m_pdHelper = AppBoxPdHelper::create(pdRenderInfo->window);
 
         // resize webview fitted to width, height of pd
         evas_object_resize(
                 m_pdWrt->GetCurrentWebview(), 
-                renderInfo->width,
-                renderInfo->height);
+                pdRenderInfo->width,
+                pdRenderInfo->height);
         // show pd
         m_pdWrt->Show();
         m_pdHelper->finishOpen(m_pdWrt->GetCurrentWebview());
     } else {
-        m_pdHelper = PdHelper::create(pdWin, pdStartUrl, renderInfo);
+        m_pdHelper = PdHelper::create(pdRenderInfo, pdStartUrl);
     }
 
     // show pd window
-    evas_object_show(pdWin);
-    showBox(m_renderInfo);
+    evas_object_show(pdRenderInfo->window);
+    showBox(boxRenderInfo);
 }
 
 void AppBoxRenderView::hidePd()
@@ -248,13 +263,19 @@ void AppBoxRenderView::hidePd()
     m_pdHelper->close();
     m_pdHelper.reset();
 
-    // stop box webview after render timer
-    addRenderTimer();
+    // stop box webview
+    stopRenderBox();
 }
 
 Evas_Object* AppBoxRenderView::getBoxWebView()
 {
-    return m_boxWrt->GetCurrentWebview();
+    if (!m_pdHelper) {
+        return m_boxWrt->GetCurrentWebview();
+    } else {
+        // Here, we can't use GetCurrentWebView() of wrt-core to get Box' webview,
+        // because in the non fast-open, GetCurrentWebview() returns PD's webview.
+        return m_pdHelper->getBoxWebView();
+    }
 }
 
 Evas_Object* AppBoxRenderView::getPdWebView()
@@ -303,8 +324,7 @@ Evas_Object* AppBoxRenderView::getCurrentSnapShot()
 {
     LogD("enter");
     clearSnapShot();
-    m_snapshot = m_renderBuffer->getSnapshot();
-    //evas_object_layer_set(m_snapshot, EVAS_LAYER_MAX);
+    m_snapshot = m_boxRenderBuffer->getSnapshot();
 
     return m_snapshot;
 }
@@ -313,8 +333,6 @@ void AppBoxRenderView::clearSnapShot()
 {
     LogD("enter");
     if (m_snapshot) {
-        evas_object_layer_set(m_snapshot, EVAS_LAYER_MIN);
-        //evas_object_hide(m_snapshot);
         evas_object_del(m_snapshot);
         m_snapshot = NULL;
     }
@@ -342,25 +360,61 @@ void AppBoxRenderView::deleteRenderTimer()
     }
 }
 
-Eina_Bool AppBoxRenderView::fireRenderTimerCallback(void* data)
+void AppBoxRenderView::stopRenderBox()
 {
-    LogD("enter");
-
-    AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
-    This->m_fireRenderTimer = NULL;
-
-    This->m_renderBuffer->stopCanvasUpdate();
-    if (web_provider_livebox_get_mouse_event(This->m_boxId.c_str())) {
+    deleteRenderTimer();
+    m_boxRenderBuffer->stopCanvasUpdate();
+    if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
         // stop touch timer
-        This->m_renderBuffer->deleteTouchTimer();
-        This->m_boxWrt->Suspend();
+        m_boxRenderBuffer->deleteTouchTimer();
+
+        // temp condition
+        if (m_boxWrt_isSuspended == false)
+        {
+            m_boxWrt_isSuspended = true;
+            m_boxWrt->Suspend();
+        }
     } else {
         // Before webview should be removed,
         // new evas object with last render data should be created
         // otherwise, after webview is removed, box is white screen.
-        evas_object_show(This->getCurrentSnapShot());
-        This->destroyBoxWrtCore();
+        evas_object_show(getCurrentSnapShot());
+        destroyBoxWrtCore();
+    }
+}
+
+void AppBoxRenderView::setWebViewBasicSetting(Evas_Object* webview)
+{
+    LogD("enter");
+
+    if (!webview) {
+        return;
     }
+    Ewk_Settings* setting = ewk_view_settings_get(webview);
+    // To support transparent background
+    evas_object_color_set(webview, 0, 0, 0, 1);
+    ewk_view_visibility_set(webview, EINA_TRUE);
+
+    // To know starting point for updating buffer
+    evas_object_smart_callback_add(
+            webview,
+            "load,nonemptylayout,finished",
+            loadNonEmptyLayoutFinishedCallback,
+            this);
+    evas_object_smart_callback_add(
+            webview,
+            "frame,rendered",
+            frameRenderedCallback,
+            this);
+}
+
+Eina_Bool AppBoxRenderView::fireRenderTimerCallback(void* data)
+{
+    LogD("enter");
+
+    AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+    This->m_fireRenderTimer = NULL;
+    This->stopRenderBox();
 
     return ECORE_CALLBACK_CANCEL;
 }
@@ -379,6 +433,7 @@ void AppBoxRenderView::executeScriptCallback(
         Evas_Object* webview, const char* result, void* data)
 {
     LogD("enter");
+
     std::string resultStr(result ? result : "null");
     LogD("result: %s", resultStr.c_str());
 }
@@ -386,7 +441,9 @@ void AppBoxRenderView::executeScriptCallback(
 void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
 {
     LogD("enter");
-    m_renderBuffer->startCanvasUpdate();
+    if(!webview) {
+        return;
+    }
     // execute injection for creating js objects
     std::ifstream jsFile(injectionFile);
     std::string script((std::istreambuf_iterator<char>(jsFile)),
@@ -399,6 +456,10 @@ void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
 void AppBoxRenderView::finishLoadCallback(Evas_Object* webview)
 {
     LogD("enter");
+    if (!webview) {
+        return;
+    }
+
     ewk_view_visibility_set(webview, EINA_TRUE);
 
     if (!m_pdHelper) {
@@ -437,9 +498,9 @@ void AppBoxRenderView::createWindowBeforeCallback(Evas** canvas, Evas_Object* pa
 void AppBoxRenderView::createWindowAfterCallback(Evas_Object* parent, Evas_Object* child)
 {
     LogD("enter");
-
-    // To support transparent background
-    evas_object_color_set(child, 0, 0, 0, 0);
+    if (!parent) {
+        return;
+    }
 
     if (m_pdHelper) {
         Evas* parentCanvas = evas_object_evas_get(parent);
@@ -454,7 +515,7 @@ void AppBoxRenderView::createWindowAfterCallback(Evas_Object* parent, Evas_Objec
         }
     }
 
-    ewk_view_visibility_set(child, EINA_TRUE);
+    setWebViewBasicSetting(child);
     evas_object_show(child);
 }
 
@@ -481,3 +542,26 @@ void AppBoxRenderView::decideNavigationCallback(Evas_Object* webview, std::strin
         BoxSchemeHandler::Instance()->process(m_instanceId, uri);
     }
 }
+
+void AppBoxRenderView::crashWebProcessCallback()
+{
+    LogD("enter");
+    ewk_shutdown();
+    elm_exit();
+}
+
+void AppBoxRenderView::loadNonEmptyLayoutFinishedCallback(
+        void* data, Evas_Object* webview, void* eventInfo)
+{
+    LogD("enter");
+}
+
+void AppBoxRenderView::frameRenderedCallback(
+        void* data, Evas_Object* webview, void* eventInfo)
+{
+    LogD("enter");
+
+    // start to update render buffer!
+    AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+    This->m_boxRenderBuffer->startCanvasUpdate();
+}