Title: [208882] trunk
Revision
208882
Author
[email protected]
Date
2016-11-17 23:50:57 -0800 (Thu, 17 Nov 2016)

Log Message

Downloads started by context menu actions should also have a web view associated
https://bugs.webkit.org/show_bug.cgi?id=164364

Reviewed by Michael Catanzaro.

Source/WebKit2:

When a request is converted to a download WebPageProxy calls handleDownloadRequest() and clients handle that to
associate the web view to the download. When a download is started by a context menu action, WebPageProxy calls
WebProcessPool::download() with this as initiatingPage parameter, but clients are not notified in this case.

* UIProcess/API/gtk/WebKitDownload.cpp:
(webkitDownloadCreateForRequest): Deleted.
* UIProcess/API/gtk/WebKitDownloadPrivate.h:
* UIProcess/API/gtk/WebKitWebContext.cpp:
(webkitWebContextStartDownload): Use webkitWebContextGetOrCreateDownload() after WebProcessPool::download()
because the WebKitDownload could have already been created by the web view download handler at this point.
* UIProcess/API/gtk/WebKitWebView.cpp:
(webkit_web_view_download_uri): We no longer need to associate the web view to the download here.
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::download): If an initiatingPage has been passed, call handleDownloadRequest() to notify
the page client.

Tools:

Add a GTK+ unit tests to check that downloads started by the context menu have a web view associated.

* TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp:
(downloadLocalFileSuccessfully):
(testDownloadOverwriteDestinationDisallowed):
(testDownloadLocalFileError):
(testDownloadRemoteFile):
(testDownloadRemoteFileError):
(testDownloadMIMEType):
(contextMenuCallback):
(testContextMenuDownloadActions):
(beforeAll):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (208881 => 208882)


--- trunk/Source/WebKit2/ChangeLog	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Source/WebKit2/ChangeLog	2016-11-18 07:50:57 UTC (rev 208882)
@@ -1,3 +1,26 @@
+2016-11-17  Carlos Garcia Campos  <[email protected]>
+
+        Downloads started by context menu actions should also have a web view associated
+        https://bugs.webkit.org/show_bug.cgi?id=164364
+
+        Reviewed by Michael Catanzaro.
+
+        When a request is converted to a download WebPageProxy calls handleDownloadRequest() and clients handle that to
+        associate the web view to the download. When a download is started by a context menu action, WebPageProxy calls
+        WebProcessPool::download() with this as initiatingPage parameter, but clients are not notified in this case.
+
+        * UIProcess/API/gtk/WebKitDownload.cpp:
+        (webkitDownloadCreateForRequest): Deleted.
+        * UIProcess/API/gtk/WebKitDownloadPrivate.h:
+        * UIProcess/API/gtk/WebKitWebContext.cpp:
+        (webkitWebContextStartDownload): Use webkitWebContextGetOrCreateDownload() after WebProcessPool::download()
+        because the WebKitDownload could have already been created by the web view download handler at this point.
+        * UIProcess/API/gtk/WebKitWebView.cpp:
+        (webkit_web_view_download_uri): We no longer need to associate the web view to the download here.
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::download): If an initiatingPage has been passed, call handleDownloadRequest() to notify
+        the page client.
+
 2016-11-17  Alex Christensen  <[email protected]>
 
         REGRESSION: API test _WKDownload.ConvertResponseToDownload is a flaky timeout

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp (208881 => 208882)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp	2016-11-18 07:50:57 UTC (rev 208882)
@@ -322,13 +322,6 @@
     return download;
 }
 
-WebKitDownload* webkitDownloadCreateForRequest(DownloadProxy* downloadProxy, const ResourceRequest& request)
-{
-    WebKitDownload* download = webkitDownloadCreate(downloadProxy);
-    download->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request));
-    return download;
-}
-
 void webkitDownloadSetResponse(WebKitDownload* download, WebKitURIResponse* response)
 {
     download->priv->response = response;

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h (208881 => 208882)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h	2016-11-18 07:50:57 UTC (rev 208882)
@@ -27,7 +27,6 @@
 #include <wtf/text/CString.h>
 
 WebKitDownload* webkitDownloadCreate(WebKit::DownloadProxy*);
-WebKitDownload* webkitDownloadCreateForRequest(WebKit::DownloadProxy*, const WebCore::ResourceRequest&);
 bool webkitDownloadIsCancelled(WebKitDownload*);
 void webkitDownloadSetResponse(WebKitDownload*, WebKitURIResponse*);
 void webkitDownloadSetWebView(WebKitDownload*, WebKitWebView*);

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp (208881 => 208882)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp	2016-11-18 07:50:57 UTC (rev 208882)
@@ -579,10 +579,11 @@
  */
 WebKitDownload* webkit_web_context_download_uri(WebKitWebContext* context, const gchar* uri)
 {
-    g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0);
-    g_return_val_if_fail(uri, 0);
+    g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr);
+    g_return_val_if_fail(uri, nullptr);
 
-    return webkitWebContextStartDownload(context, uri, 0);
+    GRefPtr<WebKitDownload> download = webkitWebContextStartDownload(context, uri, nullptr);
+    return download.leakRef();
 }
 
 /**
@@ -1237,10 +1238,7 @@
 WebKitDownload* webkitWebContextStartDownload(WebKitWebContext* context, const char* uri, WebPageProxy* initiatingPage)
 {
     WebCore::ResourceRequest request(String::fromUTF8(uri));
-    DownloadProxy* downloadProxy = context->priv->processPool->download(initiatingPage, request);
-    WebKitDownload* download = webkitDownloadCreateForRequest(downloadProxy, request);
-    downloadsMap().set(downloadProxy, download);
-    return download;
+    return webkitWebContextGetOrCreateDownload(context->priv->processPool->download(initiatingPage, request));
 }
 
 void webkitWebContextRemoveDownload(DownloadProxy* downloadProxy)

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (208881 => 208882)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2016-11-18 07:50:57 UTC (rev 208882)
@@ -3351,13 +3351,11 @@
  */
 WebKitDownload* webkit_web_view_download_uri(WebKitWebView* webView, const char* uri)
 {
-    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
-    g_return_val_if_fail(uri, 0);
+    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
+    g_return_val_if_fail(uri, nullptr);
 
-    WebKitDownload* download = webkitWebContextStartDownload(webView->priv->context.get(), uri, getPage(webView));
-    webkitDownloadSetWebView(download, webView);
-
-    return download;
+    GRefPtr<WebKitDownload> download = webkitWebContextStartDownload(webView->priv->context.get(), uri, getPage(webView));
+    return download.leakRef();
 }
 
 /**

Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp (208881 => 208882)


--- trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp	2016-11-18 07:50:57 UTC (rev 208882)
@@ -812,6 +812,9 @@
     DownloadProxy* downloadProxy = createDownloadProxy(request);
     SessionID sessionID = initiatingPage ? initiatingPage->sessionID() : SessionID::defaultSessionID();
 
+    if (initiatingPage)
+        initiatingPage->handleDownloadRequest(downloadProxy);
+
     if (networkProcess()) {
         ResourceRequest updatedRequest(request);
         // Request's firstPartyForCookies will be used as Original URL of the download request.

Modified: trunk/Tools/ChangeLog (208881 => 208882)


--- trunk/Tools/ChangeLog	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Tools/ChangeLog	2016-11-18 07:50:57 UTC (rev 208882)
@@ -1,3 +1,23 @@
+2016-11-17  Carlos Garcia Campos  <[email protected]>
+
+        Downloads started by context menu actions should also have a web view associated
+        https://bugs.webkit.org/show_bug.cgi?id=164364
+
+        Reviewed by Michael Catanzaro.
+
+        Add a GTK+ unit tests to check that downloads started by the context menu have a web view associated.
+
+        * TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp:
+        (downloadLocalFileSuccessfully):
+        (testDownloadOverwriteDestinationDisallowed):
+        (testDownloadLocalFileError):
+        (testDownloadRemoteFile):
+        (testDownloadRemoteFileError):
+        (testDownloadMIMEType):
+        (contextMenuCallback):
+        (testContextMenuDownloadActions):
+        (beforeAll):
+
 2016-11-17  Ryosuke Niwa  <[email protected]>
 
         Add an experimental API to find elements across shadow boundaries

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp (208881 => 208882)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp	2016-11-18 07:25:42 UTC (rev 208881)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp	2016-11-18 07:50:57 UTC (rev 208882)
@@ -159,16 +159,16 @@
         webkit_download_set_destination(download, destinationURI.get());
     }
 
-    WebKitDownload* downloadURIAndWaitUntilFinishes(const CString& requestURI)
+    GRefPtr<WebKitDownload> downloadURIAndWaitUntilFinishes(const CString& requestURI)
     {
-        WebKitDownload* download = webkit_web_context_download_uri(m_webContext.get(), requestURI.data());
-        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download));
+        GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_context_download_uri(m_webContext.get(), requestURI.data()));
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));
 
-        g_assert(!webkit_download_get_allow_overwrite(download));
-        webkit_download_set_allow_overwrite(download, m_allowOverwrite);
-        g_assert(webkit_download_get_allow_overwrite(download) == m_allowOverwrite);
+        g_assert(!webkit_download_get_allow_overwrite(download.get()));
+        webkit_download_set_allow_overwrite(download.get(), m_allowOverwrite);
+        g_assert(webkit_download_get_allow_overwrite(download.get()) == m_allowOverwrite);
 
-        WebKitURIRequest* request = webkit_download_get_request(download);
+        WebKitURIRequest* request = webkit_download_get_request(download.get());
         g_assert(request);
         ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, requestURI);
 
@@ -200,7 +200,7 @@
     GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get()));
     GRefPtr<GFileInfo> sourceInfo = adoptGRef(g_file_query_info(source.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0));
     GUniquePtr<char> sourceURI(g_file_get_uri(source.get()));
-    GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(sourceURI.get()));
+    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinishes(sourceURI.get());
     g_assert(!webkit_download_get_web_view(download.get()));
 
     Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
@@ -321,7 +321,7 @@
     GUniquePtr<char> sourcePath(g_build_filename(Test::getResourcesDir().data(), filename, nullptr));
     GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get()));
     GUniquePtr<char> sourceURI(g_file_get_uri(source.get()));
-    GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(sourceURI.get()));
+    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinishes(sourceURI.get());
     g_assert(!webkit_download_get_web_view(download.get()));
 
     Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
@@ -338,7 +338,7 @@
 static void testDownloadLocalFileError(DownloadErrorTest* test, gconstpointer)
 {
     test->m_expectedError = DownloadErrorTest::NetworkError;
-    GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes("file:///foo/bar"));
+    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinishes("file:///foo/bar");
     g_assert(!webkit_download_get_web_view(download.get()));
 
     Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
@@ -353,7 +353,7 @@
     GUniquePtr<char> path(g_build_filename(Test::getResourcesDir().data(), "test.pdf", nullptr));
     GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.get()));
     GUniquePtr<char> uri(g_file_get_uri(file.get()));
-    download = adoptGRef(test->downloadURIAndWaitUntilFinishes(uri.get()));
+    download = test->downloadURIAndWaitUntilFinishes(uri.get());
     g_assert(!webkit_download_get_web_view(download.get()));
 
     g_assert_cmpint(events.size(), ==, 4);
@@ -366,7 +366,7 @@
     test->checkDestinationAndDeleteFile(download.get(), "bar");
 
     test->m_expectedError = DownloadErrorTest::DownloadCancelled;
-    download = adoptGRef(test->downloadURIAndWaitUntilFinishes(uri.get()));
+    download = test->downloadURIAndWaitUntilFinishes(uri.get());
     g_assert(!webkit_download_get_web_view(download.get()));
 
     g_assert_cmpint(events.size(), ==, 4);
@@ -439,7 +439,7 @@
 
 static void testDownloadRemoteFile(DownloadTest* test, gconstpointer)
 {
-    GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/test.pdf")));
+    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/test.pdf"));
     g_assert(!webkit_download_get_web_view(download.get()));
 
     Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
@@ -463,7 +463,7 @@
 static void testDownloadRemoteFileError(DownloadErrorTest* test, gconstpointer)
 {
     test->m_expectedError = DownloadErrorTest::NetworkError;
-    GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/foo")));
+    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/foo"));
     g_assert(!webkit_download_get_web_view(download.get()));
 
     Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
@@ -478,7 +478,7 @@
     g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);
 
     test->m_expectedError = DownloadErrorTest::InvalidDestination;
-    download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/test.pdf")));
+    download = test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/test.pdf"));
     g_assert(!webkit_download_get_web_view(download.get()));
 
     g_assert_cmpint(events.size(), ==, 4);
@@ -491,7 +491,7 @@
     test->checkDestinationAndDeleteFile(download.get(), "bar");
 
     test->m_expectedError = DownloadErrorTest::DownloadCancelled;
-    download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/cancel-after-destination")));
+    download = test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/cancel-after-destination"));
     g_assert(!webkit_download_get_web_view(download.get()));
 
     g_assert_cmpint(events.size(), ==, 4);
@@ -564,6 +564,7 @@
 static void testWebViewDownloadURI(WebViewDownloadTest* test, gconstpointer)
 {
     GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_view_download_uri(test->m_webView, kServer->getURIForPath("/test.pdf").data()));
+    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));
     test->waitUntilDownloadStarted();
     g_assert(test->m_webView == webkit_download_get_web_view(download.get()));
     test->waitUntilDownloadFinished();
@@ -643,7 +644,7 @@
 
 static void testDownloadMIMEType(DownloadTest* test, gconstpointer)
 {
-    GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/unknown")));
+    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/unknown"));
     g_assert(!webkit_download_get_web_view(download.get()));
 
     Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
@@ -668,6 +669,62 @@
     test->checkDestinationAndDeleteFile(download.get(), kServerSuggestedFilename);
 }
 
+static gboolean contextMenuCallback(WebKitWebView* webView, WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult* hitTestResult, WebViewDownloadTest* test)
+{
+    g_assert(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult));
+    g_assert(webkit_hit_test_result_context_is_link(hitTestResult));
+    GList* items = webkit_context_menu_get_items(contextMenu);
+    GRefPtr<WebKitContextMenuItem> contextMenuItem;
+    for (GList* l = items; l; l = g_list_next(l)) {
+        g_assert(WEBKIT_IS_CONTEXT_MENU_ITEM(l->data));
+        auto* item = WEBKIT_CONTEXT_MENU_ITEM(l->data);
+        if (webkit_context_menu_item_get_stock_action(item) == WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_LINK_TO_DISK) {
+            contextMenuItem = item;
+            break;
+        }
+    }
+    g_assert(contextMenuItem.get());
+    webkit_context_menu_remove_all(contextMenu);
+    webkit_context_menu_append(contextMenu, contextMenuItem.get());
+    test->quitMainLoop();
+    return FALSE;
+}
+
+static void testContextMenuDownloadActions(WebViewDownloadTest* test, gconstpointer)
+{
+    test->showInWindowAndWaitUntilMapped();
+
+    static const char* linkHTMLFormat = "<html><body><a style='position:absolute; left:1; top:1' href=''>Download Me</a></body></html>";
+    GUniquePtr<char> linkHTML(g_strdup_printf(linkHTMLFormat, kServer->getURIForPath("/test.pdf").data()));
+    test->loadHtml(linkHTML.get(), kServer->getURIForPath("/").data());
+    test->waitUntilLoadFinished();
+
+    g_signal_connect(test->m_webView, "context-menu", G_CALLBACK(contextMenuCallback), test);
+    g_idle_add([](gpointer userData) -> gboolean {
+        auto* test = static_cast<WebViewDownloadTest*>(userData);
+        test->clickMouseButton(1, 1, 3);
+        return FALSE;
+    }, test);
+    g_main_loop_run(test->m_mainLoop);
+
+    g_idle_add([](gpointer userData) -> gboolean {
+        auto* test = static_cast<WebViewDownloadTest*>(userData);
+        // Select and activate the context menu action.
+        test->keyStroke(GDK_KEY_Down);
+        test->keyStroke(GDK_KEY_Return);
+        return FALSE;
+    }, test);
+    test->waitUntilDownloadStarted();
+
+    g_assert(test->m_webView == webkit_download_get_web_view(test->m_download.get()));
+    test->waitUntilDownloadFinished();
+
+    GRefPtr<GFile> downloadFile = adoptGRef(g_file_new_for_uri(webkit_download_get_destination(test->m_download.get())));
+    GRefPtr<GFileInfo> downloadFileInfo = adoptGRef(g_file_query_info(downloadFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), nullptr, nullptr));
+    g_assert_cmpint(g_file_info_get_size(downloadFileInfo.get()), >, 0);
+    g_file_delete(downloadFile.get(), nullptr, nullptr);
+}
+
 void beforeAll()
 {
     kServer = new WebKitTestServer();
@@ -683,6 +740,7 @@
     PolicyResponseDownloadTest::add("Downloads", "policy-decision-download", testPolicyResponseDownload);
     PolicyResponseDownloadTest::add("Downloads", "policy-decision-download-cancel", testPolicyResponseDownloadCancel);
     DownloadTest::add("Downloads", "mime-type", testDownloadMIMEType);
+    WebViewDownloadTest::add("Downloads", "contex-menu-download-actions", testContextMenuDownloadActions);
 }
 
 void afterAll()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to