Clean-up Multiprocess service support
[platform/framework/web/web-provider.git] / src / Plugin / AppBoxPlugin / AppBoxRenderView.cpp
old mode 100644 (file)
new mode 100755 (executable)
index cced9c5..f609963
 #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
+#define SNAPSHOT_REMOVE_TIME 1.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_boxWrt_isSuspended(false)
     , m_pdWrt()
+    , m_snapshot()
     , m_fireRenderTimer()
+    , m_removeSnapShotTimer()
     , m_pdHelper()
+    , m_boxRenderBuffer()
     , m_pdFastOpen(false)
-    , m_ewkContext(ewkContext)
-    , m_renderBuffer()
+    , m_boxFinishLoad(false)
+    , m_boxWrt_isSuspended(false)
 {
     LogD("enter");
     m_appId = getAppId(m_boxId);
@@ -69,45 +73,53 @@ 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 = true;
     AppBoxObserver::Instance()->registerRenderView(m_instanceId, this);
 }
 
 AppBoxRenderView::~AppBoxRenderView()
 {
     LogD("enter");
-    if (m_boxWin) {
-        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_renderBuffer->stopCanvasUpdate();
-    clearSnapShot();
+    m_boxRenderBuffer->stopCanvasUpdate();
+
+    // clear snapshot if this is not the case of pd open
+    if (!m_pdHelper) {
+        clearSnapShot();
+    }
 
     // delete already running timer
-    deleteRenderTimer();
+    deleteTimer(&m_fireRenderTimer);
 
-    // stop touch timer
+    // delete touch timer
     if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
-        m_renderBuffer->deleteTouchTimer();
+        m_boxRenderBuffer->deleteTouchTimer();
     }
 
+    // set boxFinishLoad to false
+    m_boxFinishLoad = false;
+
     // 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");
         destroyBoxWrtCore();
     }
 
-    m_boxWrt = createWrtCore(boxStartUrl, m_boxWin, m_ewkContext); 
+    m_boxWrt = createWrtCore(
+                URL_TYPE_BOX, boxStartUrl, 
+                boxRenderInfo->window, m_ewkContext);
     m_boxWrt_isSuspended = false;
 
     // in case of showing box by request of pd open
@@ -118,26 +130,24 @@ 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(
-        std::string& startUrl, Evas_Object* win, EwkContextPtr ewkContext)
+        UrlType type, std::string& startUrl, 
+        Evas_Object* win, EwkContextPtr ewkContext)
 {
     LogD("enter");
     
     WrtCorePtr wrt;
-#ifdef MULTIPROCESS_SERVICE_SUPPORT
-    wrt = WRT::CoreModuleSingleton::
-                Instance().getRunnableWidgetObject(m_appId, DPL::Optional<unsigned>());
-#else
     wrt = WRT::CoreModuleSingleton::
                 Instance().getRunnableWidgetObject(m_appId);
-#endif
     // prepare webview
     if (startUrl.empty()) {
         LogD("no start url");
@@ -149,7 +159,12 @@ AppBoxRenderView::WrtCorePtr AppBoxRenderView::createWrtCore(
     // set callback functions of RunnableWidgetObject
     WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
     cbs->loadStart = DPL::MakeDelegate(this, &AppBoxRenderView::startLoadCallback);
-    cbs->loadFinish = DPL::MakeDelegate(this, &AppBoxRenderView::finishLoadCallback);
+    if (type == URL_TYPE_BOX) {
+        cbs->loadFinish = DPL::MakeDelegate(this, &AppBoxRenderView::finishBoxLoadCallback);
+    } else {
+        cbs->loadFinish = DPL::MakeDelegate(this, &AppBoxRenderView::finishPdLoadCallback);
+    }
+
     cbs->bufferSet = DPL::MakeDelegate(this, &AppBoxRenderView::setBufferCallback);
     cbs->bufferUnset = DPL::MakeDelegate(this, &AppBoxRenderView::unsetBufferCallback);
     if (!m_pdFastOpen) {
@@ -164,18 +179,8 @@ AppBoxRenderView::WrtCorePtr AppBoxRenderView::createWrtCore(
     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);
-
-    // To know starting point for updating buffer
-    evas_object_smart_callback_add(
-            wrt->GetCurrentWebview(),
-            "load,nonemptylayout,finished",
-            //"frame,rendered", 
-            loadNonEmptyLayoutFinishedCallback,
-            this);
-
+    // set basic webview setting
+    setWebViewBasicSetting(wrt->GetCurrentWebview());
     return wrt;
 }
 
@@ -183,10 +188,12 @@ void AppBoxRenderView::destroyBoxWrtCore()
 {
     LogD("enter");
 
-    m_renderBuffer->stopCanvasUpdate();
-    deleteRenderTimer();
+    m_boxRenderBuffer->stopCanvasUpdate();
+    deleteTimer(&m_fireRenderTimer);
+    deleteTimer(&m_removeSnapShotTimer);
     destroyWrtCore(m_boxWrt);
     m_boxWrt.reset();
+
     // temp
     m_boxWrt_isSuspended = false;
 }
@@ -212,6 +219,9 @@ void AppBoxRenderView::hideBox()
 {
     LogD("enter");
     destroyBoxWrtCore();
+    if (m_boxRenderInfo->window) {
+        evas_object_hide(m_boxRenderInfo->window);
+    }
 }
 
 void AppBoxRenderView::pauseBox()
@@ -224,37 +234,43 @@ 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);
+        // if you want to launch new Web Process for PD, use the following line.
+        // EwkContextPtr pdContext = AppBoxObserver::Instance()->getPdEwkContext();
+        m_pdWrt = createWrtCore(URL_TYPE_PD, 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);
+
+    // show box
+    showBox(boxRenderInfo);
+
+    // start timer for clearing existing snapshot in case of only pd open
+    addTimer(&m_removeSnapShotTimer, SNAPSHOT_REMOVE_TIME, removeSnapShotTimerCallback);
+
 }
 
 void AppBoxRenderView::hidePd()
@@ -267,8 +283,8 @@ void AppBoxRenderView::hidePd()
     m_pdHelper->close();
     m_pdHelper.reset();
 
-    // stop box webview after render timer
-    addRenderTimer();
+    // stop box webview
+    stopRenderBox();
 }
 
 Evas_Object* AppBoxRenderView::getBoxWebView()
@@ -328,70 +344,129 @@ 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;
 }
 
-void AppBoxRenderView::clearSnapShot() 
+void AppBoxRenderView::clearSnapShot()
 {
     LogD("enter");
     if (m_snapshot) {
-        //evas_object_layer_set(m_snapshot, EVAS_LAYER_MIN);
         evas_object_del(m_snapshot);
         m_snapshot = NULL;
     }
 }
 
-void AppBoxRenderView::addRenderTimer()
+void AppBoxRenderView::showSnapShot()
 {
     LogD("enter");
-    if (m_fireRenderTimer) {
-        deleteRenderTimer();
+    if (m_snapshot) {
+        evas_object_raise(m_snapshot);
+        evas_object_show(m_snapshot);
     }
-
-    m_fireRenderTimer = ecore_timer_add(
-                            RENDER_MAX_TIME, 
-                            fireRenderTimerCallback,
-                            this);
 }
 
-void AppBoxRenderView::deleteRenderTimer()
+void AppBoxRenderView::hideSnapShot()
 {
     LogD("enter");
-    if (m_fireRenderTimer) {
-        ecore_timer_del(m_fireRenderTimer);
-        m_fireRenderTimer = NULL;
+    if (m_snapshot) {
+        evas_object_hide(m_snapshot);
+        evas_object_lower(m_snapshot);
     }
 }
 
-Eina_Bool AppBoxRenderView::fireRenderTimerCallback(void* data)
+void AppBoxRenderView::addTimer(Ecore_Timer** timer, double interval, Ecore_Task_Cb callback)
 {
     LogD("enter");
+    if (*timer) {
+        deleteTimer(timer);
+    }
 
-    AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
-    This->m_fireRenderTimer = NULL;
+    *timer = ecore_timer_add(interval, callback, this);
+}
 
-    This->m_renderBuffer->stopCanvasUpdate();
-    if (web_provider_livebox_get_mouse_event(This->m_boxId.c_str())) {
+void AppBoxRenderView::deleteTimer(Ecore_Timer** timer)
+{
+    LogD("enter");
+    if (*timer) {
+        ecore_timer_del(*timer);
+        *timer = NULL;
+    }
+}
+
+void AppBoxRenderView::stopRenderBox()
+{
+    deleteTimer(&m_fireRenderTimer);
+    m_boxRenderBuffer->stopCanvasUpdate();
+    if (web_provider_livebox_get_mouse_event(m_boxId.c_str())) {
         // stop touch timer
-        This->m_renderBuffer->deleteTouchTimer();
+        m_boxRenderBuffer->deleteTouchTimer();
 
         // temp condition
-        if (This->m_boxWrt_isSuspended == false)
+        if (m_boxWrt_isSuspended == false)
         {
-            This->m_boxWrt_isSuspended = true;
-            This->m_boxWrt->Suspend();
+            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;
+}
+
+Eina_Bool AppBoxRenderView::removeSnapShotTimerCallback(void* data)
+{
+    LogD("enter");
+
+    AppBoxRenderView* This = static_cast<AppBoxRenderView*>(data);
+    if (!(This->m_boxFinishLoad)) {
+        return ECORE_CALLBACK_RENEW;
+    }
+
+    // hide snapshot because valid frame has been prepared generally.
+    This->clearSnapShot();
+
+    This->m_removeSnapShotTimer = NULL;
     return ECORE_CALLBACK_CANCEL;
 }
 
@@ -409,6 +484,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());
 }
@@ -416,6 +492,9 @@ void AppBoxRenderView::executeScriptCallback(
 void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
 {
     LogD("enter");
+    if(!webview) {
+        return;
+    }
     // execute injection for creating js objects
     std::ifstream jsFile(injectionFile);
     std::string script((std::istreambuf_iterator<char>(jsFile)),
@@ -425,14 +504,18 @@ void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
     ewk_view_script_execute(webview, script.c_str(), executeScriptCallback, this);
 }
 
-void AppBoxRenderView::finishLoadCallback(Evas_Object* webview)
+void AppBoxRenderView::finishBoxLoadCallback(Evas_Object* webview)
 {
     LogD("enter");
+    if (!webview) {
+        return;
+    }
+
     ewk_view_visibility_set(webview, EINA_TRUE);
 
     if (!m_pdHelper) {
         // start render timer
-        addRenderTimer();
+        addTimer(&m_fireRenderTimer, RENDER_MAX_TIME, fireRenderTimerCallback);
     } else {
         if (!m_pdFastOpen) {
             if (!(m_pdHelper->isPdOpened()) && 
@@ -443,6 +526,19 @@ void AppBoxRenderView::finishLoadCallback(Evas_Object* webview)
             }
         }
     }
+
+    // set flag
+    m_boxFinishLoad = true;
+}
+
+void AppBoxRenderView::finishPdLoadCallback(Evas_Object* webview)
+{
+    LogD("enter");
+    if (!webview) {
+        return;
+    }
+
+    ewk_view_visibility_set(webview, EINA_TRUE);
 }
 
 void AppBoxRenderView::createWindowBeforeCallback(Evas** canvas, Evas_Object* parent)
@@ -466,9 +562,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);
@@ -483,7 +579,7 @@ void AppBoxRenderView::createWindowAfterCallback(Evas_Object* parent, Evas_Objec
         }
     }
 
-    ewk_view_visibility_set(child, EINA_TRUE);
+    setWebViewBasicSetting(child);
     evas_object_show(child);
 }
 
@@ -522,8 +618,14 @@ 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_renderBuffer->startCanvasUpdate();
+    This->m_boxRenderBuffer->startCanvasUpdate();
 }