Title: [295318] branches/safari-613-branch
Revision
295318
Author
[email protected]
Date
2022-06-06 19:30:17 -0700 (Mon, 06 Jun 2022)

Log Message

Cherry-pick 8a2d5954643f. rdar://problem/94467773

    Calls to print can result in unresponsive print modal
    https://bugs.webkit.org/show_bug.cgi?id=237940
    <rdar://problem/88257828>

    Reviewed by Chris Dumez.

    Source/WebKit:

    Calls to print were hanging in the case of the client asynchronously
    handling the completion handler passed to the delegate. To fix this
    we can adjust all printing IPC to have the option
    DispatchMessageEvenWhenWaitingForUnboundedSyncReply which allows IPC
    messages when waiting for a sync reply in the case where the receiver
    of the message is not guranteed to call the completion handler at the
    end of the runloop.

    * UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
    * UIProcess/API/Cocoa/WKWebViewTesting.mm:
    (-[WKWebView _computePagesForPrinting:completionHandler:]):
    * UIProcess/WebPageProxy.cpp:
    (WebKit::printingSendOptions):
    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
    (WebKit::WebChromeClient::print):

    Tools:

    Add API test. Adjust delegate naming in the PDF case to be more
    specific so we can use the generic PrintUIDelegate name in the general
    case.

    * TestWebKitAPI/SourcesCocoa.txt:
    * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
    * TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm:
    (TEST):
    (-[PrintUIDelegate _webView:printFrame:pdfFirstPageSize:completionHandler:]): Deleted.
    (-[PrintUIDelegate waitForPageSize]): Deleted.
    (-[PrintUIDelegate lastPrintedFrame]): Deleted.
    * TestWebKitAPI/Tests/WebKitCocoa/WKPrinting.mm: Added.
    (-[PrintUIDelegate callBlockAsync:]):
    (-[PrintUIDelegate _webView:printFrame:pdfFirstPageSize:completionHandler:]):
    (-[PrintUIDelegate waitForPagination]):
    (TEST):

    Canonical link: https://commits.webkit.org/248540@main
    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291412 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-613-branch/Source/WebKit/ChangeLog (295317 => 295318)


--- branches/safari-613-branch/Source/WebKit/ChangeLog	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Source/WebKit/ChangeLog	2022-06-07 02:30:17 UTC (rev 295318)
@@ -1,3 +1,27 @@
+2022-03-17  Kate Cheney  <[email protected]>
+
+        Calls to print can result in unresponsive print modal
+        https://bugs.webkit.org/show_bug.cgi?id=237940
+        <rdar://problem/88257828>
+
+        Reviewed by Chris Dumez.
+
+        Calls to print were hanging in the case of the client asynchronously
+        handling the completion handler passed to the delegate. To fix this
+        we can adjust all printing IPC to have the option
+        DispatchMessageEvenWhenWaitingForUnboundedSyncReply which allows IPC
+        messages when waiting for a sync reply in the case where the receiver
+        of the message is not guranteed to call the completion handler at the
+        end of the runloop.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
+        * UIProcess/API/Cocoa/WKWebViewTesting.mm:
+        (-[WKWebView _computePagesForPrinting:completionHandler:]):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::printingSendOptions):
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::print):
+
 2022-04-14  Wenson Hsieh  <[email protected]>
 
         Unreviewed, fix the Catalyst build after r292888

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h (295317 => 295318)


--- branches/safari-613-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2022-06-07 02:30:17 UTC (rev 295318)
@@ -118,6 +118,8 @@
 
 - (void)_isLayerTreeFrozenForTesting:(void (^)(BOOL frozen))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
+- (void)_computePagesForPrinting:(_WKFrameHandle *)handle completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 @end
 
 typedef NS_ENUM(NSInteger, _WKMediaSessionReadyState) {

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm (295317 => 295318)


--- branches/safari-613-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2022-06-07 02:30:17 UTC (rev 295318)
@@ -30,6 +30,7 @@
 #import "GPUProcessProxy.h"
 #import "MediaSessionCoordinatorProxyPrivate.h"
 #import "PlaybackSessionManagerProxy.h"
+#import "PrintInfo.h"
 #import "UserMediaProcessManager.h"
 #import "ViewGestureController.h"
 #import "WebPageProxy.h"
@@ -431,6 +432,14 @@
     });
 }
 
+- (void)_computePagesForPrinting:(_WKFrameHandle *)handle completionHandler:(void(^)(void))completionHandler
+{
+    WebKit::PrintInfo printInfo;
+    _page->computePagesForPrinting(handle->_frameHandle->frameID(), printInfo, [completionHandler = makeBlockPtr(completionHandler)] (const Vector<WebCore::IntRect>&, double, const WebCore::FloatBoxExtent&) {
+        completionHandler();
+    });
+}
+
 - (void)_gpuToWebProcessConnectionCountForTesting:(void(^)(NSUInteger))completionHandler
 {
     RefPtr gpuProcess = _page->process().processPool().gpuProcess();

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h (295317 => 295318)


--- branches/safari-613-branch/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h	2022-06-07 02:30:17 UTC (rev 295318)
@@ -25,6 +25,7 @@
 
 #import <WebKit/WKWebView.h>
 #import <WebKit/_WKElementAction.h>
+#import <WebKit/_WKFrameHandle.h>
 #import <WebKit/_WKTapHandlingResult.h>
 
 #if TARGET_OS_IPHONE

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.cpp (295317 => 295318)


--- branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-06-07 02:30:17 UTC (rev 295318)
@@ -4496,7 +4496,7 @@
 static OptionSet<IPC::SendOption> printingSendOptions(bool isPerformingDOMPrintOperation)
 {
     if (isPerformingDOMPrintOperation)
-        return IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply;
+        return IPC::SendOption::DispatchMessageEvenWhenWaitingForUnboundedSyncReply;
 
     return { };
 }

Modified: branches/safari-613-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (295317 => 295318)


--- branches/safari-613-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2022-06-07 02:30:17 UTC (rev 295318)
@@ -759,6 +759,8 @@
 #endif
 
     auto truncatedTitle = truncateFromEnd(title, maxTitleLength);
+
+    IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
     m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::PrintFrame(webFrame->frameID(), truncatedTitle.string, pdfFirstPageSize), Messages::WebPageProxy::PrintFrame::Reply());
 }
 

Modified: branches/safari-613-branch/Tools/ChangeLog (295317 => 295318)


--- branches/safari-613-branch/Tools/ChangeLog	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Tools/ChangeLog	2022-06-07 02:30:17 UTC (rev 295318)
@@ -1,3 +1,28 @@
+2022-03-17  Kate Cheney  <[email protected]>
+
+        Calls to print can result in unresponsive print modal
+        https://bugs.webkit.org/show_bug.cgi?id=237940
+        <rdar://problem/88257828>
+
+        Reviewed by Chris Dumez.
+
+        Add API test. Adjust delegate naming in the PDF case to be more
+        specific so we can use the generic PrintUIDelegate name in the general
+        case.
+
+        * TestWebKitAPI/SourcesCocoa.txt:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm:
+        (TEST):
+        (-[PrintUIDelegate _webView:printFrame:pdfFirstPageSize:completionHandler:]): Deleted.
+        (-[PrintUIDelegate waitForPageSize]): Deleted.
+        (-[PrintUIDelegate lastPrintedFrame]): Deleted.
+        * TestWebKitAPI/Tests/WebKitCocoa/WKPrinting.mm: Added.
+        (-[PrintUIDelegate callBlockAsync:]):
+        (-[PrintUIDelegate _webView:printFrame:pdfFirstPageSize:completionHandler:]):
+        (-[PrintUIDelegate waitForPagination]):
+        (TEST):
+
 2022-04-14  Wenson Hsieh  <[email protected]>
 
         [iOS] [WK2] Managed pasteboard should function for all managed domains

Modified: branches/safari-613-branch/Tools/TestWebKitAPI/SourcesCocoa.txt (295317 => 295318)


--- branches/safari-613-branch/Tools/TestWebKitAPI/SourcesCocoa.txt	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Tools/TestWebKitAPI/SourcesCocoa.txt	2022-06-07 02:30:17 UTC (rev 295318)
@@ -265,6 +265,7 @@
 Tests/WebKitCocoa/WKNavigationResponse.mm
 Tests/WebKitCocoa/WKObject.mm
 Tests/WebKitCocoa/WKPDFView.mm
+Tests/WebKitCocoa/WKPrinting.mm
 Tests/WebKitCocoa/WKProcessPoolConfiguration.mm
 Tests/WebKitCocoa/WKRequestActivatedElementInfo.mm
 Tests/WebKitCocoa/WKURLSchemeHandler-1.mm

Modified: branches/safari-613-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (295317 => 295318)


--- branches/safari-613-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2022-06-07 02:30:17 UTC (rev 295318)
@@ -2008,6 +2008,7 @@
 		4995A6EF25E876A300E5F0A9 /* csp-document-uri-report.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "csp-document-uri-report.html"; sourceTree = "<group>"; };
 		49AEEF682407276F00C87E4C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		49AEEF6B2407358600C87E4C /* InAppBrowserPrivacy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InAppBrowserPrivacy.mm; sourceTree = "<group>"; };
+		49CB61AF27E17E4D0017078E /* WKPrinting.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKPrinting.mm; sourceTree = "<group>"; };
 		49D2E5C12731E37400BCCAED /* file-with-iframe.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "file-with-iframe.html"; sourceTree = "<group>"; };
 		49D7FBA7241FDDDA00AB67FA /* in-app-browser-privacy-local-file.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "in-app-browser-privacy-local-file.html"; sourceTree = "<group>"; };
 		49EF6AD42677C0BE007967DC /* AppPrivacyReport.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AppPrivacyReport.mm; sourceTree = "<group>"; };
@@ -3645,6 +3646,7 @@
 				375E0E151D66674400EFEC2C /* WKNSNumber.mm */,
 				37B47E2E1D64E7CA005F4EFF /* WKObject.mm */,
 				2D00065D1C1F58940088E6A7 /* WKPDFView.mm */,
+				49CB61AC27E145B40017078E /* WKPrinting.mm */,
 				3781746C2198AE2400062C26 /* WKProcessPoolConfiguration.mm */,
 				44817A2E1F0486BF00003810 /* WKRequestActivatedElementInfo.mm */,
 				5E4B1D2C1D404C6100053621 /* WKScrollViewDelegate.mm */,

Modified: branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm (295317 => 295318)


--- branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm	2022-06-07 02:30:12 UTC (rev 295317)
+++ branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm	2022-06-07 02:30:17 UTC (rev 295318)
@@ -376,7 +376,7 @@
 
 #if PLATFORM(MAC)
 
-@interface PrintUIDelegate : NSObject <WKUIDelegate>
+@interface PDFPrintUIDelegate : NSObject <WKUIDelegate>
 
 - (NSSize)waitForPageSize;
 - (_WKFrameHandle *)lastPrintedFrame;
@@ -383,7 +383,7 @@
 
 @end
 
-@implementation PrintUIDelegate {
+@implementation PDFPrintUIDelegate {
     NSSize _pageSize;
     bool _receivedSize;
     RetainPtr<_WKFrameHandle> _lastPrintedFrame;
@@ -418,7 +418,7 @@
     auto schemeHandler = adoptNS([TestURLSchemeHandler new]);
     [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"test"];
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
-    auto delegate = adoptNS([PrintUIDelegate new]);
+    auto delegate = adoptNS([PDFPrintUIDelegate new]);
     [webView setUIDelegate:delegate.get()];
 
     schemeHandler.get().startURLSchemeTaskHandler = ^(WKWebView *, id<WKURLSchemeTask> task) {

Added: branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPrinting.mm (0 => 295318)


--- branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPrinting.mm	                        (rev 0)
+++ branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPrinting.mm	2022-06-07 02:30:17 UTC (rev 295318)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 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"
+
+typedef void (^CallCompletionBlock)();
+
+@interface PrintUIDelegate : NSObject <WKUIDelegate>
+
+- (void)waitForPagination;
+
+@end
+
+@implementation PrintUIDelegate {
+    bool _isDone;
+}
+
+- (void)callBlockAsync:(CallCompletionBlock)callCompletionBlock
+{
+    dispatch_async(dispatch_get_main_queue(), ^{
+        callCompletionBlock();
+    });
+}
+
+- (void)_webView:(WKWebView *)webView printFrame:(_WKFrameHandle *)frame pdfFirstPageSize:(CGSize)size completionHandler:(void (^)(void))completionHandler
+{
+    _isDone = false;
+    CallCompletionBlock callCompletionBlock = ^{
+        [webView _computePagesForPrinting:frame completionHandler:^{
+            _isDone = true;
+            completionHandler();
+        }];
+    };
+
+    // Dispatch the completion handler asynchronously to ensure we don't block IPC in the web process in the unbounded sync IPC case.
+    [self callBlockAsync:callCompletionBlock];
+}
+
+- (void)waitForPagination
+{
+    TestWebKitAPI::Util::run(&_isDone);
+}
+
+@end
+
+TEST(Printing, PrintWithDelayedCompletion)
+{
+    auto configuration = adoptNS([WKWebViewConfiguration new]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto delegate = adoptNS([PrintUIDelegate new]);
+    [webView setUIDelegate:delegate.get()];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+    [webView _test_waitForDidFinishNavigation];
+
+    [webView evaluateJavaScript:@"window.print()" completionHandler:nil];
+    [delegate waitForPagination];
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to