[iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Mar 2014 19:44:35 +0000 (19:44 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Mar 2014 19:44:35 +0000 (19:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=129322

Reviewed by Anders Carlsson.

Source/WebCore:

* platform/network/ResourceHandle.h:
* platform/network/cf/ResourceHandleCFNet.cpp:
(WebCore::ResourceHandle::releaseConnectionForDownload): Changed to
return a RetainPtr that adopts the connection's retain count.

Source/WebKit/mac:

* WebCoreSupport/WebFrameLoaderClient.mm:
(WebFrameLoaderClient::convertMainResourceLoadToDownload): Use the
RetainPtr returned by releaseConnectionForDownload() rather than
manually releasing.

Source/WebKit2:

Based on an original patch by Yongjun Zhang  <yongjun_zhang@apple.com>.

* Shared/Cocoa/APIObject.mm:
(API::Object::newObject):
* Shared/Downloads/ios/DownloadIOS.mm:
(WebKit::dispatchOnMainThread):
(WebKit::toDownload):
(WebKit::setUpDownloadClient):
(WebKit::Download::startWithHandle):
* UIProcess/API/APIDownloadClient.h:
(API::DownloadClient::~DownloadClient):
* UIProcess/API/C/WKContext.cpp:
(WKContextSetDownloadClient):
* UIProcess/API/Cocoa/WKProcessPool.mm:
(-[WKProcessPool _downloadDelegate]):
(-[WKProcessPool _setDownloadDelegate:]):
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/API/Cocoa/_WKDownload.h: Added.
* UIProcess/API/Cocoa/_WKDownload.mm: Added.
(WebKit::wrapper):
(WebKit::createAPIDownloadClient):
(-[_WKDownload dealloc]):
(-[_WKDownload API::]):
* UIProcess/API/Cocoa/_WKDownloadDelegate.h: Added.
* UIProcess/API/Cocoa/_WKDownloadInternal.h: Added.
* UIProcess/Cocoa/DownloadClient.h: Added.
* UIProcess/Cocoa/DownloadClient.mm: Added.
* WebKit2.xcodeproj/project.pbxproj:

Tools:

Add an API test suite for _WKDownload.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm: Added.
(-[DownloadDelegate initWithSourceURL:]):
(-[DownloadDelegate sourceURL]):
(-[DownloadDelegate _downloadDidStart:]):
(-[DownloadDelegate _download:didReceiveResponse:]):
(-[DownloadDelegate _download:didReceiveData:]):
(-[DownloadDelegate _download:decideDestinationWithSuggestedFilename:allowOverwrite:]):
(-[DownloadDelegate _downloadDidFinish:]):
(TEST):
(runTestWithNavigationDelegate):
(-[DownloadNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[ConvertResponseToDownloadNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):

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

22 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/network/ResourceHandle.h
Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/Cocoa/APIObject.mm
Source/WebKit2/Shared/Downloads/ios/DownloadIOS.mm
Source/WebKit2/UIProcess/API/APIDownloadClient.h
Source/WebKit2/UIProcess/API/C/WKContext.cpp
Source/WebKit2/UIProcess/API/Cocoa/WKProcessPool.mm
Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.mm [new file with mode: 0644]
Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadDelegate.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadInternal.h [new file with mode: 0644]
Source/WebKit2/UIProcess/Cocoa/DownloadClient.h [new file with mode: 0644]
Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm [new file with mode: 0644]
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm [new file with mode: 0644]

index 7ed3b35..c7d1fb8 100644 (file)
@@ -1,3 +1,15 @@
+2014-03-24  Andy Estes  <aestes@apple.com>
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        * platform/network/ResourceHandle.h:
+        * platform/network/cf/ResourceHandleCFNet.cpp:
+        (WebCore::ResourceHandle::releaseConnectionForDownload): Changed to
+        return a RetainPtr that adopts the connection's retain count.
+
 2014-03-24  Enrica Casucci  <enrica@apple.com>
 
         Update Hindi fallback font.
index 50f8b8c..4a5ddaf 100644 (file)
@@ -138,7 +138,7 @@ public:
 #if USE(CFNETWORK)
     CFURLStorageSessionRef storageSession() const;
     CFURLConnectionRef connection() const;
-    CFURLConnectionRef releaseConnectionForDownload();
+    RetainPtr<CFURLConnectionRef> releaseConnectionForDownload();
     const ResourceRequest& currentRequest() const;
     static void setHostAllowsAnyHTTPSCertificate(const String&);
     static void setClientCertificate(const String& host, CFDataRef);
index 0c305c0..5cb589d 100644 (file)
@@ -460,10 +460,10 @@ CFURLConnectionRef ResourceHandle::connection() const
     return d->m_connection.get();
 }
 
-CFURLConnectionRef ResourceHandle::releaseConnectionForDownload()
+RetainPtr<CFURLConnectionRef> ResourceHandle::releaseConnectionForDownload()
 {
     LOG(Network, "CFNet - Job %p releasing connection %p for download", this, d->m_connection.get());
-    return d->m_connection.leakRef();
+    return std::move(d->m_connection);
 }
 
 CFStringRef ResourceHandle::synchronousLoadRunLoopMode()
index 0f1c4c3..db9b721 100644 (file)
@@ -1,3 +1,15 @@
+2014-03-24  Andy Estes  <aestes@apple.com>
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::convertMainResourceLoadToDownload): Use the
+        RetainPtr returned by releaseConnectionForDownload() rather than
+        manually releasing.
+
 2014-03-24  Jon Lee  <jonlee@apple.com>
 
         Build fixes.
index 1231550..5192640 100644 (file)
@@ -330,22 +330,10 @@ void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader* doc
 
 #if USE(CFNETWORK)
     ASSERT([WebDownload respondsToSelector:@selector(_downloadWithLoadingCFURLConnection:request:response:delegate:proxy:)]);
-    CFURLConnectionRef connection = handle->connection();
-    [WebDownload _downloadWithLoadingCFURLConnection:connection
-                                                                     request:request.cfURLRequest(UpdateHTTPBody)
-                                                                    response:response.cfURLResponse()
-                                                                    delegate:[webView downloadDelegate]
-                                                                       proxy:nil];
-
-    // Release the connection since the NSURLDownload (actually CFURLDownload) will retain the connection and use it.
-    handle->releaseConnectionForDownload();
-    CFRelease(connection);
+    auto connection = handle->releaseConnectionForDownload();
+    [WebDownload _downloadWithLoadingCFURLConnection:connection.get() request:request.cfURLRequest(UpdateHTTPBody) response:response.cfURLResponse() delegate:[webView downloadDelegate] proxy:nil];
 #else
-    [WebDownload _downloadWithLoadingConnection:handle->connection()
-                                                                request:request.nsURLRequest(UpdateHTTPBody)
-                                                               response:response.nsURLResponse()
-                                                               delegate:[webView downloadDelegate]
-                                                                  proxy:nil];
+    [WebDownload _downloadWithLoadingConnection:handle->connection() request:request.nsURLRequest(UpdateHTTPBody) response:response.nsURLResponse() delegate:[webView downloadDelegate] proxy:nil];
 #endif
 }
 
index a4e4f42..137d617 100644 (file)
@@ -1,3 +1,39 @@
+2014-03-24  Andy Estes  <aestes@apple.com>
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        Based on an original patch by Yongjun Zhang  <yongjun_zhang@apple.com>.
+
+        * Shared/Cocoa/APIObject.mm:
+        (API::Object::newObject):
+        * Shared/Downloads/ios/DownloadIOS.mm:
+        (WebKit::dispatchOnMainThread):
+        (WebKit::toDownload):
+        (WebKit::setUpDownloadClient):
+        (WebKit::Download::startWithHandle):
+        * UIProcess/API/APIDownloadClient.h:
+        (API::DownloadClient::~DownloadClient):
+        * UIProcess/API/C/WKContext.cpp:
+        (WKContextSetDownloadClient):
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (-[WKProcessPool _downloadDelegate]):
+        (-[WKProcessPool _setDownloadDelegate:]):
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/API/Cocoa/_WKDownload.h: Added.
+        * UIProcess/API/Cocoa/_WKDownload.mm: Added.
+        (WebKit::wrapper):
+        (WebKit::createAPIDownloadClient):
+        (-[_WKDownload dealloc]):
+        (-[_WKDownload API::]):
+        * UIProcess/API/Cocoa/_WKDownloadDelegate.h: Added.
+        * UIProcess/API/Cocoa/_WKDownloadInternal.h: Added.
+        * UIProcess/Cocoa/DownloadClient.h: Added.
+        * UIProcess/Cocoa/DownloadClient.mm: Added.
+        * WebKit2.xcodeproj/project.pbxproj:
+
 2014-03-24  Dániel Bátyai  <dbatyai.u-szeged@partner.samsung.com>
 
         [EFL][WK2] Buildfix after r166159.
index 501eb4c..f621350 100644 (file)
@@ -28,6 +28,7 @@
 
 #if WK_API_ENABLED
 
+#import "_WKDownloadInternal.h"
 #import "WKBackForwardListInternal.h"
 #import "WKBackForwardListItemInternal.h"
 #import "WKBrowsingContextControllerInternal.h"
@@ -113,6 +114,10 @@ void* Object::newObject(size_t size, Type type)
         wrapper = [WKNSDictionary alloc];
         break;
 
+    case Type::Download:
+        wrapper = [_WKDownload alloc];
+        break;
+
     case Type::Error:
         wrapper = NSAllocateObject([WKNSError self], size, nullptr);
         break;
index 9bda601..f6625ca 100644 (file)
 
 #if PLATFORM(IOS)
 
+#import "DataReference.h"
+#import <CFNetwork/CFURLDownload.h>
 #import <WebCore/NotImplemented.h>
+#import <WebCore/ResourceError.h>
+#import <WebCore/ResourceHandle.h>
+#import <WebCore/ResourceResponse.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/RunLoop.h>
 
 using namespace WebCore;
 
 namespace WebKit {
-    
+
+// FIXME: If possible, we should consider moving some callbacks off the main thread or at least
+// making them asynchonous calls.
+static void dispatchOnMainThread(void(^block)())
+{
+    if (RunLoop::isMain()) {
+        block();
+        return;
+    }
+
+    dispatch_sync(dispatch_get_main_queue(), block);
+}
+
+static inline Download* toDownload(const void* clientInfo)
+{
+    return static_cast<Download*>(const_cast<void*>(clientInfo));
+}
+
+static void setUpDownloadClient(CFURLDownloadClient& client, Download& download)
+{
+    memset(&client, 0, sizeof(client));
+    client.clientInfo = &download;
+
+    client.didStart = [](CFURLDownloadRef, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)->didStart();
+        });
+    };
+
+    client.willSendRequest = [](CFURLDownloadRef, CFURLRequestRef request, CFURLResponseRef, const void*) -> CFURLRequestRef {
+        return CFRetain(request);
+    };
+
+    client.didReceiveResponse = [](CFURLDownloadRef, CFURLResponseRef response, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)->didReceiveResponse(response);
+        });
+    };
+
+    client.didReceiveData = [](CFURLDownloadRef, CFIndex length, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)->didReceiveData(length);
+        });
+    };
+
+    client.shouldDecodeDataOfMIMEType = [](CFURLDownloadRef, CFStringRef encodingType, const void* clientInfo) -> Boolean {
+        __block BOOL returnValue = NO;
+        dispatchOnMainThread(^{
+            returnValue = toDownload(clientInfo)->shouldDecodeSourceDataOfMIMEType(encodingType);
+        });
+        return returnValue;
+    };
+
+    client.decideDestinationWithSuggestedObjectName = [](CFURLDownloadRef downloadRef, CFStringRef objectName, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            BOOL allowOverwrite;
+            String destination = toDownload(clientInfo)->decideDestinationWithSuggestedFilename(objectName, allowOverwrite);
+            if (!destination.isNull())
+                CFURLDownloadSetDestination(downloadRef, reinterpret_cast<CFURLRef>([NSURL fileURLWithPath:destination]), allowOverwrite);
+        });
+    };
+
+    client.didCreateDestination = [](CFURLDownloadRef, CFURLRef path, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)->didCreateDestination(CFURLGetString(path));
+        });
+    };
+
+    client.didFinish = [](CFURLDownloadRef, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            toDownload(clientInfo)->didFinish();
+        });
+    };
+
+    client.didFail = [](CFURLDownloadRef downloadRef, CFErrorRef error, const void* clientInfo) {
+        dispatchOnMainThread(^{
+            auto resumeData = adoptCF(CFURLDownloadCopyResumeData(downloadRef));
+            toDownload(clientInfo)->didFail(error, IPC::DataReference(CFDataGetBytePtr(resumeData.get()), CFDataGetLength(resumeData.get())));
+        });
+    };
+}
+
 void Download::start()
 {
     notImplemented();
 }
 
-void Download::startWithHandle(ResourceHandle*, const ResourceResponse&)
+void Download::startWithHandle(ResourceHandle* handle, const ResourceResponse& response)
 {
-    notImplemented();
+    CFURLDownloadClient client;
+    setUpDownloadClient(client, *this);
+    m_download = adoptCF(CFURLDownloadCreateAndStartWithLoadingConnection(NULL, handle->releaseConnectionForDownload().get(), m_request.cfURLRequest(UpdateHTTPBody), response.cfURLResponse(), &client));
 }
 
 void Download::cancel()
index a1531eb..1c5431b 100644 (file)
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
-class ResourceResponse;
 class ResourceError;
+class ResourceResponse;
 }
 
 namespace WebKit {
 class AuthenticationChallengeProxy;
-class WebContext;
 class DownloadProxy;
+class WebContext;
 }
 
 namespace API {
 
 class DownloadClient {
 public:
-    virtual ~DownloadClient()   { }
+    virtual ~DownloadClient() { }
 
     virtual void didStart(WebKit::WebContext*, WebKit::DownloadProxy*) { }
     virtual void didReceiveAuthenticationChallenge(WebKit::WebContext*, WebKit::DownloadProxy*, WebKit::AuthenticationChallengeProxy*) { }
     virtual void didReceiveResponse(WebKit::WebContext*, WebKit::DownloadProxy*, const WebCore::ResourceResponse&) { }
     virtual void didReceiveData(WebKit::WebContext*, WebKit::DownloadProxy*, uint64_t length) { }
     virtual bool shouldDecodeSourceDataOfMIMEType(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String& mimeType) { return true; }
-    virtual WTF::String decideDestinationWithSuggestedFilename(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String& filename, bool& allowOverwrite)
-    {
-        return WTF::String();
-    }
+    virtual WTF::String decideDestinationWithSuggestedFilename(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String& filename, bool& allowOverwrite) { return {}; }
     virtual void didCreateDestination(WebKit::WebContext*, WebKit::DownloadProxy*, const WTF::String& path) { }
     virtual void didFinish(WebKit::WebContext*, WebKit::DownloadProxy*) { }
     virtual void didFail(WebKit::WebContext*, WebKit::DownloadProxy*, const WebCore::ResourceError&) { }
index d6ded5c..7acd76e 100644 (file)
@@ -170,7 +170,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didStart(WebContext* webContext, DownloadProxy* downloadProxy) override
         {
             if (!m_client.didStart)
-            return;
+                return;
 
             m_client.didStart(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
         }
@@ -178,7 +178,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didReceiveAuthenticationChallenge(WebContext* webContext, DownloadProxy* downloadProxy, AuthenticationChallengeProxy* authenticationChallengeProxy) override
         {
             if (!m_client.didReceiveAuthenticationChallenge)
-            return;
+                return;
 
             m_client.didReceiveAuthenticationChallenge(toAPI(webContext), toAPI(downloadProxy), toAPI(authenticationChallengeProxy), m_client.base.clientInfo);
         }
@@ -186,7 +186,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didReceiveResponse(WebContext* webContext, DownloadProxy* downloadProxy, const ResourceResponse& response) override
         {
             if (!m_client.didReceiveResponse)
-            return;
+                return;
 
             m_client.didReceiveResponse(toAPI(webContext), toAPI(downloadProxy), toAPI(API::URLResponse::create(response).get()), m_client.base.clientInfo);
         }
@@ -194,7 +194,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didReceiveData(WebContext* webContext, DownloadProxy* downloadProxy, uint64_t length) override
         {
             if (!m_client.didReceiveData)
-            return;
+                return;
 
             m_client.didReceiveData(toAPI(webContext), toAPI(downloadProxy), length, m_client.base.clientInfo);
         }
@@ -202,7 +202,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual bool shouldDecodeSourceDataOfMIMEType(WebContext* webContext, DownloadProxy* downloadProxy, const String& mimeType) override
         {
             if (!m_client.shouldDecodeSourceDataOfMIMEType)
-            return true;
+                return true;
 
             return m_client.shouldDecodeSourceDataOfMIMEType(toAPI(webContext), toAPI(downloadProxy), toAPI(mimeType.impl()), m_client.base.clientInfo);
         }
@@ -210,7 +210,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual String decideDestinationWithSuggestedFilename(WebContext* webContext, DownloadProxy* downloadProxy, const String& filename, bool& allowOverwrite) override
         {
             if (!m_client.decideDestinationWithSuggestedFilename)
-            return String();
+                return String();
 
             WKRetainPtr<WKStringRef> destination(AdoptWK, m_client.decideDestinationWithSuggestedFilename(toAPI(webContext), toAPI(downloadProxy), toAPI(filename.impl()), &allowOverwrite, m_client.base.clientInfo));
             return toWTFString(destination.get());
@@ -219,7 +219,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didCreateDestination(WebContext* webContext, DownloadProxy* downloadProxy, const String& path) override
         {
             if (!m_client.didCreateDestination)
-            return;
+                return;
 
             m_client.didCreateDestination(toAPI(webContext), toAPI(downloadProxy), toAPI(path.impl()), m_client.base.clientInfo);
         }
@@ -227,7 +227,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didFinish(WebContext* webContext, DownloadProxy* downloadProxy) override
         {
             if (!m_client.didFinish)
-            return;
+                return;
 
             m_client.didFinish(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
         }
@@ -235,7 +235,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didFail(WebContext* webContext, DownloadProxy* downloadProxy, const ResourceError& error) override
         {
             if (!m_client.didFail)
-            return;
+                return;
 
             m_client.didFail(toAPI(webContext), toAPI(downloadProxy), toAPI(error), m_client.base.clientInfo);
         }
@@ -243,7 +243,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void didCancel(WebContext* webContext, DownloadProxy* downloadProxy) override
         {
             if (!m_client.didCancel)
-            return;
+                return;
             
             m_client.didCancel(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
         }
@@ -251,7 +251,7 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload
         virtual void processDidCrash(WebContext* webContext, DownloadProxy* downloadProxy) override
         {
             if (!m_client.processDidCrash)
-            return;
+                return;
             
             m_client.processDidCrash(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo);
         }
index e155763..9ba4718 100644 (file)
 
 #if WK_API_ENABLED
 
+#import "_WKDownloadDelegate.h"
 #import "CacheModel.h"
+#import "DownloadClient.h"
 #import "HistoryClient.h"
 #import "ProcessModel.h"
 #import "WKObject.h"
 #import "WKProcessPoolConfigurationPrivate.h"
+#import "WeakObjCPtr.h"
 #import "WebCertificateInfo.h"
 #import "WebContext.h"
 #import "WebCookieManagerProxy.h"
@@ -58,7 +61,9 @@ enum : NSUInteger {
 @end
 #endif
 
-@implementation WKProcessPool
+@implementation WKProcessPool {
+    WebKit::WeakObjCPtr<id <_WKDownloadDelegate>> _downloadDelegate;
+}
 
 - (instancetype)init
 {
@@ -173,6 +178,17 @@ static WebKit::HTTPCookieAcceptPolicy toHTTPCookieAcceptPolicy(NSHTTPCookieAccep
     _context->sendToAllProcesses(Messages::WebProcess::SetInjectedBundleParameter(parameter, IPC::DataReference(static_cast<const uint8_t*>([data bytes]), [data length])));
 }
 
+- (id <_WKDownloadDelegate>)_downloadDelegate
+{
+    return _downloadDelegate.getAutoreleased();
+}
+
+- (void)_setDownloadDelegate:(id <_WKDownloadDelegate>)downloadDelegate
+{
+    _downloadDelegate = downloadDelegate;
+    _context->setDownloadClient(std::make_unique<WebKit::DownloadClient>(downloadDelegate));
+}
+
 @end
 
 #endif // WK_API_ENABLED
index ba12ce8..509464a 100644 (file)
@@ -28,6 +28,7 @@
 #if WK_API_ENABLED
 
 @class _WKProcessPoolConfiguration;
+@protocol _WKDownloadDelegate;
 
 @interface WKProcessPool (WKPrivate)
 
@@ -41,6 +42,8 @@
 - (id)_objectForBundleParameter:(NSString *)parameter;
 - (void)_setObject:(id <NSCopying, NSSecureCoding>)object forBundleParameter:(NSString *)parameter;
 
+@property (nonatomic, weak, setter=_setDownloadDelegate:) id <_WKDownloadDelegate> _downloadDelegate;
+
 @end
 
 #endif
diff --git a/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.h b/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.h
new file mode 100644 (file)
index 0000000..2562fe4
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
+ */
+
+#import <WebKit2/WKFoundation.h>
+
+#if WK_API_ENABLED
+
+#import <Foundation/Foundation.h>
+
+WK_API_CLASS
+@interface _WKDownload : NSObject
+
+@end
+
+#endif // WK_API_ENABLED
diff --git a/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.mm b/Source/WebKit2/UIProcess/API/Cocoa/_WKDownload.mm
new file mode 100644 (file)
index 0000000..1c73efd
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
+ */
+
+#import "config.h"
+#import "_WKDownloadInternal.h"
+
+#if WK_API_ENABLED
+
+#import "DownloadProxy.h"
+
+@implementation _WKDownload {
+    API::ObjectStorage<WebKit::DownloadProxy> _download;
+}
+
+- (void)dealloc
+{
+    _download->~DownloadProxy();
+
+    [super dealloc];
+}
+
+#pragma mark WKObject protocol implementation
+
+- (API::Object&)_apiObject
+{
+    return *_download;
+}
+
+@end
+
+#endif // WK_API_ENABLED
diff --git a/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadDelegate.h b/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadDelegate.h
new file mode 100644 (file)
index 0000000..6437179
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
+ */
+
+#import <WebKit2/WKFoundation.h>
+
+#if WK_API_ENABLED
+
+#import <Foundation/Foundation.h>
+
+@class _WKDownload;
+
+@protocol _WKDownloadDelegate <NSObject>
+@optional
+- (void)_downloadDidStart:(_WKDownload *)download;
+- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response;
+- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length;
+- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite;
+- (void)_downloadDidFinish:(_WKDownload *)download;
+@end
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadInternal.h b/Source/WebKit2/UIProcess/API/Cocoa/_WKDownloadInternal.h
new file mode 100644 (file)
index 0000000..fced08c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
+ */
+
+#import "_WKDownload.h"
+
+#if WK_API_ENABLED
+
+#import "WKObject.h"
+
+@protocol _WKDownloadDelegate;
+
+namespace API {
+class DownloadClient;
+}
+
+namespace WebKit {
+std::unique_ptr<API::DownloadClient> createAPIDownloadClient(id <_WKDownloadDelegate>);
+}
+
+@interface _WKDownload () <WKObject>
+@end
+
+#endif // WK_API_ENABLED
diff --git a/Source/WebKit2/UIProcess/Cocoa/DownloadClient.h b/Source/WebKit2/UIProcess/Cocoa/DownloadClient.h
new file mode 100644 (file)
index 0000000..41630b9
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
+ */
+
+#ifndef DownloadClient_h
+#define DownloadClient_h
+
+#import "WKFoundation.h"
+
+#if WK_API_ENABLED
+
+#import "APIDownloadClient.h"
+#import "WeakObjCPtr.h"
+
+@protocol _WKDownloadDelegate;
+
+namespace WebCore {
+class ResourceResponse;
+}
+
+namespace WebKit {
+    
+class DownloadClient final : public API::DownloadClient {
+public:
+    explicit DownloadClient(id <_WKDownloadDelegate>);
+    
+private:
+    // From API::DownloadClient
+    virtual void didStart(WebContext*, DownloadProxy*);
+    virtual void didReceiveResponse(WebContext*, DownloadProxy*, const WebCore::ResourceResponse&);
+    virtual void didReceiveData(WebContext*, DownloadProxy*, uint64_t length);
+    virtual String decideDestinationWithSuggestedFilename(WebContext*, DownloadProxy*, const String& filename, bool& allowOverwriteParam);
+    virtual void didFinish(WebContext*, DownloadProxy*);
+
+    WeakObjCPtr<id <_WKDownloadDelegate>> m_delegate;
+
+    struct {
+        bool downloadDidStart : 1;            
+        bool downloadDidReceiveResponse : 1;
+        bool downloadDidReceiveData : 1;
+        bool downloadDecideDestinationWithSuggestedFilenameAllowOverwrite : 1;
+        bool downloadDidFinish : 1;
+    } m_delegateMethods;
+};
+
+} // namespace WebKit
+
+#endif
+
+#endif // DownloadClient_h
diff --git a/Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm b/Source/WebKit2/UIProcess/Cocoa/DownloadClient.mm
new file mode 100644 (file)
index 0000000..34b7331
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
+ */
+
+#import "config.h"
+#import "DownloadClient.h"
+
+#if WK_API_ENABLED
+
+#import "_WKDownloadDelegate.h"
+#import "_WKDownloadInternal.h"
+#import "DownloadProxy.h"
+#import <WebCore/ResourceResponse.h>
+
+namespace WebKit {
+
+static inline _WKDownload *wrapper(DownloadProxy& download)
+{
+    ASSERT([download.wrapper() isKindOfClass:[_WKDownload class]]);
+    return (_WKDownload *)download.wrapper();
+}
+
+DownloadClient::DownloadClient(id <_WKDownloadDelegate> delegate)
+    : m_delegate(delegate)
+{
+    m_delegateMethods.downloadDidStart = [delegate respondsToSelector:@selector(_downloadDidStart:)];
+    m_delegateMethods.downloadDidReceiveResponse = [delegate respondsToSelector:@selector(_download:didReceiveResponse:)];
+    m_delegateMethods.downloadDidReceiveData = [delegate respondsToSelector:@selector(_download:didReceiveData:)];
+    m_delegateMethods.downloadDecideDestinationWithSuggestedFilenameAllowOverwrite = [delegate respondsToSelector:@selector(_download:decideDestinationWithSuggestedFilename:allowOverwrite:)];
+    m_delegateMethods.downloadDidFinish = [delegate respondsToSelector:@selector(_downloadDidFinish:)];
+}
+
+void DownloadClient::didStart(WebContext*, DownloadProxy* downloadProxy)
+{
+    if (m_delegateMethods.downloadDidStart)
+        [m_delegate.get() _downloadDidStart:wrapper(*downloadProxy)];
+}
+
+void DownloadClient::didReceiveResponse(WebContext*, DownloadProxy* downloadProxy, const WebCore::ResourceResponse& response)
+{
+    if (m_delegateMethods.downloadDidReceiveResponse)
+        [m_delegate.get() _download:wrapper(*downloadProxy) didReceiveResponse:response.nsURLResponse()];
+}
+
+void DownloadClient::didReceiveData(WebContext*, DownloadProxy* downloadProxy, uint64_t length)
+{
+    if (m_delegateMethods.downloadDidReceiveData)
+        [m_delegate.get() _download:wrapper(*downloadProxy) didReceiveData:length];
+}
+
+String DownloadClient::decideDestinationWithSuggestedFilename(WebContext*, DownloadProxy* downloadProxy, const String& filename, bool& allowOverwriteParam)
+{
+    if (!m_delegateMethods.downloadDecideDestinationWithSuggestedFilenameAllowOverwrite)
+        return String();
+    
+    BOOL allowOverwrite;
+    NSString *destination = [m_delegate.get() _download:wrapper(*downloadProxy) decideDestinationWithSuggestedFilename:filename allowOverwrite:&allowOverwrite];
+    allowOverwriteParam = allowOverwrite;
+    return destination;
+}
+
+void DownloadClient::didFinish(WebContext*, DownloadProxy* downloadProxy)
+{
+    if (m_delegateMethods.downloadDidFinish)
+        [m_delegate.get() _downloadDidFinish:wrapper(*downloadProxy)];
+}
+
+} // namespace WebKit
+
+#endif // WK_API_ENABLED
\ No newline at end of file
index 0521462..218d3fe 100644 (file)
                9F54F8951648AE0F007DF81A /* PluginProcessManagerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9F54F8941648AE0E007DF81A /* PluginProcessManagerMac.mm */; };
                9FB5F394169E6A80002C25BF /* WKContextPrivateMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FB5F392169E6A80002C25BF /* WKContextPrivateMac.mm */; };
                9FB5F395169E6A80002C25BF /* WKContextPrivateMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 9FB5F393169E6A80002C25BF /* WKContextPrivateMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A1A4FE5B18DCE9FA00B5EA8A /* _WKDownload.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */; };
+               A1A4FE5C18DCE9FA00B5EA8A /* _WKDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */; };
+               A1A4FE6118DD54A400B5EA8A /* _WKDownloadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE6018DD54A400B5EA8A /* _WKDownloadDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A1DF631218E0B7C8003A3E2A /* DownloadClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1DF631018E0B7C8003A3E2A /* DownloadClient.mm */; };
+               A1DF631318E0B7C8003A3E2A /* DownloadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A1DF631118E0B7C8003A3E2A /* DownloadClient.h */; };
                A5EFD38C16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A5EFD38B16B0E88C00B2F0E8 /* WKPageVisibilityTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7D792D61767CB6E00881CBE /* ActivityAssertion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D792D51767CB6E00881CBE /* ActivityAssertion.cpp */; };
                A7D792D81767CCA300881CBE /* ActivityAssertion.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D792D41767CB0900881CBE /* ActivityAssertion.h */; };
                9F54F8941648AE0E007DF81A /* PluginProcessManagerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PluginProcessManagerMac.mm; sourceTree = "<group>"; };
                9FB5F392169E6A80002C25BF /* WKContextPrivateMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKContextPrivateMac.mm; path = mac/WKContextPrivateMac.mm; sourceTree = "<group>"; };
                9FB5F393169E6A80002C25BF /* WKContextPrivateMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKContextPrivateMac.h; path = mac/WKContextPrivateMac.h; sourceTree = "<group>"; };
+               A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownload.h; sourceTree = "<group>"; };
+               A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKDownload.mm; sourceTree = "<group>"; };
+               A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownloadInternal.h; sourceTree = "<group>"; };
+               A1A4FE6018DD54A400B5EA8A /* _WKDownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownloadDelegate.h; sourceTree = "<group>"; };
+               A1DF631018E0B7C8003A3E2A /* DownloadClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DownloadClient.mm; sourceTree = "<group>"; };
+               A1DF631118E0B7C8003A3E2A /* DownloadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadClient.h; sourceTree = "<group>"; };
                A1EDD2D91884ACE000BBFE98 /* All.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = All.xcconfig; sourceTree = "<group>"; };
                A1EDD2DB1884B96400BBFE98 /* PluginProcessShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = PluginProcessShim.xcconfig; sourceTree = "<group>"; };
                A1EDD2DC1884B9B500BBFE98 /* SecItemShim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SecItemShim.xcconfig; sourceTree = "<group>"; };
                1ABC3DF21899E415004F0626 /* Cocoa */ = {
                        isa = PBXGroup;
                        children = (
-                               2D7AAFD218C8640600A7ACD4 /* WKWebViewContentProvider.h */,
-                               2DC6D9C118C44A610043BAD4 /* WKWebViewContentProviderRegistry.h */,
-                               2DC6D9C218C44A610043BAD4 /* WKWebViewContentProviderRegistry.mm */,
-                               0F0C365918C0555800F607D7 /* LayerRepresentation.h */,
+                               A1DF631118E0B7C8003A3E2A /* DownloadClient.h */,
+                               A1DF631018E0B7C8003A3E2A /* DownloadClient.mm */,
                                1A422F8D18B29C6400D8CD96 /* HistoryClient.h */,
                                1A422F8C18B29C6400D8CD96 /* HistoryClient.mm */,
+                               0F0C365918C0555800F607D7 /* LayerRepresentation.h */,
                                1ABC3DF41899E437004F0626 /* NavigationState.h */,
                                1ABC3DF31899E437004F0626 /* NavigationState.mm */,
                                1AFE436418B6C081009C7A48 /* UIClient.h */,
                                1AFE436318B6C081009C7A48 /* UIClient.mm */,
+                               2D7AAFD218C8640600A7ACD4 /* WKWebViewContentProvider.h */,
+                               2DC6D9C118C44A610043BAD4 /* WKWebViewContentProviderRegistry.h */,
+                               2DC6D9C218C44A610043BAD4 /* WKWebViewContentProviderRegistry.mm */,
                        );
                        path = Cocoa;
                        sourceTree = "<group>";
                                37A5E01218BBF937000A081E /* _WKActivatedElementInfo.h */,
                                37A5E01118BBF937000A081E /* _WKActivatedElementInfo.mm */,
                                379A873518BBFA4300588AF2 /* _WKActivatedElementInfoInternal.h */,
+                               A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */,
+                               A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */,
+                               A1A4FE6018DD54A400B5EA8A /* _WKDownloadDelegate.h */,
+                               A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */,
                                379A873818BBFE0F00588AF2 /* _WKElementAction.h */,
                                379A873718BBFE0F00588AF2 /* _WKElementAction.mm */,
                                379A873B18BBFF0700588AF2 /* _WKElementActionInternal.h */,
                                C517388112DF8F4F00EE3F47 /* DragControllerAction.h in Headers */,
                                BC8452A81162C80900CAB9B5 /* DrawingArea.h in Headers */,
                                378E1A4A18208CD60031007A /* WKNSString.h in Headers */,
+                               A1A4FE5C18DCE9FA00B5EA8A /* _WKDownloadInternal.h in Headers */,
                                2D8949F1182044F600E898AA /* PlatformCALayerRemoteTiledBacking.h in Headers */,
                                0FB659231208B4DB0044816C /* DrawingAreaInfo.h in Headers */,
                                26F9A83B18A3468100AEB88A /* WKWebViewPrivate.h in Headers */,
                                51FD18B61651FBAD00DBE1CE /* NetworkResourceLoader.h in Headers */,
                                E152551B17011819003D7ADB /* NetworkResourceLoaderMessages.h in Headers */,
                                51CBBA10165219B6005BE8FD /* NetworkResourceLoadParameters.h in Headers */,
+                               A1DF631318E0B7C8003A3E2A /* DownloadClient.h in Headers */,
                                51829DA61637C70C000953D6 /* NetworkResourceLoadScheduler.h in Headers */,
                                31A2EC5614899C0900810D71 /* NotificationPermissionRequest.h in Headers */,
                                3131261F148FF82C00BA2A39 /* NotificationPermissionRequestManager.h in Headers */,
                                7CF47FFF17276AE3008ACB91 /* WKBundlePageBannerMac.h in Headers */,
                                BC7B633D12A45D1200D174A4 /* WKBundlePageGroup.h in Headers */,
                                ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */,
+                               A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */,
                                BC1B419811D41D570011E8DD /* WKBundlePagePrivate.h in Headers */,
                                BCF049E711FE20F600F86A58 /* WKBundlePrivate.h in Headers */,
                                BC60C5791240A546008C5E29 /* WKBundleRangeHandle.h in Headers */,
                                1AE00D5D182DADE100087DD7 /* KeyedEncoder.h in Headers */,
                                3309345B1315B9980097A7BC /* WKCookieManager.h in Headers */,
                                512F58FA12A88A5400629530 /* WKCredential.h in Headers */,
+                               A1A4FE6118DD54A400B5EA8A /* _WKDownloadDelegate.h in Headers */,
                                0FCB4E4618BBE044000FCFC9 /* PageClientImplIOS.h in Headers */,
                                518ACF1112B015F800B04B83 /* WKCredentialTypes.h in Headers */,
                                1AFDD3171891C94700153970 /* WKPreferences.h in Headers */,
                                37183D56182F4E700080C811 /* WKNSURLExtras.mm in Sources */,
                                374436881820E7240049579F /* WKObject.mm in Sources */,
                                1A0F29E3120B44420053D1B9 /* VisitedLinkProvider.cpp in Sources */,
+                               A1DF631218E0B7C8003A3E2A /* DownloadClient.mm in Sources */,
                                1A0F29CB120B37160053D1B9 /* VisitedLinkTable.cpp in Sources */,
                                1AC1337F18590AE400F3EC05 /* RemoteObjectRegistry.mm in Sources */,
                                CEDA12E2152CD1AE00D9E08D /* WebAlternativeTextClient.cpp in Sources */,
                                BC3066BE125A442100E71278 /* WebProcessMessageReceiver.cpp in Sources */,
                                BC111B11112F5E4F00337BAB /* WebProcessProxy.cpp in Sources */,
                                51032F18180F73BB00961BB7 /* WebToDatabaseProcessConnection.cpp in Sources */,
+                               A1A4FE5B18DCE9FA00B5EA8A /* _WKDownload.mm in Sources */,
                                51D130581382F10500351EDD /* WebProcessProxyMac.mm in Sources */,
                                BCEE7AD012817988009827DA /* WebProcessProxyMessageReceiver.cpp in Sources */,
                                512F589C12A8838800629530 /* WebProtectionSpace.cpp in Sources */,
index 2b26701..7d83617 100644 (file)
@@ -1,3 +1,26 @@
+2014-03-24  Andy Estes  <aestes@apple.com>
+
+        [iOS] Download support by CFURLDownloadRef under USE(CFNETWORK).
+        https://bugs.webkit.org/show_bug.cgi?id=129322
+
+        Reviewed by Anders Carlsson.
+
+        Add an API test suite for _WKDownload.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm: Added.
+        (-[DownloadDelegate initWithSourceURL:]):
+        (-[DownloadDelegate sourceURL]):
+        (-[DownloadDelegate _downloadDidStart:]):
+        (-[DownloadDelegate _download:didReceiveResponse:]):
+        (-[DownloadDelegate _download:didReceiveData:]):
+        (-[DownloadDelegate _download:decideDestinationWithSuggestedFilename:allowOverwrite:]):
+        (-[DownloadDelegate _downloadDidFinish:]):
+        (TEST):
+        (runTestWithNavigationDelegate):
+        (-[DownloadNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (-[ConvertResponseToDownloadNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):
+
 2014-03-24  Joseph Pecoraro  <pecoraro@apple.com>
 
         filter-build-webkit: reduce unfiltered output
index be41f8c..8bbb570 100644 (file)
                9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */; };
                9B4F8FA4159D52B1002D9F94 /* HTMLCollectionNamedItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */; };
                9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
+               A1A4FE5F18DD3DB700B5EA8A /* Download.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1A4FE5D18DD3DB700B5EA8A /* Download.mm */; };
                A57A34F016AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm in Sources */ = {isa = PBXBuildFile; fileRef = A57A34EF16AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm */; };
                A57A34F216AF6B2B00C2501F /* PageVisibilityStateWithWindowChanges.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */; };
                A5E2027315B2181900C13E14 /* WindowlessWebViewWithMedia.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */; };
                9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLFormCollectionNamedItem.html; sourceTree = "<group>"; };
                9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = "<group>"; };
                9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; };
+               A1A4FE5D18DD3DB700B5EA8A /* Download.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Download.mm; sourceTree = "<group>"; };
                A57A34EF16AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageVisibilityStateWithWindowChanges.mm; sourceTree = "<group>"; };
                A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = PageVisibilityStateWithWindowChanges.html; sourceTree = "<group>"; };
                A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = WindowlessWebViewWithMedia.html; sourceTree = "<group>"; };
                1ABC3DEC1899BE55004F0626 /* WebKit2 Cocoa */ = {
                        isa = PBXGroup;
                        children = (
+                               A1A4FE5D18DD3DB700B5EA8A /* Download.mm */,
                                1ABC3DED1899BE6D004F0626 /* Navigation.mm */,
                        );
                        name = "WebKit2 Cocoa";
                                14464013167A8305000BD218 /* LayoutUnit.cpp in Sources */,
                                2D640B5517875DFF00BFAF99 /* ScrollPinningBehaviors.cpp in Sources */,
                                26300B1816755CD90066886D /* ListHashSet.cpp in Sources */,
+                               A1A4FE5F18DD3DB700B5EA8A /* Download.mm in Sources */,
                                52CB47411448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp in Sources */,
                                33DC8911141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp in Sources */,
                                8AA28C1A16D2FA7B002FF4DB /* LoadPageOnCrash.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/Download.mm
new file mode 100644 (file)
index 0000000..0f9e581
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2014 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
+ */
+
+#import "config.h"
+#import <WebKit2/WKFoundation.h>
+
+#if WK_API_ENABLED
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+#import <WebCore/FileSystem.h>
+#import <WebKit2/_WKDownloadDelegate.h>
+#import <WebKit2/WKNavigationDelegate.h>
+#import <WebKit2/WKProcessPoolPrivate.h>
+#import <WebKit2/WKWebView.h>
+#import <WebKit2/WKWebViewConfiguration.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/text/WTFString.h>
+
+static bool isDone;
+
+@interface DownloadDelegate : NSObject <_WKDownloadDelegate>
+- (id)initWithSourceURL:(NSURL *)sourceURL;
+@property (nonatomic, readonly) NSURL *sourceURL;
+@end
+
+@implementation DownloadDelegate {
+    RetainPtr<_WKDownload> _download;
+    RetainPtr<NSURL> _sourceURL;
+    String _destinationPath;
+    long long _expectedContentLength;
+    uint64_t _receivedContentLength;
+}
+
+- (id)initWithSourceURL:(NSURL *)sourceURL
+{
+    if (!(self = [super init]))
+        return nil;
+    _sourceURL = sourceURL;
+    _expectedContentLength = 0;
+    _receivedContentLength = 0;
+    return self;
+}
+
+- (NSURL *)sourceURL
+{
+    return _sourceURL.get();
+}
+
+- (void)_downloadDidStart:(_WKDownload *)download
+{
+    EXPECT_NULL(_download);
+    EXPECT_NOT_NULL(download);
+    _download = download;
+}
+
+- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
+{
+    EXPECT_EQ(_download, download);
+    EXPECT_TRUE(_expectedContentLength == 0);
+    EXPECT_TRUE(_receivedContentLength == 0);
+    EXPECT_TRUE([[response URL] isEqual:[self sourceURL]]);
+    _expectedContentLength = [response expectedContentLength];
+}
+
+- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
+{
+    EXPECT_EQ(_download, download);
+    _receivedContentLength += length;
+}
+
+- (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
+{
+    EXPECT_EQ(_download, download);
+
+    WebCore::PlatformFileHandle fileHandle;
+    _destinationPath = WebCore::openTemporaryFile("TestWebKitAPI", fileHandle);
+    EXPECT_TRUE(fileHandle != WebCore::invalidPlatformFileHandle);
+    WebCore::closeFile(fileHandle);
+
+    *allowOverwrite = YES;
+    return _destinationPath;
+}
+
+- (void)_downloadDidFinish:(_WKDownload *)download
+{
+    EXPECT_EQ(_download, download);
+    EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast<uint64_t>(_expectedContentLength) == _receivedContentLength);
+    EXPECT_TRUE([[NSFileManager defaultManager] contentsEqualAtPath:_destinationPath andPath:[_sourceURL path]]);
+    WebCore::deleteFile(_destinationPath);
+    isDone = true;
+}
+
+@end
+
+TEST(_WKDownload, DownloadDelegate)
+{
+    RetainPtr<WKProcessPool> processPool = adoptNS([[WKProcessPool alloc] init]);
+    DownloadDelegate *downloadDelegate = [[DownloadDelegate alloc] init];
+    [processPool _setDownloadDelegate:downloadDelegate];
+
+    @autoreleasepool {
+        EXPECT_EQ(downloadDelegate, [processPool _downloadDelegate]);
+    }
+
+    [downloadDelegate release];
+    EXPECT_NULL([processPool _downloadDelegate]);
+}
+
+static void runTestWithNavigationDelegate(id <WKNavigationDelegate> navigationDelegate)
+{
+    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView setNavigationDelegate:navigationDelegate];
+
+    RetainPtr<DownloadDelegate> downloadDelegate = adoptNS([[DownloadDelegate alloc] initWithSourceURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]);
+    [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
+
+    [webView loadRequest:[NSURLRequest requestWithURL:[downloadDelegate sourceURL]]];
+    TestWebKitAPI::Util::run(&isDone);
+}
+
+@interface DownloadNavigationDelegate : NSObject <WKNavigationDelegate>
+@end
+
+@implementation DownloadNavigationDelegate
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationPolicyDecision))decisionHandler
+{
+    decisionHandler(WKNavigationPolicyDecisionDownload);
+}
+@end
+
+TEST(_WKDownload, DownloadRequest)
+{
+    runTestWithNavigationDelegate(adoptNS([[DownloadNavigationDelegate alloc] init]).get());
+}
+
+@interface ConvertResponseToDownloadNavigationDelegate : NSObject <WKNavigationDelegate>
+@end
+
+@implementation ConvertResponseToDownloadNavigationDelegate
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicyDecision))decisionHandler
+{
+    decisionHandler(WKNavigationResponsePolicyDecisionBecomeDownload);
+}
+@end
+
+TEST(_WKDownload, ConvertResponseToDownload)
+{
+    runTestWithNavigationDelegate(adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]).get());
+}
+
+#endif