Add Web API for communication between Box and PD
authorYunchan Cho <yunchan.cho@samsung.com>
Tue, 23 Apr 2013 09:55:24 +0000 (18:55 +0900)
committerYunchan Cho <yunchan.cho@samsung.com>
Fri, 26 Apr 2013 05:26:13 +0000 (14:26 +0900)
[Issue#] N/A
[Problem] There is no Web API for communication between Box and PD
[Cause] N/A
[Solution] Javascript code is added for managing js events regarding appwidget and firing them by native code

Change-Id: Iab51fabfbb6198dd25e188598f1f4c945e7f3a71

16 files changed:
src/Core/BoxSchemeHandler.cpp
src/Core/BoxSchemeHandler.h
src/Core/IBox.h
src/Core/Service/CMakeLists.txt
src/Core/Service/MessageManager.cpp [new file with mode: 0644]
src/Core/Service/MessageManager.h [new file with mode: 0644]
src/Core/View/CMakeLists.txt
src/Core/View/IPdHelper.h
src/Core/View/IRenderView.h
src/Core/View/InjectedScript.h [deleted file]
src/Core/View/PdHelper.cpp
src/Core/View/PdHelper.h
src/Core/View/WebView.cpp
src/Core/View/injection.js [new file with mode: 0644]
src/Plugin/AppBoxPlugin/AppBoxRenderView.cpp
src/Plugin/AppBoxPlugin/AppBoxRenderView.h

index 126ea4c..df44a17 100755 (executable)
 #include "Service/AppControl.h"
 #include "Service/PeriodChanger.h"
 #include "Service/ScrollHolder.h"
+#include "Service/MessageManager.h"
 #include "Util/Log.h"
 #include "BoxSchemeHandler.h"
 
+using namespace Service;
+
 static const std::string BOX_SCHEME("box://");
 static const std::string BOX_SCHEME_RELOAD("box://reload");
 static const std::string BOX_SCHEME_CHANGE_PERIOD("box://change-period");
 static const std::string BOX_SCHEME_LAUNCH_BROWSER("box://launch-browser");
 static const std::string BOX_SCHEME_SCROLL_START("box://scroll-start");
 static const std::string BOX_SCHEME_SCROLL_STOP("box://scroll-stop");
+static const std::string BOX_SCHEME_SEND_MESSAGE_TO_PD("box://send-message-to-pd");
+static const std::string BOX_SCHEME_SEND_MESSAGE_TO_BOX("box://send-message-to-box");
 
 static const std::string HTTP_SCHEME("http://");
 static const std::string HTTPS_SCHEME("https://");
@@ -122,6 +127,25 @@ bool BoxSchemeHandler::process(std::string& instanceId, std::string& uri)
        return handleScroll(instanceId, false);
     }
 
+    if (!uri.compare(
+                0,
+                BOX_SCHEME_SEND_MESSAGE_TO_BOX.size(),
+                BOX_SCHEME_SEND_MESSAGE_TO_BOX))
+    {
+        std::string key("message");
+        std::string message = parse(uri, key);
+        return handleSendMessage(instanceId, MessageManager::TO_BOX, message);
+    }
+
+    if (!uri.compare(
+                0,
+                BOX_SCHEME_SEND_MESSAGE_TO_PD.size(),
+                BOX_SCHEME_SEND_MESSAGE_TO_PD))
+    {
+        std::string key("message");
+        std::string message = parse(uri, key);
+        return handleSendMessage(instanceId, MessageManager::TO_PD, message);
+    }
     LogD("unknown box scheme protocol");
     return false;
 }
@@ -198,8 +222,8 @@ bool BoxSchemeHandler::handleChangePeriod(std::string& instanceId, float request
 bool BoxSchemeHandler::handleLaunchBrowser(std::string& instanceId, std::string& url)
 {
     LogD("enter");
-    if(!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
-       !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
+    if (!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
+        !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
     {
         return Service::AppControl::launchBrowser(url);
     }
@@ -207,6 +231,35 @@ bool BoxSchemeHandler::handleLaunchBrowser(std::string& instanceId, std::string&
     return false;
 }
 
+bool BoxSchemeHandler::handleSendMessage(
+        std::string& instanceId, 
+        MessageManager::ReceiverType receiver, 
+        std::string& message)
+{
+    LogD("enter");
+    Box* box = getBox(instanceId);
+    if (!box) {
+        LogD("no box for update period");
+        return false;
+    };
+
+    // set webview of receiver
+    Evas_Object* webview;
+    switch (receiver) {
+    case MessageManager::TO_BOX:
+        webview = box->m_view->getBoxWebView();
+        break;
+    case MessageManager::TO_PD:
+        webview = box->m_view->getPdWebView();
+        break;
+    default:
+        LogD("not supported receiver");
+        return false;
+    }
+
+    return m_messageManager->send(webview, receiver, message); 
+}
+
 std::string BoxSchemeHandler::parse(std::string& uri, std::string& key)
 {
     LogD("enter");
index d17c641..d5b4507 100644 (file)
 
 #include <string>
 #include <map>
+#include "Service/PeriodChanger.h"
+#include "Service/MessageManager.h"
 
-class Box;
+using namespace Service;
 
-namespace Service {
-class PeriodChanger;
-}
+class Box;
 
 #define EXPORT_CLASS __attribute__ ((visibility("default"))
 
@@ -45,6 +45,10 @@ class EXPORT_CLASS BoxSchemeHandler {
         bool handleChangePeriod(std::string& instanceId, float requestedPeriod = -1.0f);
         bool handleLaunchBrowser(std::string& instanceId, std::string& url);
         bool handleScroll(std::string& instanceId, bool start);
+        bool handleSendMessage(
+                std::string& instanceId, 
+                MessageManager::ReceiverType receiver, 
+                std::string& message);
         std::string parse(std::string& uri, std::string& key);
 
         BoxSchemeHandler();
@@ -55,7 +59,8 @@ class EXPORT_CLASS BoxSchemeHandler {
         typedef std::pair<std::string, Box*> BoxMapPair;
         BoxMap m_boxMap;
         // members for service
-        std::shared_ptr<Service::PeriodChanger> m_periodChanger;
+        std::shared_ptr<PeriodChanger> m_periodChanger;
+        std::shared_ptr<MessageManager> m_messageManager;
         static BoxSchemeHandler* s_instance;
 };
 
index 63acccf..115d244 100644 (file)
 #ifndef I_BOX_H
 #define I_BOX_H
 
+#include <ewk_view.h>
 #include <ewk_context.h>
 
 class IBox {
     public:
+        // functions for lifecycle
         virtual bool show() = 0;
         virtual bool hide() = 0;
         virtual bool resize(int width, int height) = 0;
@@ -32,6 +34,8 @@ class IBox {
         virtual bool openPd(int width, int height, double x, double y) = 0;
         virtual bool closePd() = 0;
         virtual bool update() = 0;
+
+        // functions for specific service
         virtual bool changePeriod(float period) = 0;
 
         //virtual IBox& operator=(const IBox& rhs) = 0;
index 76e84bb..9b13e20 100644 (file)
@@ -33,6 +33,7 @@ SET(SRCS
     ${CMAKE_CURRENT_SOURCE_DIR}/AppControl.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/PeriodChanger.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/ScrollHolder.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/MessageManager.cpp
 )
 
 SET(HEADERS
diff --git a/src/Core/Service/MessageManager.cpp b/src/Core/Service/MessageManager.cpp
new file mode 100644 (file)
index 0000000..f8b6488
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Flora License, Version 1.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.tizenopensource.org/license
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file    MessageMenager.h
+ * @author  Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#include <string>
+#include <Evas.h>
+#include <ewk_view.h>
+#include <Core/Util/Log.h>
+#include "MessageManager.h"
+
+namespace Service {
+
+static const std::string jsFireWindowEventFunction("webprovider.fireAppWidgetEvent");
+static const std::string jsPdMessageEvent("pdmessage");
+static const std::string jsBoxMessageEvent("boxmessage");
+
+MessageManager::MessageManager()
+{
+    LogD("enter");
+}
+
+MessageManager::~MessageManager()
+{
+    LogD("enter");
+}
+
+bool MessageManager::send(Evas_Object* webview, ReceiverType receiver, std::string& message)
+{
+    LogD("enter");
+
+    std::string eventName;
+
+    // set message event name triggered by receiver
+    switch (receiver) {
+    case TO_BOX:
+        eventName = jsPdMessageEvent;
+        break;
+    case TO_PD:
+        eventName = jsBoxMessageEvent;
+        break;
+    default:
+        return false;
+    }
+
+    std::string script = jsFireWindowEventFunction;
+    script += "(\"";
+    script += eventName;
+    script += "\", \"";
+    script += message;
+    script +="\");";
+    LogD("calling javascript: %s", script.c_str());
+
+    // execute js code for sending message
+    ewk_view_script_execute(webview, script.c_str(), executeScriptCallback, this);
+
+    return true;
+}
+
+void MessageManager::executeScriptCallback(
+        Evas_Object* webview, const char* result, void* data)
+{
+    LogD("enter");
+    std::string resultStr(result ? result : "null");
+    LogD("result: %s", resultStr.c_str());
+}
+} // Service
diff --git a/src/Core/Service/MessageManager.h b/src/Core/Service/MessageManager.h
new file mode 100644 (file)
index 0000000..7c84771
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Flora License, Version 1.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.tizenopensource.org/license
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file    MessageManager.h
+ * @author  Yunchan Cho (yunchan.cho@samsung.com)
+ */
+
+#ifndef MESSAGE_MANAGER_H
+#define MESSAGE_MANAGER_H
+
+#include <string>
+#include <memory>
+#include <Evas.h>
+
+namespace Service {
+
+class MessageManager;
+typedef std::shared_ptr<MessageManager> MessageManagerPtr;
+
+class MessageManager {
+    public:
+        enum ReceiverType {
+            TO_BOX,
+            TO_PD
+        };
+
+        static MessageManagerPtr create() {
+            return MessageManagerPtr(new MessageManager());
+        }
+        bool send(Evas_Object* webview, ReceiverType receiver, std::string& message);
+        ~MessageManager();
+
+    private:
+        static void executeScriptCallback(
+                Evas_Object* webview, const char* result, void* data);
+        MessageManager();
+};
+} // Service
+
+#endif // MESSAGE_MANAGER_H
index 910fafa..86f517c 100644 (file)
@@ -63,3 +63,4 @@ INSTALL_FILE(IPdHelper.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DI
 INSTALL_FILE(PdHelper.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME}) 
 INSTALL_FILE(IWebView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME}) 
 INSTALL_FILE(WebView.h include/${PROJECT_NAME}/${PARENT_DIR_NAME}/${CURRENT_DIR_NAME}) 
+INSTALL_FILE(injection.js /usr/share/${PROJECT_NAME})
index e16decb..93dced1 100644 (file)
@@ -29,6 +29,7 @@ class IPdHelper {
         virtual void close() = 0;
         virtual void setBaseWebView(Evas_Object*& base) = 0;
         virtual Evas_Object* getBaseWebView() const = 0;
+        virtual Evas_Object* getPdWebView() const = 0;
         virtual Evas* getPdCanvas() const = 0;
         virtual bool isPdOpened() const = 0;
 };
index e7e2457..2d6ca35 100644 (file)
@@ -43,6 +43,8 @@ class IRenderView {
         virtual void resumeBox() = 0;
         virtual void showPd(Evas_Object* pdWin, RenderInfoPtr renderInfo) = 0;
         virtual void hidePd() = 0;
+        virtual Evas_Object* getBoxWebView() = 0;
+        virtual Evas_Object* getPdWebView() = 0;
         virtual ~IRenderView() {};
 };
 typedef std::shared_ptr<IRenderView> IRenderViewPtr;
diff --git a/src/Core/View/InjectedScript.h b/src/Core/View/InjectedScript.h
deleted file mode 100644 (file)
index ad00390..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *    Licensed under the Flora License, Version 1.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://floralicense.org/license/
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-/**
- * @file    InjectedScript.h
- * @author  Yunchan Cho (yunchan.cho@samsung.com)
- */
-
-#define INJECTED_SCRIPT                                                     \
-       "                                                                    \
-       function reload() {                                                  \
-           window.location.href=\"box://reload\";                           \
-       }                                                                    \
-       function changePeriod(period) {                                      \
-           switch (arguments.length) {                                      \
-               case 0:                                                      \
-                    window.location.href=\"box://change-period\";           \
-                    break;                                                  \
-               case 1:                                                      \
-                    window.location.href=\"box://change-period?period=\" + period;                    \
-                    break;                                                  \
-                default:                                                    \
-                    window.location.href=\"box://change-period\";           \
-                    break;                                                  \
-           }                                                                \
-       }                                                                    \
-       function launchBrowser(url) {                                        \
-           window.location.href=\"box://launch-browser?url=\" + url;        \
-       }                                                                    \
-       function scrollStart(){                                              \
-           window.location.href=\"box://scroll-start\";                     \
-       }                                                                    \
-       function scrollStop(){                                               \
-           window.location.href=\"box://scroll-stop\";                      \
-       }                                                                    \
-       window.tizen = new Object();                                         \
-       window.tizen.appwidget = new Object();                               \
-       window.tizen.appwidget.reload = reload;                              \
-       window.tizen.appwidget.changePeriod = changePeriod;                  \
-       window.tizen.appwidget.launchBrowser = launchBrowser;                \
-       window.tizen.appwidget.scrollStart = scrollStart;                    \
-       window.tizen.appwidget.scrollStop = scrollStop;                      \
-       "
index 4c0464d..a73efe3 100644 (file)
@@ -85,6 +85,12 @@ Evas_Object* PdHelper::getBaseWebView() const
     return m_baseWebView;
 }
 
+Evas_Object* PdHelper::getPdWebView() const
+{
+    LogD("enter");
+    return m_pdWebView;
+}
+
 Evas* PdHelper::getPdCanvas() const  
 {
     LogD("enter");
index f0d38e8..f6c4766 100644 (file)
@@ -40,6 +40,7 @@ class EXPORT_CLASS PdHelper: public IPdHelper {
         virtual void close();
         virtual void setBaseWebView(Evas_Object*& parent);
         virtual Evas_Object* getBaseWebView() const;
+        virtual Evas_Object* getPdWebView() const;
         virtual Evas* getPdCanvas() const;
         virtual bool isPdOpened() const;
         virtual ~PdHelper();
index b3e686a..25f3dda 100644 (file)
  * @author  Yunchan Cho (yunchan.cho@samsung.com)
  */
 #include <string>
+#include <fstream>
+#include <streambuf>
 #include <Evas.h>
 #include <Eina.h>
 #include <ewk_context.h>
 #include <ewk_view.h>
 #include <Core/Util/Log.h>
-#include "InjectedScript.h"
 #include "WebView.h"
 
+// injection javascript file regarding creating js object used by box and pd
+static const std::string injectionFile("/usr/share/web-provider/injection.js");
+
 std::map<const std::string, const Evas_Smart_Cb> WebView::m_smartCallbacksMap =
 {
     {"load,started", WebView::loadStartedCallback},
@@ -217,8 +221,13 @@ void WebView::loadStartedCallback(
     LogD("enter");
 
     WebView* This = static_cast<WebView*>(data);
-    const char* injectedScript = INJECTED_SCRIPT;
-    ewk_view_script_execute(obj, injectedScript, executeScriptCallback, This);
+
+    std::ifstream jsFile(injectionFile);
+    std::string script((std::istreambuf_iterator<char>(jsFile)),
+                        std::istreambuf_iterator<char>());
+    LogD("injected js code: %s", script.c_str());
+
+    ewk_view_script_execute(obj, script.c_str(), executeScriptCallback, This);
     This->didLoadStarted(obj);
 }
 
diff --git a/src/Core/View/injection.js b/src/Core/View/injection.js
new file mode 100644 (file)
index 0000000..f2d7b16
--- /dev/null
@@ -0,0 +1,101 @@
+// set javascript objects for Web APIs of Tizen appwidget
+if (typeof window.tizen == 'undefined') {
+    console.log("window.tizen object not exists");
+    window.tizen = new Object();
+}
+
+window.tizen.appwidget = new Object();
+
+// these are functions for overriding standard javascript functions regarding event
+var original_addEventListener = window.addEventListener;
+var original_removeEventListener = window.removeEventListener;
+
+// this variable is responsible to keep information of appwidget evetns
+var appWidgetEvents = {};
+
+// define event structure for appwidget
+window.AppWidgetEventInfo = function(event, callback) {
+    this.event = event;
+    this.callback = callback;
+};
+
+window.addEventListener = function(event, callback, capture) {
+    var e = event.toLowerCase();
+    if (typeof appWidgetEvents[e] != 'undefined') {
+        appWidgetEvents[e].callback = callback;
+    } else {
+        original_addEventListener.call(window, event, callback, capture);
+    }
+};
+
+window.removeEventListener = function(event, callback, capture) {
+    var e = event.toLowerCase();
+    if (typeof appWidgetEvents[e] != "undefined") {
+        appWidgetEvents[e].callback = "null";
+    } else {
+        original_removeEventListener.call(window, event, callback, capture);
+    }
+};
+
+// Define tizen appwidget APIs
+window.tizen.appwidget.reload = function() {
+    window.location.href = "box://reload";
+}
+
+window.tizen.appwidget.changePeriod = function(period) {
+    switch (arguments.length) {
+    case 0:
+        window.location.href = "box://change-period";
+        break;
+    case 1:
+        window.location.href = "box://change-period?period=" + period;
+        break;
+    default:
+        window.location.href = "box://change-period";
+        break;
+    }
+}
+
+window.tizen.appwidget.launchBrowser = function(url) {
+    window.location.href = "box://launch-browser?url=" + url;
+}
+
+window.tizen.appwidget.scrollStart = function() {
+    window.location.href = "box://scroll-start";
+}
+
+window.tizen.appwidget.scrollStop = function() {
+    window.location.href = "box://scroll-stop";
+}
+
+window.tizen.appwidget.sendMessageToBox = function(message) {
+    window.location.href = "box://send-message-to-box?message=" + message;
+}
+
+window.tizen.appwidget.sendMessageToPd = function(message) {
+    window.location.href = "box://send-message-to-pd?message=" + message;
+}
+
+var webprovider = {
+    // define specific function for registering appwidget event
+    registerAppWidgetEvent: function(event) {
+        return (appWidgetEvents[event] = new AppWidgetEventInfo(event, "null"));
+    },
+
+    // define specific function for firing registered appwidget event
+    fireAppWidgetEvent: function(event, data) {
+        // this is called by web-provider, which is native code
+        if (typeof appWidgetEvents[event] != 'undefined') {
+            setTimeout(function() {
+                appWidgetEvents[event].callback(data);
+            }, 0);
+            console.log("fire appwidget event: " + event);
+        } else {
+            console.log("unknown appwidget event: " + event);
+        }
+    },
+}
+
+// register custom events for appwidget
+webprovider.registerAppWidgetEvent("pdmessage");
+webprovider.registerAppWidgetEvent("boxmessage");
index e6a667d..ff88f32 100644 (file)
  * @author  Yunchan Cho (yunchan.cho@samsung.com)
  */
 #include <string>
+#include <fstream>
+#include <streambuf>
 #include <Eina.h>
 #include <Evas.h>
 #include <Ecore.h>
+#include <ewk_view.h>
 #include <livebox-service.h>
 #include <i_runnable_widget_object.h>
 #include <core_module.h>
@@ -36,6 +39,9 @@
 
 #define RENDER_MAX_TIME 10.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)
@@ -205,6 +211,20 @@ void AppBoxRenderView::hidePd()
     addRenderTimer();
 }
 
+Evas_Object* AppBoxRenderView::getBoxWebView()
+{
+    return m_baseWebView;
+}
+
+Evas_Object* AppBoxRenderView::getPdWebView()
+{
+    if (!m_pdHelper) {
+        return NULL;
+    }
+
+    return m_pdHelper->getPdWebView();
+}
+
 std::string AppBoxRenderView::getAppId(std::string& boxId)
 {
     LogD("enter");
@@ -314,10 +334,24 @@ Eina_Bool AppBoxRenderView::openPdIdlerCallback(void* data)
     return ECORE_CALLBACK_CANCEL;
 }
 
+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());
+}
 
 void AppBoxRenderView::startLoadCallback(Evas_Object* webview)
 {
-    // start load
+    LogD("enter");
+    // execute injection for creating js objects
+    std::ifstream jsFile(injectionFile);
+    std::string script((std::istreambuf_iterator<char>(jsFile)),
+                        std::istreambuf_iterator<char>());
+
+    LogD("injected js code: %s", script.c_str());
+    ewk_view_script_execute(webview, script.c_str(), executeScriptCallback, this);
 }
 
 void AppBoxRenderView::finishLoadCallback(Evas_Object* webview)
index b4ec4ad..c5dcd40 100644 (file)
@@ -49,6 +49,8 @@ class AppBoxRenderView: public IRenderView {
         virtual void resumeBox();
         virtual void showPd(Evas_Object* pdWin, RenderInfoPtr renderInfo);
         virtual void hidePd();
+        Evas_Object* getBoxWebView();
+        Evas_Object* getPdWebView();
         virtual ~AppBoxRenderView();
 
     private:
@@ -72,6 +74,10 @@ class AppBoxRenderView: public IRenderView {
         static Eina_Bool fireRenderTimerCallback(void* data);
         static Eina_Bool openPdIdlerCallback(void* data);
 
+        // ewk view callback
+        static void executeScriptCallback(
+                Evas_Object* webview, const char* result, void* data);
+
         // user Callbacks of RunnableWidgetObject
         void startLoadCallback(Evas_Object* webview);
         void finishLoadCallback(Evas_Object* webview);