[WK2][EFL] Add callbacks to the WKViewClient to handle Web Process crash and relaunch
authormikhail.pozdnyakov@intel.com <mikhail.pozdnyakov@intel.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 21:38:38 +0000 (21:38 +0000)
committermikhail.pozdnyakov@intel.com <mikhail.pozdnyakov@intel.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 21:38:38 +0000 (21:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109828

Reviewed by Kenneth Rohde Christiansen.

Source/WebKit2:

Providing WKViewClient with Web Process crash and Web Process relaunch
callbacks brings better design as WebView should not be aware of
EFL-specific code handling the corresponding events.

The implementation of the mentioned Web Process callbacks was also added.

* UIProcess/API/C/efl/WKView.cpp:
(WKViewSetThemePath):
* UIProcess/API/C/efl/WKView.h:
* UIProcess/efl/ViewClientEfl.cpp:
(WebKit::ViewClientEfl::webProcessCrashed):
(WebKit):
(WebKit::ViewClientEfl::webProcessDidRelaunch):
(WebKit::ViewClientEfl::ViewClientEfl):
* UIProcess/efl/ViewClientEfl.h:
(ViewClientEfl):
* UIProcess/efl/WebView.cpp:
(WebKit::WebView::setThemePath):

    Accepts WTF::String instead of WKStringRef as it is
    more appropriate for C++ API implementation class.

(WebKit::WebView::processDidCrash):
(WebKit::WebView::didRelaunchProcess):
* UIProcess/efl/WebView.h:
(WebView):
* UIProcess/efl/WebViewClient.cpp:
(WebKit::WebViewClient::webProcessCrashed):
(WebKit):
(WebKit::WebViewClient::webProcessDidRelaunch):
* UIProcess/efl/WebViewClient.h:

Tools:

Added API test for newly added Web Process crash and Web Process relaunch WKViewClient
callbacks.

* TestWebKitAPI/CMakeLists.txt:

    Tests located in 'TestWebKitAPI/Tests/WebKit2' subdirectories are also
    considered.

* TestWebKitAPI/PlatformEfl.cmake:
* TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp: Added.
(TestWebKitAPI):
(TestWebKitAPI::didFinishLoadForFrame):
(TestWebKitAPI::setPageLoaderClient):
(TestWebKitAPI::webProcessCrashed):
(TestWebKitAPI::webProcessDidRelaunch):
(TestWebKitAPI::setViewClient):
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@144664 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/C/efl/WKView.cpp
Source/WebKit2/UIProcess/API/C/efl/WKView.h
Source/WebKit2/UIProcess/efl/ViewClientEfl.cpp
Source/WebKit2/UIProcess/efl/ViewClientEfl.h
Source/WebKit2/UIProcess/efl/WebView.cpp
Source/WebKit2/UIProcess/efl/WebView.h
Source/WebKit2/UIProcess/efl/WebViewClient.cpp
Source/WebKit2/UIProcess/efl/WebViewClient.h
Tools/ChangeLog
Tools/TestWebKitAPI/CMakeLists.txt
Tools/TestWebKitAPI/PlatformEfl.cmake
Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp [new file with mode: 0644]

index ec2d603..25bc816 100644 (file)
@@ -1,3 +1,42 @@
+2013-03-04  Mikhail Pozdnyakov  <mikhail.pozdnyakov@intel.com>
+
+        [WK2][EFL] Add callbacks to the WKViewClient to handle Web Process crash and relaunch
+        https://bugs.webkit.org/show_bug.cgi?id=109828
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Providing WKViewClient with Web Process crash and Web Process relaunch
+        callbacks brings better design as WebView should not be aware of
+        EFL-specific code handling the corresponding events.
+
+        The implementation of the mentioned Web Process callbacks was also added.
+
+        * UIProcess/API/C/efl/WKView.cpp:
+        (WKViewSetThemePath):
+        * UIProcess/API/C/efl/WKView.h:
+        * UIProcess/efl/ViewClientEfl.cpp:
+        (WebKit::ViewClientEfl::webProcessCrashed):
+        (WebKit):
+        (WebKit::ViewClientEfl::webProcessDidRelaunch):
+        (WebKit::ViewClientEfl::ViewClientEfl):
+        * UIProcess/efl/ViewClientEfl.h:
+        (ViewClientEfl):
+        * UIProcess/efl/WebView.cpp:
+        (WebKit::WebView::setThemePath):
+
+            Accepts WTF::String instead of WKStringRef as it is
+            more appropriate for C++ API implementation class.
+
+        (WebKit::WebView::processDidCrash):
+        (WebKit::WebView::didRelaunchProcess):
+        * UIProcess/efl/WebView.h:
+        (WebView):
+        * UIProcess/efl/WebViewClient.cpp:
+        (WebKit::WebViewClient::webProcessCrashed):
+        (WebKit):
+        (WebKit::WebViewClient::webProcessDidRelaunch):
+        * UIProcess/efl/WebViewClient.h:
+
 2013-03-04  Anders Carlsson  <andersca@apple.com>
 
         Complete the plug-in URL string before sending it to the UI process
index 177911f..a249820 100644 (file)
@@ -106,7 +106,7 @@ bool WKViewGetDrawsTransparentBackground(WKViewRef viewRef)
 
 void WKViewSetThemePath(WKViewRef viewRef, WKStringRef theme)
 {
-    toImpl(viewRef)->setThemePath(theme);
+    toImpl(viewRef)->setThemePath(toImpl(theme)->string());
 }
 
 void WKViewSuspendActiveDOMObjectsAndAnimations(WKViewRef viewRef)
index 7345566..a709b48 100644 (file)
@@ -38,8 +38,10 @@ typedef struct _cairo_surface cairo_surface_t;
 extern "C" {
 #endif
 
+typedef void (*WKViewCallback)(WKViewRef view, const void* clientInfo);
 typedef void (*WKViewViewNeedsDisplayCallback)(WKViewRef view, WKRect area, const void* clientInfo);
 typedef void (*WKViewPageDidChangeContentsSizeCallback)(WKViewRef view, WKSize size, const void* clientInfo);
+typedef void (*WKViewWebProcessCrashedCallback)(WKViewRef view, WKURLRef url, const void* clientInfo);
 
 struct WKViewClient {
     int                                              version;
@@ -48,6 +50,8 @@ struct WKViewClient {
     // Version 0
     WKViewViewNeedsDisplayCallback                   viewNeedsDisplay;
     WKViewPageDidChangeContentsSizeCallback          didChangeContentsSize;
+    WKViewWebProcessCrashedCallback                  webProcessCrashed;
+    WKViewCallback                                   webProcessDidRelaunch;
 };
 typedef struct WKViewClient WKViewClient;
 
index 77f8bf3..55b5aa1 100644 (file)
@@ -27,7 +27,8 @@
 #include "ViewClientEfl.h"
 
 #include "EwkView.h"
-#include "WKView.h"
+#include <WebKit2/WKString.h>
+#include <WebKit2/WKView.h>
 
 using namespace EwkViewCallbacks;
 
@@ -50,6 +51,37 @@ void ViewClientEfl::didChangeContentsSize(WKViewRef, WKSize size, const void* cl
     ewkView->smartCallback<ContentsSizeChanged>().call(size);
 }
 
+void ViewClientEfl::webProcessCrashed(WKViewRef, WKURLRef url, const void* clientInfo)
+{
+    EwkView* ewkView = toEwkView(clientInfo);
+
+    // Check if loading was ongoing, when web process crashed.
+    double loadProgress = WKPageGetEstimatedProgress(ewkView->wkPage());
+    if (loadProgress >= 0 && loadProgress < 1) {
+        loadProgress = 1;
+        ewkView->smartCallback<LoadProgress>().call(&loadProgress);
+    }
+
+    ewkView->smartCallback<TooltipTextUnset>().call();
+
+    bool handled = false;
+    ewkView->smartCallback<WebProcessCrashed>().call(&handled);
+
+    if (!handled) {
+        WKEinaSharedString urlString(url);
+        WARN("WARNING: The web process experienced a crash on '%s'.\n", static_cast<const char*>(urlString));
+
+        // Display an error page
+        ewk_view_html_string_load(ewkView->evasObject(), "The web process has crashed.", 0, urlString);
+    }
+}
+
+void ViewClientEfl::webProcessDidRelaunch(WKViewRef viewRef, const void* clientInfo)
+{
+    if (const char* themePath = toEwkView(clientInfo)->themePath())
+        WKViewSetThemePath(viewRef, adoptWK(WKStringCreateWithUTF8CString(themePath)).get());
+}
+
 ViewClientEfl::ViewClientEfl(EwkView* view)
     : m_view(view)
 {
@@ -61,6 +93,8 @@ ViewClientEfl::ViewClientEfl(EwkView* view)
     viewClient.clientInfo = this;
     viewClient.didChangeContentsSize = didChangeContentsSize;
     viewClient.viewNeedsDisplay = viewNeedsDisplay;
+    viewClient.webProcessCrashed = webProcessCrashed;
+    viewClient.webProcessDidRelaunch = webProcessDidRelaunch;
 
     WKViewSetViewClient(m_view->wkView(), &viewClient);
 }
index 2ebd3a2..6baaf09 100644 (file)
@@ -49,6 +49,8 @@ private:
     static EwkView* toEwkView(const void* clientInfo);
     static void viewNeedsDisplay(WKViewRef, WKRect area, const void* clientInfo);
     static void didChangeContentsSize(WKViewRef, WKSize, const void* clientInfo);
+    static void webProcessCrashed(WKViewRef, WKURLRef, const void* clientInfo);
+    static void webProcessDidRelaunch(WKViewRef, const void* clientInfo);
 
     EwkView* m_view;
 };
index 5846e21..2973198 100644 (file)
@@ -128,9 +128,9 @@ Evas_Object* WebView::evasObject()
     return m_ewkView->evasObject();
 }
 
-void WebView::setThemePath(WKStringRef theme)
+void WebView::setThemePath(const String& theme)
 {
-    m_page->setThemePath(toWTFString(theme).utf8().data());
+    m_page->setThemePath(theme);
 }
 
 void WebView::setDrawsBackground(bool drawsBackground)
@@ -297,32 +297,12 @@ bool WebView::isViewInWindow()
 
 void WebView::processDidCrash()
 {
-    // Check if loading was ongoing, when web process crashed.
-    double loadProgress = ewk_view_load_progress_get(m_ewkView->evasObject());
-    if (loadProgress >= 0 && loadProgress < 1) {
-        loadProgress = 1;
-        m_ewkView->smartCallback<LoadProgress>().call(&loadProgress);
-    }
-
-    m_ewkView->smartCallback<TooltipTextUnset>().call();
-
-    bool handled = false;
-    m_ewkView->smartCallback<WebProcessCrashed>().call(&handled);
-
-    if (!handled) {
-        CString url = m_page->urlAtProcessExit().utf8();
-        WARN("WARNING: The web process experienced a crash on '%s'.\n", url.data());
-
-        // Display an error page
-        ewk_view_html_string_load(m_ewkView->evasObject(), "The web process has crashed.", 0, url.data());
-    }
+    m_client.webProcessCrashed(this, m_page->urlAtProcessExit());
 }
 
 void WebView::didRelaunchProcess()
 {
-    const char* themePath = m_ewkView->themePath();
-    if (themePath)
-        m_page->setThemePath(themePath);
+    m_client.webProcessDidRelaunch(this);
 }
 
 void WebView::pageClosed()
index 42c8d13..9f5f6f4 100644 (file)
@@ -68,7 +68,7 @@ public:
     void setDrawsTransparentBackground(bool);
     bool drawsTransparentBackground() const;
 
-    void setThemePath(WKStringRef);
+    void setThemePath(const String&);
 
     void suspendActiveDOMObjectsAndAnimations();
     void resumeActiveDOMObjectsAndAnimations();
index 05fc80c..ffca093 100644 (file)
@@ -27,6 +27,7 @@
 #include "WebViewClient.h"
 
 #include "WKAPICast.h"
+#include "WKRetainPtr.h"
 
 using namespace WebCore;
 
@@ -48,4 +49,20 @@ void WebViewClient::didChangeContentsSize(WebView* view, const IntSize& size)
     m_client.didChangeContentsSize(toAPI(view), toAPI(size), m_client.clientInfo);
 }
 
+void WebViewClient::webProcessCrashed(WebView* view, const String& url)
+{
+    if (!m_client.webProcessCrashed)
+        return;
+
+    m_client.webProcessCrashed(toAPI(view), adoptWK(toCopiedURLAPI(url)).get(), m_client.clientInfo);
+}
+
+void WebViewClient::webProcessDidRelaunch(WebView* view)
+{
+    if (!m_client.webProcessDidRelaunch)
+        return;
+
+    m_client.webProcessDidRelaunch(toAPI(view), m_client.clientInfo);
+}
+
 } // namespace WebKit
index d5e82dd..10cf92d 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "APIClient.h"
 #include "WKView.h"
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 class IntRect;
@@ -42,6 +43,8 @@ class WebViewClient: public APIClient<WKViewClient, kWKViewClientCurrentVersion>
 public:
     void viewNeedsDisplay(WebView*, const WebCore::IntRect&);
     void didChangeContentsSize(WebView*, const WebCore::IntSize&);
+    void webProcessCrashed(WebView*, const String& url);
+    void webProcessDidRelaunch(WebView*);
 };
 
 } // namespace WebKit
index b0758d3..04db34f 100644 (file)
@@ -1,3 +1,28 @@
+2013-03-04  Mikhail Pozdnyakov  <mikhail.pozdnyakov@intel.com>
+
+        [WK2][EFL] Add callbacks to the WKViewClient to handle Web Process crash and relaunch
+        https://bugs.webkit.org/show_bug.cgi?id=109828
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Added API test for newly added Web Process crash and Web Process relaunch WKViewClient
+        callbacks.
+
+        * TestWebKitAPI/CMakeLists.txt:
+
+            Tests located in 'TestWebKitAPI/Tests/WebKit2' subdirectories are also
+            considered.
+
+        * TestWebKitAPI/PlatformEfl.cmake:
+        * TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp: Added.
+        (TestWebKitAPI):
+        (TestWebKitAPI::didFinishLoadForFrame):
+        (TestWebKitAPI::setPageLoaderClient):
+        (TestWebKitAPI::webProcessCrashed):
+        (TestWebKitAPI::webProcessDidRelaunch):
+        (TestWebKitAPI::setViewClient):
+        (TestWebKitAPI::TEST):
+
 2013-03-04  Chris Fleizach  <cfleizach@apple.com>
 
         AX: Upstream iOS Accessibility DumpRenderTree changes
index 71f7a92..a8e9999 100644 (file)
@@ -128,10 +128,11 @@ set(test_webkit2_api_LIBRARIES
 )
 
 foreach (testName ${test_webkit2_api_BINARIES})
-    add_executable(test_webkit2_api_${testName} ${TESTWEBKITAPI_DIR}/Tests/WebKit2/${testName}.cpp)
-    add_test(test_webkit2_api_${testName} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_webkit2_api_${testName})
-    set_tests_properties(test_webkit2_api_${testName} PROPERTIES TIMEOUT 60)
-    target_link_libraries(test_webkit2_api_${testName} ${test_webkit2_api_LIBRARIES})
+    get_filename_component(testBaseName ${testName} NAME)
+    add_executable(test_webkit2_api_${testBaseName} ${TESTWEBKITAPI_DIR}/Tests/WebKit2/${testName}.cpp)
+    add_test(test_webkit2_api_${testBaseName} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_webkit2_api_${testBaseName})
+    set_tests_properties(test_webkit2_api_${testBaseName} PROPERTIES TIMEOUT 60)
+    target_link_libraries(test_webkit2_api_${testBaseName} ${test_webkit2_api_LIBRARIES})
 endforeach ()
 
 # We don't run tests that are expected to fail. We could use the WILL_FAIL
index 3bcb89b..1d34ad0 100644 (file)
@@ -86,6 +86,7 @@ set(test_webkit2_api_BINARIES
     WKStringJSString
     WKURL
     WillSendSubmitEvent
+    efl/WKViewClientWebProcessCallbacks
 )
 
 set(test_webkit2_api_fail_BINARIES
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp
new file mode 100644 (file)
index 0000000..9c2dfa9
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PlatformUtilities.h"
+#include "PlatformWebView.h"
+#include "Test.h"
+#include "WKView.h"
+#include <WebKit2/WKRetainPtr.h>
+
+namespace TestWebKitAPI {
+
+struct TestStatesData {
+    TestStatesData(WKViewRef view, WKURLRef url)
+        : view(view)
+        , url(url)
+        , didFinishLoad(false)
+        , didCrash(false)
+        , didRelaunch(false)
+    {
+    }
+
+    WKViewRef view;
+    WKURLRef url;
+    bool didFinishLoad;
+    bool didCrash;
+    bool didRelaunch;
+};
+
+static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void* clientInfo)
+{
+    TestStatesData* states = const_cast<TestStatesData*>(static_cast<const TestStatesData*>(clientInfo));
+    states->didFinishLoad = true;
+}
+
+static void setPageLoaderClient(WKPageRef page, const void* clientInfo)
+{
+    WKPageLoaderClient loaderClient;
+    memset(&loaderClient, 0, sizeof(loaderClient));
+
+    loaderClient.didFinishLoadForFrame = didFinishLoadForFrame;
+    loaderClient.clientInfo = clientInfo;
+
+    WKPageSetPageLoaderClient(page, &loaderClient);
+}
+
+void webProcessCrashed(WKViewRef view, WKURLRef url, const void* clientInfo)
+{
+    TestStatesData* states = const_cast<TestStatesData*>(static_cast<const TestStatesData*>(clientInfo));
+
+    EXPECT_EQ(states->view, view);
+    EXPECT_TRUE(WKURLIsEqual(url, states->url));
+
+    states->didCrash = true;
+}
+
+void webProcessDidRelaunch(WKViewRef view, const void* clientInfo)
+{
+    TestStatesData* states = const_cast<TestStatesData*>(static_cast<const TestStatesData*>(clientInfo));
+
+    EXPECT_EQ(states->view, view);
+
+    states->didRelaunch = true;
+}
+
+static void setViewClient(WKViewRef view, const void* clientInfo)
+{
+    WKViewClient viewClient;
+    memset(&viewClient, 0, sizeof(WKViewClient));
+
+    viewClient.version = kWKViewClientCurrentVersion;
+    viewClient.clientInfo = clientInfo;
+    viewClient.webProcessCrashed = webProcessCrashed;
+    viewClient.webProcessDidRelaunch = webProcessDidRelaunch;
+
+    WKViewSetViewClient(view, &viewClient);
+}
+
+TEST(WebKit2, WKViewClientWebProcessCallbacks)
+{
+    WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate());
+    WKRetainPtr<WKURLRef> url = Util::createURLForResource("simple", "html");
+
+    PlatformWebView view(context.get());
+
+    TestStatesData states = TestStatesData(view.platformView(), url.get());
+
+    setPageLoaderClient(view.page(), &states);
+    setViewClient(view.platformView(), &states);
+
+    WKPageLoadURL(view.page(), url.get());
+    Util::run(&states.didFinishLoad);
+
+    WKPageTerminate(view.page());
+    Util::run(&states.didCrash);
+
+    WKPageReload(view.page());
+    Util::run(&states.didRelaunch);
+}
+
+} // namespace TestWebKitAPI