From 3c3c719fec7ed8efcfa40f778d58b143aef97780 Mon Sep 17 00:00:00 2001 From: Per Arne Vollan Date: Mon, 2 Sep 2024 15:52:20 -0700 Subject: [PATCH] The download client should be able to determine if a placeholder should be used https://bugs.webkit.org/show_bug.cgi?id=278737 rdar://134794671 Reviewed by Alex Christensen. The download client should be able to determine if a placeholder should be used for the final location of the download. This patch prepares for this by passing the value from the UI process to the Networking process. This was previously landed in . This version addresses a build error. * Source/WebKit/NetworkProcess/Downloads/Download.h: * Source/WebKit/NetworkProcess/Downloads/DownloadManager.cpp: (WebKit::DownloadManager::publishDownloadProgress): * Source/WebKit/NetworkProcess/Downloads/DownloadManager.h: * Source/WebKit/NetworkProcess/Downloads/PendingDownload.cpp: (WebKit::PendingDownload::publishProgress): (WebKit::PendingDownload::didBecomeDownload): * Source/WebKit/NetworkProcess/Downloads/PendingDownload.h: * Source/WebKit/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm: (WebKit::Download::publishProgress): * Source/WebKit/NetworkProcess/NetworkProcess.cpp: (WebKit::NetworkProcess::publishDownloadProgress): * Source/WebKit/NetworkProcess/NetworkProcess.h: * Source/WebKit/NetworkProcess/NetworkProcess.messages.in: * Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h: * Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm: (-[_WKDownload publishProgressAtURL:]): * Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm: (-[WKDownload setDelegate:]): * Source/WebKit/UIProcess/API/Cocoa/WKDownloadDelegate.h: * Source/WebKit/UIProcess/API/Cocoa/WKDownloadDelegatePrivate.h: Added. * Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp: (WebKit::DownloadProxy::decideDestinationWithSuggestedFilename): * Source/WebKit/UIProcess/Downloads/DownloadProxy.h: (WebKit::DownloadProxy::setUseDownloadPlaceholder): * Source/WebKit/UIProcess/Downloads/DownloadProxyCocoa.mm: (WebKit::DownloadProxy::publishProgress): * Source/WebKit/WebKit.xcodeproj/project.pbxproj: * Tools/TestWebKitAPI/Tests/WebKitCocoa/Download.mm: (TestWebKitAPI::DecidePlaceholderPolicy)): * Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.h: * Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.mm: (-[TestDownloadDelegate _download:decidePlaceholderPolicy:]): Canonical link: https://commits.webkit.org/283071@main --- .../NetworkProcess/Downloads/Download.h | 3 +- .../Downloads/DownloadManager.cpp | 6 +- .../Downloads/DownloadManager.h | 3 +- .../Downloads/PendingDownload.cpp | 5 +- .../Downloads/PendingDownload.h | 4 +- .../Downloads/cocoa/DownloadCocoa.mm | 5 +- .../WebKit/NetworkProcess/NetworkProcess.cpp | 14 ++++- Source/WebKit/NetworkProcess/NetworkProcess.h | 3 +- .../NetworkProcess/NetworkProcess.messages.in | 3 - .../WebKit/Shared/API/Cocoa/WebKitPrivate.h | 1 + .../WebKit/UIProcess/API/APIDownloadClient.h | 5 +- .../WebKit/UIProcess/API/Cocoa/WKDownload.mm | 38 +++++++++++- .../API/Cocoa/WKDownloadDelegatePrivate.h | 59 +++++++++++++++++++ .../WebKit/UIProcess/API/Cocoa/_WKDownload.mm | 2 + .../UIProcess/Downloads/DownloadProxy.cpp | 11 ++-- .../UIProcess/Downloads/DownloadProxy.h | 8 ++- .../Downloads/DownloadProxy.messages.in | 3 +- .../UIProcess/Downloads/DownloadProxyCocoa.mm | 9 +-- .../Downloads/UseDownloadPlaceholder.h | 35 +++++++++++ .../WebKit/WebKit.xcodeproj/project.pbxproj | 8 +++ .../Tests/WebKitCocoa/Download.mm | 33 +++++++++++ .../cocoa/TestDownloadDelegate.h | 6 +- .../cocoa/TestDownloadDelegate.mm | 8 +++ 23 files changed, 235 insertions(+), 37 deletions(-) create mode 100644 Source/WebKit/UIProcess/API/Cocoa/WKDownloadDelegatePrivate.h create mode 100644 Source/WebKit/UIProcess/Downloads/UseDownloadPlaceholder.h diff --git a/Source/WebKit/NetworkProcess/Downloads/Download.h b/Source/WebKit/NetworkProcess/Downloads/Download.h index 8693167981db7..46624f548d53e 100644 --- a/Source/WebKit/NetworkProcess/Downloads/Download.h +++ b/Source/WebKit/NetworkProcess/Downloads/Download.h @@ -31,6 +31,7 @@ #include "MessageSender.h" #include "NetworkDataTask.h" #include "SandboxExtension.h" +#include "UseDownloadPlaceholder.h" #include #include #include @@ -90,7 +91,7 @@ class Download : public IPC::MessageSender, public CanMakeWeakPtr, pub #endif #if HAVE(MODERN_DOWNLOADPROGRESS) - void publishProgress(const URL&, std::span); + void publishProgress(const URL&, std::span, WebKit::UseDownloadPlaceholder); #endif DownloadID downloadID() const { return m_downloadID; } diff --git a/Source/WebKit/NetworkProcess/Downloads/DownloadManager.cpp b/Source/WebKit/NetworkProcess/Downloads/DownloadManager.cpp index 005b9c36c3e75..5c55ea51cec35 100644 --- a/Source/WebKit/NetworkProcess/Downloads/DownloadManager.cpp +++ b/Source/WebKit/NetworkProcess/Downloads/DownloadManager.cpp @@ -129,12 +129,12 @@ void DownloadManager::cancelDownload(DownloadID downloadID, CompletionHandler bookmarkData) +void DownloadManager::publishDownloadProgress(DownloadID downloadID, const URL& url, std::span bookmarkData, WebKit::UseDownloadPlaceholder useDownloadPlaceholder) { if (auto* download = m_downloads.get(downloadID)) - download->publishProgress(url, bookmarkData); + download->publishProgress(url, bookmarkData, useDownloadPlaceholder); else if (auto* pendingDownload = m_pendingDownloads.get(downloadID)) - pendingDownload->publishProgress(url, bookmarkData); + pendingDownload->publishProgress(url, bookmarkData, useDownloadPlaceholder); } #else void DownloadManager::publishDownloadProgress(DownloadID downloadID, const URL& url, SandboxExtension::Handle&& sandboxExtensionHandle) diff --git a/Source/WebKit/NetworkProcess/Downloads/DownloadManager.h b/Source/WebKit/NetworkProcess/Downloads/DownloadManager.h index ffa871eb88802..4ad623d6b0247 100644 --- a/Source/WebKit/NetworkProcess/Downloads/DownloadManager.h +++ b/Source/WebKit/NetworkProcess/Downloads/DownloadManager.h @@ -31,6 +31,7 @@ #include "PendingDownload.h" #include "PolicyDecision.h" #include "SandboxExtension.h" +#include "UseDownloadPlaceholder.h" #include #include #include @@ -101,7 +102,7 @@ class DownloadManager : public CanMakeCheckedPtr { void cancelDownload(DownloadID, CompletionHandler)>&&); #if PLATFORM(COCOA) #if HAVE(MODERN_DOWNLOADPROGRESS) - void publishDownloadProgress(DownloadID, const URL&, std::span bookmarkData); + void publishDownloadProgress(DownloadID, const URL&, std::span bookmarkData, WebKit::UseDownloadPlaceholder); #else void publishDownloadProgress(DownloadID, const URL&, SandboxExtension::Handle&&); #endif diff --git a/Source/WebKit/NetworkProcess/Downloads/PendingDownload.cpp b/Source/WebKit/NetworkProcess/Downloads/PendingDownload.cpp index 950f09ed5e466..7db1d44333cff 100644 --- a/Source/WebKit/NetworkProcess/Downloads/PendingDownload.cpp +++ b/Source/WebKit/NetworkProcess/Downloads/PendingDownload.cpp @@ -81,11 +81,12 @@ void PendingDownload::cancel(CompletionHandler)>&& #if PLATFORM(COCOA) #if HAVE(MODERN_DOWNLOADPROGRESS) -void PendingDownload::publishProgress(const URL& url, std::span bookmarkData) +void PendingDownload::publishProgress(const URL& url, std::span bookmarkData, UseDownloadPlaceholder useDownloadPlaceholder) { ASSERT(!m_progressURL.isValid()); m_progressURL = url; m_bookmarkData = bookmarkData; + m_useDownloadPlaceholder = useDownloadPlaceholder; } #else void PendingDownload::publishProgress(const URL& url, SandboxExtension::Handle&& sandboxExtension) @@ -101,7 +102,7 @@ void PendingDownload::didBecomeDownload(const std::unique_ptr& downloa if (!m_progressURL.isValid()) return; #if HAVE(MODERN_DOWNLOADPROGRESS) - download->publishProgress(m_progressURL, m_bookmarkData); + download->publishProgress(m_progressURL, m_bookmarkData, m_useDownloadPlaceholder); #else download->publishProgress(m_progressURL, WTFMove(m_progressSandboxExtension)); #endif diff --git a/Source/WebKit/NetworkProcess/Downloads/PendingDownload.h b/Source/WebKit/NetworkProcess/Downloads/PendingDownload.h index 1d9bc9178e26d..355efe36187ea 100644 --- a/Source/WebKit/NetworkProcess/Downloads/PendingDownload.h +++ b/Source/WebKit/NetworkProcess/Downloads/PendingDownload.h @@ -29,6 +29,7 @@ #include "MessageSender.h" #include "NetworkLoadClient.h" #include "SandboxExtension.h" +#include "UseDownloadPlaceholder.h" #include namespace WebKit { @@ -66,7 +67,7 @@ class PendingDownload : public NetworkLoadClient, public IPC::MessageSender, pub #if PLATFORM(COCOA) #if HAVE(MODERN_DOWNLOADPROGRESS) - void publishProgress(const URL&, std::span); + void publishProgress(const URL&, std::span, UseDownloadPlaceholder); #else void publishProgress(const URL&, SandboxExtension::Handle&&); #endif @@ -97,6 +98,7 @@ class PendingDownload : public NetworkLoadClient, public IPC::MessageSender, pub URL m_progressURL; #if HAVE(MODERN_DOWNLOADPROGRESS) Vector m_bookmarkData; + UseDownloadPlaceholder m_useDownloadPlaceholder { UseDownloadPlaceholder::No }; #else SandboxExtension::Handle m_progressSandboxExtension; #endif diff --git a/Source/WebKit/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm b/Source/WebKit/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm index bf104edf9baf8..65cbf30d4d9ad 100644 --- a/Source/WebKit/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm +++ b/Source/WebKit/NetworkProcess/Downloads/cocoa/DownloadCocoa.mm @@ -90,7 +90,7 @@ } #if HAVE(MODERN_DOWNLOADPROGRESS) -void Download::publishProgress(const URL& url, std::span bookmarkData) +void Download::publishProgress(const URL& url, std::span bookmarkData, UseDownloadPlaceholder useDownloadPlaceholder) { if (m_progress) { RELEASE_LOG(Network, "Progress is already being published for download."); @@ -110,7 +110,8 @@ bool shouldEnableModernDownloadProgress = CFPreferencesGetAppBooleanValue(CFSTR("EnableModernDownloadProgress"), CFSTR("com.apple.WebKit"), NULL); if (shouldEnableModernDownloadProgress) { - m_progress = adoptNS([[WKModernDownloadProgress alloc] initWithDownloadTask:m_downloadTask.get() download:*this URL:(NSURL *)url]); + NSData *accessToken = [NSData data]; // FIXME: replace with actual access token + m_progress = adoptNS([[WKModernDownloadProgress alloc] initWithDownloadTask:m_downloadTask.get() download:*this URL:(NSURL *)url useDownloadPlaceholder:useDownloadPlaceholder == WebKit::UseDownloadPlaceholder::Yes liveActivityAccessToken:accessToken]); [m_progress publish]; } else { m_progress = adoptNS([[WKDownloadProgress alloc] initWithDownloadTask:m_downloadTask.get() download:*this URL:(NSURL *)url sandboxExtension:nullptr]); diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp index 131b888ff51fc..73199cde54beb 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp +++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp @@ -2141,9 +2141,9 @@ void NetworkProcess::cancelDownload(DownloadID downloadID, CompletionHandler bookmarkData) +void NetworkProcess::publishDownloadProgress(DownloadID downloadID, const URL& url, std::span bookmarkData, WebKit::UseDownloadPlaceholder useDownloadPlaceholder) { - downloadManager().publishDownloadProgress(downloadID, url, bookmarkData); + downloadManager().publishDownloadProgress(downloadID, url, bookmarkData, useDownloadPlaceholder); } #else void NetworkProcess::publishDownloadProgress(DownloadID downloadID, const URL& url, SandboxExtension::Handle&& sandboxExtensionHandle) @@ -2157,7 +2157,7 @@ void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTas { String suggestedFilename = networkDataTask.suggestedFilename(); - downloadProxyConnection()->sendWithAsyncReply(Messages::DownloadProxy::DecideDestinationWithSuggestedFilename(response, suggestedFilename), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler), networkDataTask = Ref { networkDataTask }] (String&& destination, SandboxExtension::Handle&& sandboxExtensionHandle, AllowOverwrite allowOverwrite) mutable { + downloadProxyConnection()->sendWithAsyncReply(Messages::DownloadProxy::DecideDestinationWithSuggestedFilename(response, suggestedFilename), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler), networkDataTask = Ref { networkDataTask }] (String&& destination, SandboxExtension::Handle&& sandboxExtensionHandle, AllowOverwrite allowOverwrite, WebKit::UseDownloadPlaceholder usePlaceholder) mutable { auto downloadID = *networkDataTask->pendingDownloadID(); if (destination.isEmpty()) return completionHandler(PolicyAction::Ignore); @@ -2166,6 +2166,14 @@ void NetworkProcess::findPendingDownloadLocation(NetworkDataTask& networkDataTas if (networkDataTask->state() == NetworkDataTask::State::Canceling || networkDataTask->state() == NetworkDataTask::State::Completed) return; +#if HAVE(MODERN_DOWNLOADPROGRESS) + bool shouldEnableModernDownloadProgress = CFPreferencesGetAppBooleanValue(CFSTR("EnableModernDownloadProgress"), CFSTR("com.apple.WebKit"), nullptr); + if (shouldEnableModernDownloadProgress) + publishDownloadProgress(downloadID, URL::fileURLWithFileSystemPath(destination), std::span(), usePlaceholder); +#else + UNUSED_PARAM(usePlaceholder); +#endif + if (downloadManager().download(downloadID)) { // The completion handler already called dataTaskBecameDownloadTask(). return; diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h index fb1687978260d..6c985c9be7b4e 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.h +++ b/Source/WebKit/NetworkProcess/NetworkProcess.h @@ -33,6 +33,7 @@ #include "DownloadManager.h" #include "NetworkContentRuleListManager.h" #include "QuotaIncreaseRequestIdentifier.h" +#include "UseDownloadPlaceholder.h" #include "WebPageProxyIdentifier.h" #include "WebResourceLoadStatisticsStore.h" #include "WebsiteData.h" @@ -483,7 +484,7 @@ class NetworkProcess final : public AuxiliaryProcess, private DownloadManager::C void cancelDownload(DownloadID, CompletionHandler)>&&); #if PLATFORM(COCOA) #if HAVE(MODERN_DOWNLOADPROGRESS) - void publishDownloadProgress(DownloadID, const URL&, std::span bookmarkData); + void publishDownloadProgress(DownloadID, const URL&, std::span bookmarkData, WebKit::UseDownloadPlaceholder); #else void publishDownloadProgress(DownloadID, const URL&, SandboxExtensionHandle&&); #endif diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in index 40a427dca2ace..a9b36cf601fff 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in +++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in @@ -52,9 +52,6 @@ messages -> NetworkProcess LegacyReceiver { DownloadRequest(PAL::SessionID sessionID, WebKit::DownloadID downloadID, WebCore::ResourceRequest request, std::optional topOrigin, std::optional isNavigatingToAppBoundDomain, String suggestedFilename) ResumeDownload(PAL::SessionID sessionID, WebKit::DownloadID downloadID, std::span resumeData, String path, WebKit::SandboxExtensionHandle sandboxExtensionHandle, enum:bool WebKit::CallDownloadDidStart callDownloadDidStart) CancelDownload(WebKit::DownloadID downloadID) -> (std::span resumeData) -#if HAVE(MODERN_DOWNLOADPROGRESS) - PublishDownloadProgress(WebKit::DownloadID downloadID, URL url, std::span bookmarkData) -#endif #if PLATFORM(COCOA) && !HAVE(MODERN_DOWNLOADPROGRESS) PublishDownloadProgress(WebKit::DownloadID downloadID, URL url, WebKit::SandboxExtensionHandle sandboxExtensionHandle) #endif diff --git a/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h b/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h index 656ce1f8c9f7c..a16bb3462ce6e 100644 --- a/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h +++ b/Source/WebKit/Shared/API/Cocoa/WebKitPrivate.h @@ -23,6 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +#import #import #import #import diff --git a/Source/WebKit/UIProcess/API/APIDownloadClient.h b/Source/WebKit/UIProcess/API/APIDownloadClient.h index 36e1adcfaceda..f5a1b3b546dad 100644 --- a/Source/WebKit/UIProcess/API/APIDownloadClient.h +++ b/Source/WebKit/UIProcess/API/APIDownloadClient.h @@ -29,6 +29,7 @@ #include "AuthenticationChallengeProxy.h" #include "AuthenticationDecisionListener.h" #include "DownloadID.h" +#include "DownloadProxy.h" #include #include #include @@ -41,7 +42,6 @@ class ResourceResponse; namespace WebKit { class AuthenticationChallengeProxy; -class DownloadProxy; class WebsiteDataStore; class WebProtectionSpace; @@ -60,6 +60,9 @@ class DownloadClient : public RefCounted { virtual void legacyDidStart(WebKit::DownloadProxy&) { } virtual void didReceiveAuthenticationChallenge(WebKit::DownloadProxy&, WebKit::AuthenticationChallengeProxy& challenge) { challenge.listener().completeChallenge(WebKit::AuthenticationChallengeDisposition::Cancel); } virtual void didReceiveData(WebKit::DownloadProxy&, uint64_t, uint64_t, uint64_t) { } +#if HAVE(MODERN_DOWNLOADPROGRESS) + virtual void decidePlaceholderPolicy(WebKit::DownloadProxy&, CompletionHandler&& completionHandler) { completionHandler(WebKit::UseDownloadPlaceholder::No); } +#endif virtual void decideDestinationWithSuggestedFilename(WebKit::DownloadProxy&, const WebCore::ResourceResponse&, const WTF::String&, CompletionHandler&& completionHandler) { completionHandler(WebKit::AllowOverwrite::No, { }); } virtual void didCreateDestination(WebKit::DownloadProxy&, const WTF::String&) { } virtual void didFinish(WebKit::DownloadProxy&) { } diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm b/Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm index 9c459085069f2..f551a8048c882 100644 --- a/Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm +++ b/Source/WebKit/UIProcess/API/Cocoa/WKDownload.mm @@ -30,6 +30,7 @@ #import "CompletionHandlerCallChecker.h" #import "DownloadProxy.h" #import "WKDownloadDelegate.h" +#import "WKDownloadDelegatePrivate.h" #import "WKFrameInfoInternal.h" #import "WKNSData.h" #import "WKNSURLAuthenticationChallenge.h" @@ -41,12 +42,16 @@ class DownloadClient final : public API::DownloadClient { public: - explicit DownloadClient(id delegate) + explicit DownloadClient(id delegate) : m_delegate(delegate) , m_respondsToWillPerformHTTPRedirection([delegate respondsToSelector:@selector(download:willPerformHTTPRedirection:newRequest:decisionHandler:)]) , m_respondsToDidReceiveAuthenticationChallenge([delegate respondsToSelector:@selector(download:didReceiveAuthenticationChallenge:completionHandler:)]) , m_respondsToDidFinish([m_delegate respondsToSelector:@selector(downloadDidFinish:)]) , m_respondsToDidFailWithError([delegate respondsToSelector:@selector(download:didFailWithError:resumeData:)]) +#if HAVE(MODERN_DOWNLOADPROGRESS) + , m_respondsToDecidePlaceholderPolicy([delegate respondsToSelector:@selector(_download:decidePlaceholderPolicy:)]) +#endif + { ASSERT([delegate respondsToSelector:@selector(download:decideDestinationUsingResponse:suggestedFilename:completionHandler:)]); } @@ -142,6 +147,30 @@ void decideDestinationWithSuggestedFilename(WebKit::DownloadProxy& download, con }).get()]; } +#if HAVE(MODERN_DOWNLOADPROGRESS) + void decidePlaceholderPolicy(WebKit::DownloadProxy& download, CompletionHandler&& completionHandler) + { + if (!m_respondsToDecidePlaceholderPolicy) { + completionHandler(WebKit::UseDownloadPlaceholder::No); + return; + } + [m_delegate _download:wrapper(download) decidePlaceholderPolicy:makeBlockPtr([completionHandler = WTFMove(completionHandler)] (_WKPlaceholderPolicy policy) mutable { + switch (policy) { + case _WKPlaceholderPolicyDisable: { + completionHandler(WebKit::UseDownloadPlaceholder::No); + break; + } + case _WKPlaceholderPolicyEnable: { + completionHandler(WebKit::UseDownloadPlaceholder::Yes); + break; + } + default: + [NSException raise:NSInvalidArgumentException format:@"Invalid WKPlaceholderPolicy (%ld)", (long)policy]; + } + }).get()]; + } +#endif + void didReceiveData(WebKit::DownloadProxy& download, uint64_t, uint64_t totalBytesWritten, uint64_t totalBytesExpectedToWrite) final { NSProgress *progress = wrapper(download).progress; @@ -173,12 +202,15 @@ void processDidCrash(WebKit::DownloadProxy& download) final [m_delegate download:wrapper(download) didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorNetworkConnectionLost userInfo:nil] resumeData:nil]; } - WeakObjCPtr > m_delegate; + WeakObjCPtr> m_delegate; bool m_respondsToWillPerformHTTPRedirection : 1; bool m_respondsToDidReceiveAuthenticationChallenge : 1; bool m_respondsToDidFinish : 1; bool m_respondsToDidFailWithError : 1; +#if HAVE(MODERN_DOWNLOADPROGRESS) + bool m_respondsToDecidePlaceholderPolicy : 1; +#endif }; @implementation WKDownload @@ -219,7 +251,7 @@ - (WKFrameInfo *)originatingFrame return _delegate.get().get(); } -- (void)setDelegate:(id )delegate +- (void)setDelegate:(id)delegate { _delegate = delegate; _download->setClient(adoptRef(*new DownloadClient(delegate))); diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKDownloadDelegatePrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKDownloadDelegatePrivate.h new file mode 100644 index 0000000000000..79322c1b283e1 --- /dev/null +++ b/Source/WebKit/UIProcess/API/Cocoa/WKDownloadDelegatePrivate.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 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 +#import +#import + +@class WKDownload; + +/* @enum _WKPlaceholderPolicy + @abstract The policy for creating a placeholder file in the Downloads directory during downloads. + @constant _WKPlaceholderPolicyDisable Do not create a placeholder file. + @constant _WKPlaceholderPolicyEnable Create a placeholder file. + */ +typedef NS_ENUM(NSInteger, _WKPlaceholderPolicy) { + _WKPlaceholderPolicyDisable, + _WKPlaceholderPolicyEnable, +} NS_SWIFT_NAME(WKDownload.PlaceholderPolicy) WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); + +NS_ASSUME_NONNULL_BEGIN + +WK_SWIFT_UI_ACTOR +@protocol WKDownloadDelegatePrivate + +@optional + +/* @abstract Invoked when the download needs a placeholder policy from the client. + @param download The download for which we need a placeholder policy + @param completionHandler The completion handler that should be invoked with the chosen policy + @discussion The placeholder policy specifies whether a placeholder file should be created in + the Downloads directory when the download is in progress. + */ +- (void)_download:(WKDownload *)download decidePlaceholderPolicy:(void (^)(_WKPlaceholderPolicy))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm index 338348dfa061a..54c50c9a8cb9f 100644 --- a/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKDownload.mm @@ -79,7 +79,9 @@ - (void)cancel - (void)publishProgressAtURL:(NSURL *)URL { +#if !HAVE(MODERN_DOWNLOADPROGRESS) _download->_download->publishProgress(URL); +#endif } - (NSURLRequest *)request diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp index 4d2991f887d8e..17b0f4d068b10 100644 --- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp +++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp @@ -141,7 +141,7 @@ void DownloadProxy::didReceiveData(uint64_t bytesWritten, uint64_t totalBytesWri m_client->didReceiveData(*this, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); } -void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::ResourceResponse& response, String&& suggestedFilename, CompletionHandler&& completionHandler) +void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::ResourceResponse& response, String&& suggestedFilename, DecideDestinationCallback&& completionHandler) { RELEASE_LOG_INFO_IF(!response.expectedContentLength(), Network, "DownloadProxy::decideDestinationWithSuggestedFilename expectedContentLength is null"); @@ -161,12 +161,13 @@ void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::Resour } setDestinationFilename(destination); - completionHandler(destination, WTFMove(sandboxExtensionHandle), allowOverwrite); #if HAVE(MODERN_DOWNLOADPROGRESS) - bool shouldEnableModernDownloadProgress = CFPreferencesGetAppBooleanValue(CFSTR("EnableModernDownloadProgress"), CFSTR("com.apple.WebKit"), nullptr); - if (!destination.isEmpty() && shouldEnableModernDownloadProgress) - publishProgress(URL::fileURLWithFileSystemPath(destination)); + m_client->decidePlaceholderPolicy(*this, [completionHandler = WTFMove(completionHandler), destination = WTFMove(destination), sandboxExtensionHandle = WTFMove(sandboxExtensionHandle), allowOverwrite] (WebKit::UseDownloadPlaceholder usePlaceholder) mutable { + completionHandler(destination, WTFMove(sandboxExtensionHandle), allowOverwrite, usePlaceholder); + }); +#else + completionHandler(destination, WTFMove(sandboxExtensionHandle), allowOverwrite, WebKit::UseDownloadPlaceholder::No); #endif }); } diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h index 76852723ff17f..4c83db3523e25 100644 --- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h +++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h @@ -30,6 +30,7 @@ #include "DownloadID.h" #include "IdentifierTypes.h" #include "SandboxExtension.h" +#include "UseDownloadPlaceholder.h" #include #include #include @@ -63,6 +64,7 @@ struct FrameInfoData; class DownloadProxy : public API::ObjectImpl, public IPC::MessageReceiver { public: + using DecideDestinationCallback = CompletionHandler; template static Ref create(Args&&... args) { @@ -94,7 +96,11 @@ class DownloadProxy : public API::ObjectImpl, publi void setDestinationFilename(const String& d) { m_destinationFilename = d; } #if PLATFORM(COCOA) +#if HAVE(MODERN_DOWNLOADPROGRESS) + void publishProgress(const URL&, UseDownloadPlaceholder = UseDownloadPlaceholder::No); +#else void publishProgress(const URL&); +#endif void setProgress(NSProgress *progress) { m_progress = progress; } NSProgress *progress() const { return m_progress.get(); } #endif @@ -117,7 +123,7 @@ class DownloadProxy : public API::ObjectImpl, publi void didFinish(); void didFail(const WebCore::ResourceError&, std::span resumeData); void willSendRequest(WebCore::ResourceRequest&& redirectRequest, const WebCore::ResourceResponse& redirectResponse, CompletionHandler&&); - void decideDestinationWithSuggestedFilename(const WebCore::ResourceResponse&, String&& suggestedFilename, CompletionHandler&&); + void decideDestinationWithSuggestedFilename(const WebCore::ResourceResponse&, String&& suggestedFilename, DecideDestinationCallback&&); private: explicit DownloadProxy(DownloadProxyMap&, WebsiteDataStore&, API::DownloadClient&, const WebCore::ResourceRequest&, const FrameInfoData&, WebPageProxy*); diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.messages.in b/Source/WebKit/UIProcess/Downloads/DownloadProxy.messages.in index 24c73deb132cb..1d49b7f54ebc2 100644 --- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.messages.in +++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.messages.in @@ -24,8 +24,7 @@ messages -> DownloadProxy { DidStart(WebCore::ResourceRequest request, String suggestedFilename) DidReceiveAuthenticationChallenge(WebCore::AuthenticationChallenge challenge, WebKit::AuthenticationChallengeIdentifier challengeID) WillSendRequest(WebCore::ResourceRequest redirectRequest, WebCore::ResourceResponse redirectResponse) -> (WebCore::ResourceRequest newRequest) - DecideDestinationWithSuggestedFilename(WebCore::ResourceResponse response, String suggestedFilename) -> (String filename, WebKit::SandboxExtensionHandle handle, enum:bool WebKit::AllowOverwrite allowOverwrite) - + DecideDestinationWithSuggestedFilename(WebCore::ResourceResponse response, String suggestedFilename) -> (String filename, WebKit::SandboxExtensionHandle handle, enum:bool WebKit::AllowOverwrite allowOverwrite, enum:bool WebKit::UseDownloadPlaceholder useDownloadPlaceholder) DidReceiveData(uint64_t bytesWritten, uint64_t totalBytesWritten, uint64_t totalBytesExpectedToWrite) DidCreateDestination(String path) DidFinish() diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxyCocoa.mm b/Source/WebKit/UIProcess/Downloads/DownloadProxyCocoa.mm index 10aa7e757c25c..51dab2f911c9d 100644 --- a/Source/WebKit/UIProcess/Downloads/DownloadProxyCocoa.mm +++ b/Source/WebKit/UIProcess/Downloads/DownloadProxyCocoa.mm @@ -34,24 +34,19 @@ namespace WebKit { +#if !HAVE(MODERN_DOWNLOADPROGRESS) void DownloadProxy::publishProgress(const URL& url) { if (!m_dataStore) return; -#if HAVE(MODERN_DOWNLOADPROGRESS) - RetainPtr localURL = adoptNS([[NSURL alloc] initFileURLWithPath:url.fileSystemPath() relativeToURL:nil]); - NSError *error = nil; - RetainPtr bookmark = [localURL bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark includingResourceValuesForKeys:nil relativeToURL:nil error:&error]; - m_dataStore->networkProcess().send(Messages::NetworkProcess::PublishDownloadProgress(m_downloadID, url, span(bookmark.get())), 0); -#else auto handle = SandboxExtension::createHandle(url.fileSystemPath(), SandboxExtension::Type::ReadWrite); ASSERT(handle); if (!handle) return; m_dataStore->networkProcess().send(Messages::NetworkProcess::PublishDownloadProgress(m_downloadID, url, WTFMove(*handle)), 0); + } #endif -} } diff --git a/Source/WebKit/UIProcess/Downloads/UseDownloadPlaceholder.h b/Source/WebKit/UIProcess/Downloads/UseDownloadPlaceholder.h new file mode 100644 index 0000000000000..7e094e6f8e410 --- /dev/null +++ b/Source/WebKit/UIProcess/Downloads/UseDownloadPlaceholder.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 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. + */ + +#pragma once + +namespace WebKit { + +enum class UseDownloadPlaceholder : bool { + No, + Yes, +}; + +} // namespace WebKit diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj index 1c92e01f649d6..0135df0bdc786 100644 --- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj +++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj @@ -2438,8 +2438,10 @@ E31869C42B1A7C2400571519 /* WKProcessExtension.mm in Sources */ = {isa = PBXBuildFile; fileRef = E31869C22B1A7C2400571519 /* WKProcessExtension.mm */; }; E31869C52B1A7C2400571519 /* WKProcessExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = E31869C32B1A7C2400571519 /* WKProcessExtension.h */; }; E326E357284E580E00157372 /* AuxiliaryProcessProxyCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = E326E356284E580E00157372 /* AuxiliaryProcessProxyCocoa.mm */; }; + E33E8FFD2C7FD2980002BEB3 /* UseDownloadPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = E33E8FFC2C7FD2980002BEB3 /* UseDownloadPlaceholder.h */; }; E34DAD392B753FA700FABEE2 /* ExtensionProcess.mm in Sources */ = {isa = PBXBuildFile; fileRef = E34DAD372B753FA700FABEE2 /* ExtensionProcess.mm */; }; E34DAD3A2B753FA700FABEE2 /* ExtensionProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = E34DAD382B753FA700FABEE2 /* ExtensionProcess.h */; }; + E3607DEA2C7FE92200956766 /* WKDownloadDelegatePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = E3607DE92C7FE92200956766 /* WKDownloadDelegatePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; E36A00E329CF7AC000AC4E8A /* TextTrackRepresentationCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = E36A00E229CF7AC000AC4E8A /* TextTrackRepresentationCocoa.mm */; }; E36FF00327F36FBD004BE21A /* SandboxStateVariables.h in Headers */ = {isa = PBXBuildFile; fileRef = E36FF00127F36FBD004BE21A /* SandboxStateVariables.h */; }; E3816B3D27E2463A005EAFC0 /* WebMockContentFilterManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3816B3B27E24639005EAFC0 /* WebMockContentFilterManager.cpp */; }; @@ -7979,6 +7981,7 @@ E31869C22B1A7C2400571519 /* WKProcessExtension.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKProcessExtension.mm; sourceTree = ""; }; E31869C32B1A7C2400571519 /* WKProcessExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKProcessExtension.h; sourceTree = ""; }; E326E356284E580E00157372 /* AuxiliaryProcessProxyCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AuxiliaryProcessProxyCocoa.mm; sourceTree = ""; }; + E33E8FFC2C7FD2980002BEB3 /* UseDownloadPlaceholder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UseDownloadPlaceholder.h; sourceTree = ""; }; E3439B632345463A0011DE0B /* NetworkProcessConnectionInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NetworkProcessConnectionInfo.h; path = Network/NetworkProcessConnectionInfo.h; sourceTree = ""; }; E34B110C27C46BC6006D2F2E /* libWebCoreTestShim.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libWebCoreTestShim.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; E34B110F27C46D09006D2F2E /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -7987,6 +7990,7 @@ E350A7C52934F1C100A06C29 /* common.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = common.sb; sourceTree = ""; }; E350A7C82934F75F00A06C29 /* common.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = common.sb; sourceTree = ""; }; E350A7DF29364D3800A06C29 /* util.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = util.sb; sourceTree = ""; }; + E3607DE92C7FE92200956766 /* WKDownloadDelegatePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKDownloadDelegatePrivate.h; sourceTree = ""; }; E36A00E129CF4EBA00AC4E8A /* TextTrackRepresentationCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextTrackRepresentationCocoa.h; sourceTree = ""; }; E36A00E229CF7AC000AC4E8A /* TextTrackRepresentationCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TextTrackRepresentationCocoa.mm; sourceTree = ""; }; E36D701A27B709ED006531B7 /* WebAttachmentElementClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebAttachmentElementClient.h; sourceTree = ""; }; @@ -9493,6 +9497,7 @@ E382D57E2C21D500005F7653 /* DownloadProxyCocoa.mm */, 1AD25E93167AB08100EA9BCD /* DownloadProxyMap.cpp */, 1AD25E94167AB08100EA9BCD /* DownloadProxyMap.h */, + E33E8FFC2C7FD2980002BEB3 /* UseDownloadPlaceholder.h */, ); path = Downloads; sourceTree = ""; @@ -11585,6 +11590,7 @@ DF0C5F24252ECB8D00D921DB /* WKDownload.h */, DF0C5F23252ECB8D00D921DB /* WKDownload.mm */, DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */, + E3607DE92C7FE92200956766 /* WKDownloadDelegatePrivate.h */, DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */, 1AF4592D19464B2000F9D4A2 /* WKError.h */, 1AF4592C19464B2000F9D4A2 /* WKError.mm */, @@ -16820,6 +16826,7 @@ 93D1EEF529669D74009B31D6 /* UnifiedOriginStorageLevel.h in Headers */, 1A64245E12DE29A100CAAE2C /* UpdateInfo.h in Headers */, 5C19A5201FD0B29500EEA323 /* URLSchemeTaskParameters.h in Headers */, + E33E8FFD2C7FD2980002BEB3 /* UseDownloadPlaceholder.h in Headers */, 1AC1336818565B5700F3EC05 /* UserData.h in Headers */, CD491B081E70D05F00009066 /* UserMediaCaptureManager.h in Headers */, CD491B0E1E732E4D00009066 /* UserMediaCaptureManagerMessages.h in Headers */, @@ -17327,6 +17334,7 @@ DF0C5F28252ECB8E00D921DB /* WKDownload.h in Headers */, 5C2EBDFA2564380B00D55B05 /* WKDownloadClient.h in Headers */, DF0C5F2A252ECB8E00D921DB /* WKDownloadDelegate.h in Headers */, + E3607DEA2C7FE92200956766 /* WKDownloadDelegatePrivate.h in Headers */, DF0C5F2B252ED44000D921DB /* WKDownloadInternal.h in Headers */, 637281A221ADC744009E0DE6 /* WKDownloadProgress.h in Headers */, 1AB7D78D1288CD9A00CFD08C /* WKDownloadRef.h in Headers */, diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/Download.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/Download.mm index aa4c63ac0a6e9..84f4f8a0692e2 100644 --- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/Download.mm +++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/Download.mm @@ -2247,6 +2247,39 @@ HTTPServer server({ }); } +#if HAVE(MODERN_DOWNLOADPROGRESS) +TEST(WKDownload, DecidePlaceholderPolicy) +{ + HTTPServer server({ + { "/"_s, { 404, { }, "http body"_s } } + }); + NSURL *expectedDownloadFile = tempFileThatDoesNotExist(); + auto delegate = adoptNS([TestDownloadDelegate new]); + auto webView = adoptNS([WKWebView new]); + [webView setNavigationDelegate:delegate.get()]; + + __block bool didFinish = false; + [webView startDownloadUsingRequest:server.request() completionHandler:^(WKDownload *download) { + download.delegate = delegate.get(); + delegate.get().decideDestinationUsingResponse = ^(WKDownload *, NSURLResponse *, NSString *, void (^completionHandler)(NSURL *)) { + completionHandler(expectedDownloadFile); + }; + delegate.get().downloadDidFinish = ^(WKDownload *download) { + didFinish = true; + }; + }]; + Util::run(&didFinish); + + checkFileContents(expectedDownloadFile, "http body"_s); + + checkCallbackRecord(delegate.get(), { + DownloadCallback::DecideDestination, + DownloadCallback::DecidePlaceholderPolicy, + DownloadCallback::DidFinish, + }); +} +#endif + TEST(WKDownload, NetworkProcessCrash) { auto server = downloadTestServer(); diff --git a/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.h b/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.h index 37a6598589fd1..184f5f700523d 100644 --- a/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.h +++ b/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.h @@ -23,12 +23,16 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +#import #import enum class DownloadCallback : uint8_t { WillRedirect, AuthenticationChallenge, DecideDestination, +#if HAVE(MODERN_DOWNLOADPROGRESS) + DecidePlaceholderPolicy, +#endif DidFinish, DidFailWithError, NavigationActionBecameDownload, @@ -37,7 +41,7 @@ enum class DownloadCallback : uint8_t { NavigationResponse, }; -@interface TestDownloadDelegate : NSObject +@interface TestDownloadDelegate : NSObject @property (nonatomic, copy) void (^willPerformHTTPRedirection)(WKDownload *, NSHTTPURLResponse *, NSURLRequest *, void (^)(WKDownloadRedirectPolicy)); @property (nonatomic, copy) void (^didReceiveAuthenticationChallenge)(WKDownload *, NSURLAuthenticationChallenge *, void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential*)); diff --git a/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.mm b/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.mm index 783cae42321f4..6b75be5b1ec03 100644 --- a/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.mm +++ b/Tools/TestWebKitAPI/cocoa/TestDownloadDelegate.mm @@ -58,6 +58,14 @@ - (void)download:(WKDownload *)download didReceiveAuthenticationChallenge:(NSURL completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } +#if HAVE(MODERN_DOWNLOADPROGRESS) +- (void)_download:(WKDownload *)download decidePlaceholderPolicy:(void (^)(_WKPlaceholderPolicy))completionHandler +{ + _callbackRecord.append(DownloadCallback::DecidePlaceholderPolicy); + completionHandler(_WKPlaceholderPolicyDisable); +} +#endif + - (void)downloadDidFinish:(WKDownload *)download { _callbackRecord.append(DownloadCallback::DidFinish);