Title: [279376] branches/safari-612.1.21-branch
Revision
279376
Author
[email protected]
Date
2021-06-29 11:00:06 -0700 (Tue, 29 Jun 2021)

Log Message

Cherry-pick r279361. rdar://problem/79923766

    REGRESSION (r279310): Occasional crash when focusing login fields on iPad with a software keyboard
    https://bugs.webkit.org/show_bug.cgi?id=227472
    rdar://79876040

    Reviewed by Tim Horton.

    Source/WebKit:

    I added a mechanism in r279310 to defer calling `-[WKContentView _setSuppressSoftwareKeyboard:NO]` until we've
    gotten a response from the web process containing an up-to-date autocorrection context. However, in the case
    where the WKWebView client sets `_suppressSoftwareKeyboard` to `YES` and then immediately to `NO` underneath the
    scope of a call to `-_webView:willStartInputSession:`, we'll end up calling into `-_setSuppressSoftwareKeyboard:`
    inside the scope of `-requestAutocorrectionContextWithCompletionHandler:`, when we've received an
    autocorrection context while sync-waiting. This is problematic because it breaks UIKeyboardTaskQueue's state,
    since the call to `-_setSuppressSoftwareKeyboard:` will attempt to enqueue a new task after the previous task's
    context has already returned execution to the parent.

    To fix this, we instead invoke `self._suppressSoftwareKeyboard = NO;` *before* calling the completion block in
    `-_handleAutocorrectionContext:`. This allows the request for an autocorrection context underneath
    `-_setSuppressSoftwareKeyboard:` to be handled (and completed) as a child task of the previous task, which keeps
    UIKeyboardTaskQueue in a valid state.

    Test: fast/forms/ios/suppress-software-keyboard-while-focusing-input.html

    * UIProcess/ios/WKContentViewInteraction.mm:
    (-[WKContentView _handleAutocorrectionContext:]):

    Tools:

    Make it possible to induce the crash (prior to the fix) by introducing two new testing primitives on iOS:

    -   `UIScriptController.suppressSoftwareKeyboard`, a readwrite attribute that can be used to suppress the
        appearance of the software keyboard on iOS by calling `-[WKWebView _setSuppressSoftwareKeyboard:]`.

    -   `UIScriptController.willStartInputSessionCallback`, a callback that is invoked when we're about to start a
        UI-process-side input session. On iOS, this corresponds to
        `-[_WKInputDelegate _webView:willStartInputSession:`].

    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
    * TestRunnerShared/UIScriptContext/UIScriptContext.h:
    * TestRunnerShared/UIScriptContext/UIScriptController.h:
    (WTR::UIScriptController::suppressSoftwareKeyboard const):
    (WTR::UIScriptController::setSuppressSoftwareKeyboard):
    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
    (WTR::UIScriptController::setWillStartInputSessionCallback):
    (WTR::UIScriptController::willStartInputSessionCallback const):
    * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
    * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
    (-[TestRunnerWKWebView initWithFrame:configuration:]):
    (-[TestRunnerWKWebView resetInteractionCallbacks]):
    (-[TestRunnerWKWebView _webView:willStartInputSession:]):
    * WebKitTestRunner/ios/TestControllerIOS.mm:
    (WTR::TestController::platformResetStateToConsistentValues):

    Make sure that we revert `_suppressSoftwareKeyboard` to `NO`, in case a layout test ends while leaving this on,
    to prevent subsequent layout tests from behaving in unexpected ways.

    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
    (WTR::UIScriptControllerIOS::setWillStartInputSessionCallback):
    (WTR::UIScriptControllerIOS::suppressSoftwareKeyboard const):
    (WTR::UIScriptControllerIOS::setSuppressSoftwareKeyboard):

    LayoutTests:

    Add a new layout test to exercise the crash. See Tools and Source/WebKit ChangeLogs for more information.
    This new test suppresses and then immediately un-suppresses the software keyboard inside the
    `-_webView:willStartInputSession:` input delegate hook while focusing a regular text field.

    * fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt: Added.
    * fast/forms/ios/suppress-software-keyboard-while-focusing-input.html: Added.

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-612.1.21-branch/LayoutTests/ChangeLog (279375 => 279376)


--- branches/safari-612.1.21-branch/LayoutTests/ChangeLog	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/LayoutTests/ChangeLog	2021-06-29 18:00:06 UTC (rev 279376)
@@ -1,3 +1,97 @@
+2021-06-29  Alan Coon  <[email protected]>
+
+        Cherry-pick r279361. rdar://problem/79923766
+
+    REGRESSION (r279310): Occasional crash when focusing login fields on iPad with a software keyboard
+    https://bugs.webkit.org/show_bug.cgi?id=227472
+    rdar://79876040
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebKit:
+    
+    I added a mechanism in r279310 to defer calling `-[WKContentView _setSuppressSoftwareKeyboard:NO]` until we've
+    gotten a response from the web process containing an up-to-date autocorrection context. However, in the case
+    where the WKWebView client sets `_suppressSoftwareKeyboard` to `YES` and then immediately to `NO` underneath the
+    scope of a call to `-_webView:willStartInputSession:`, we'll end up calling into `-_setSuppressSoftwareKeyboard:`
+    inside the scope of `-requestAutocorrectionContextWithCompletionHandler:`, when we've received an
+    autocorrection context while sync-waiting. This is problematic because it breaks UIKeyboardTaskQueue's state,
+    since the call to `-_setSuppressSoftwareKeyboard:` will attempt to enqueue a new task after the previous task's
+    context has already returned execution to the parent.
+    
+    To fix this, we instead invoke `self._suppressSoftwareKeyboard = NO;` *before* calling the completion block in
+    `-_handleAutocorrectionContext:`. This allows the request for an autocorrection context underneath
+    `-_setSuppressSoftwareKeyboard:` to be handled (and completed) as a child task of the previous task, which keeps
+    UIKeyboardTaskQueue in a valid state.
+    
+    Test: fast/forms/ios/suppress-software-keyboard-while-focusing-input.html
+    
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView _handleAutocorrectionContext:]):
+    
+    Tools:
+    
+    Make it possible to induce the crash (prior to the fix) by introducing two new testing primitives on iOS:
+    
+    -   `UIScriptController.suppressSoftwareKeyboard`, a readwrite attribute that can be used to suppress the
+        appearance of the software keyboard on iOS by calling `-[WKWebView _setSuppressSoftwareKeyboard:]`.
+    
+    -   `UIScriptController.willStartInputSessionCallback`, a callback that is invoked when we're about to start a
+        UI-process-side input session. On iOS, this corresponds to
+        `-[_WKInputDelegate _webView:willStartInputSession:`].
+    
+    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+    * TestRunnerShared/UIScriptContext/UIScriptContext.h:
+    * TestRunnerShared/UIScriptContext/UIScriptController.h:
+    (WTR::UIScriptController::suppressSoftwareKeyboard const):
+    (WTR::UIScriptController::setSuppressSoftwareKeyboard):
+    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+    (WTR::UIScriptController::setWillStartInputSessionCallback):
+    (WTR::UIScriptController::willStartInputSessionCallback const):
+    * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
+    * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+    (-[TestRunnerWKWebView initWithFrame:configuration:]):
+    (-[TestRunnerWKWebView resetInteractionCallbacks]):
+    (-[TestRunnerWKWebView _webView:willStartInputSession:]):
+    * WebKitTestRunner/ios/TestControllerIOS.mm:
+    (WTR::TestController::platformResetStateToConsistentValues):
+    
+    Make sure that we revert `_suppressSoftwareKeyboard` to `NO`, in case a layout test ends while leaving this on,
+    to prevent subsequent layout tests from behaving in unexpected ways.
+    
+    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+    (WTR::UIScriptControllerIOS::setWillStartInputSessionCallback):
+    (WTR::UIScriptControllerIOS::suppressSoftwareKeyboard const):
+    (WTR::UIScriptControllerIOS::setSuppressSoftwareKeyboard):
+    
+    LayoutTests:
+    
+    Add a new layout test to exercise the crash. See Tools and Source/WebKit ChangeLogs for more information.
+    This new test suppresses and then immediately un-suppresses the software keyboard inside the
+    `-_webView:willStartInputSession:` input delegate hook while focusing a regular text field.
+    
+    * fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt: Added.
+    * fast/forms/ios/suppress-software-keyboard-while-focusing-input.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279361 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-06-28  Wenson Hsieh  <[email protected]>
+
+            REGRESSION (r279310): Occasional crash when focusing login fields on iPad with a software keyboard
+            https://bugs.webkit.org/show_bug.cgi?id=227472
+            rdar://79876040
+
+            Reviewed by Tim Horton.
+
+            Add a new layout test to exercise the crash. See Tools and Source/WebKit ChangeLogs for more information.
+            This new test suppresses and then immediately un-suppresses the software keyboard inside the
+            `-_webView:willStartInputSession:` input delegate hook while focusing a regular text field.
+
+            * fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt: Added.
+            * fast/forms/ios/suppress-software-keyboard-while-focusing-input.html: Added.
+
 2021-06-27  Alan Bujtas  <[email protected]>
 
         [LFC][TFC] Add support for shrinking over-constrained columns based on the width type priority list

Added: branches/safari-612.1.21-branch/LayoutTests/fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt (0 => 279376)


--- branches/safari-612.1.21-branch/LayoutTests/fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt	                        (rev 0)
+++ branches/safari-612.1.21-branch/LayoutTests/fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt	2021-06-29 18:00:06 UTC (rev 279376)
@@ -0,0 +1,9 @@
+
+This test verifies that temporarily suppressing the software keyboard while focusing an input field does not crash the UI process. This test requires WebKitTestRunner.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/safari-612.1.21-branch/LayoutTests/fast/forms/ios/suppress-software-keyboard-while-focusing-input.html (0 => 279376)


--- branches/safari-612.1.21-branch/LayoutTests/fast/forms/ios/suppress-software-keyboard-while-focusing-input.html	                        (rev 0)
+++ branches/safari-612.1.21-branch/LayoutTests/fast/forms/ios/suppress-software-keyboard-while-focusing-input.html	2021-06-29 18:00:06 UTC (rev 279376)
@@ -0,0 +1,63 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<script src=""
+<script src=""
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+html, body {
+    margin: 0;
+    width: 100%;
+    height: 100%;
+}
+
+input {
+    width: 100%;
+    font-size: 100px;
+    display: block;
+}
+</style>
+</head>
+<body>
+<input></input>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("This test verifies that temporarily suppressing the software keyboard while focusing an input field does not crash the UI process. This test requires WebKitTestRunner.");
+
+jsTestIsAsync = true;
+addEventListener("load", async () => {
+    if (!window.testRunner)
+        return;
+
+    await UIHelper.setHardwareKeyboardAttached(false);
+
+    let input = document.querySelector("input");
+    const x = input.offsetLeft + input.offsetWidth / 2;
+    const y = input.offsetTop + input.offsetHeight / 2;
+
+    await new Promise(resolve => {
+        testRunner.runUIScript(`
+            (function() {
+                uiController.willStartInputSessionCallback = () => {
+                    uiController.suppressSoftwareKeyboard = true;
+                    uiController.suppressSoftwareKeyboard = false;
+                };
+
+                uiController.didShowKeyboardCallback = () => {
+                    uiController.didShowKeyboardCallback = null;
+                    uiController.willStartInputSessionCallback = null;
+                    uiController.uiScriptComplete();
+                };
+
+                uiController.singleTapAtPoint(${x}, ${y}, () => { });
+            })()`, resolve);
+    });
+
+    input.blur();
+    await UIHelper.waitForKeyboardToHide();
+    finishJSTest();
+});
+</script>
+</body>
+</html>

Modified: branches/safari-612.1.21-branch/Source/WebKit/ChangeLog (279375 => 279376)


--- branches/safari-612.1.21-branch/Source/WebKit/ChangeLog	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Source/WebKit/ChangeLog	2021-06-29 18:00:06 UTC (rev 279376)
@@ -1,3 +1,109 @@
+2021-06-29  Alan Coon  <[email protected]>
+
+        Cherry-pick r279361. rdar://problem/79923766
+
+    REGRESSION (r279310): Occasional crash when focusing login fields on iPad with a software keyboard
+    https://bugs.webkit.org/show_bug.cgi?id=227472
+    rdar://79876040
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebKit:
+    
+    I added a mechanism in r279310 to defer calling `-[WKContentView _setSuppressSoftwareKeyboard:NO]` until we've
+    gotten a response from the web process containing an up-to-date autocorrection context. However, in the case
+    where the WKWebView client sets `_suppressSoftwareKeyboard` to `YES` and then immediately to `NO` underneath the
+    scope of a call to `-_webView:willStartInputSession:`, we'll end up calling into `-_setSuppressSoftwareKeyboard:`
+    inside the scope of `-requestAutocorrectionContextWithCompletionHandler:`, when we've received an
+    autocorrection context while sync-waiting. This is problematic because it breaks UIKeyboardTaskQueue's state,
+    since the call to `-_setSuppressSoftwareKeyboard:` will attempt to enqueue a new task after the previous task's
+    context has already returned execution to the parent.
+    
+    To fix this, we instead invoke `self._suppressSoftwareKeyboard = NO;` *before* calling the completion block in
+    `-_handleAutocorrectionContext:`. This allows the request for an autocorrection context underneath
+    `-_setSuppressSoftwareKeyboard:` to be handled (and completed) as a child task of the previous task, which keeps
+    UIKeyboardTaskQueue in a valid state.
+    
+    Test: fast/forms/ios/suppress-software-keyboard-while-focusing-input.html
+    
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView _handleAutocorrectionContext:]):
+    
+    Tools:
+    
+    Make it possible to induce the crash (prior to the fix) by introducing two new testing primitives on iOS:
+    
+    -   `UIScriptController.suppressSoftwareKeyboard`, a readwrite attribute that can be used to suppress the
+        appearance of the software keyboard on iOS by calling `-[WKWebView _setSuppressSoftwareKeyboard:]`.
+    
+    -   `UIScriptController.willStartInputSessionCallback`, a callback that is invoked when we're about to start a
+        UI-process-side input session. On iOS, this corresponds to
+        `-[_WKInputDelegate _webView:willStartInputSession:`].
+    
+    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+    * TestRunnerShared/UIScriptContext/UIScriptContext.h:
+    * TestRunnerShared/UIScriptContext/UIScriptController.h:
+    (WTR::UIScriptController::suppressSoftwareKeyboard const):
+    (WTR::UIScriptController::setSuppressSoftwareKeyboard):
+    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+    (WTR::UIScriptController::setWillStartInputSessionCallback):
+    (WTR::UIScriptController::willStartInputSessionCallback const):
+    * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
+    * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+    (-[TestRunnerWKWebView initWithFrame:configuration:]):
+    (-[TestRunnerWKWebView resetInteractionCallbacks]):
+    (-[TestRunnerWKWebView _webView:willStartInputSession:]):
+    * WebKitTestRunner/ios/TestControllerIOS.mm:
+    (WTR::TestController::platformResetStateToConsistentValues):
+    
+    Make sure that we revert `_suppressSoftwareKeyboard` to `NO`, in case a layout test ends while leaving this on,
+    to prevent subsequent layout tests from behaving in unexpected ways.
+    
+    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+    (WTR::UIScriptControllerIOS::setWillStartInputSessionCallback):
+    (WTR::UIScriptControllerIOS::suppressSoftwareKeyboard const):
+    (WTR::UIScriptControllerIOS::setSuppressSoftwareKeyboard):
+    
+    LayoutTests:
+    
+    Add a new layout test to exercise the crash. See Tools and Source/WebKit ChangeLogs for more information.
+    This new test suppresses and then immediately un-suppresses the software keyboard inside the
+    `-_webView:willStartInputSession:` input delegate hook while focusing a regular text field.
+    
+    * fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt: Added.
+    * fast/forms/ios/suppress-software-keyboard-while-focusing-input.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279361 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-06-28  Wenson Hsieh  <[email protected]>
+
+            REGRESSION (r279310): Occasional crash when focusing login fields on iPad with a software keyboard
+            https://bugs.webkit.org/show_bug.cgi?id=227472
+            rdar://79876040
+
+            Reviewed by Tim Horton.
+
+            I added a mechanism in r279310 to defer calling `-[WKContentView _setSuppressSoftwareKeyboard:NO]` until we've
+            gotten a response from the web process containing an up-to-date autocorrection context. However, in the case
+            where the WKWebView client sets `_suppressSoftwareKeyboard` to `YES` and then immediately to `NO` underneath the
+            scope of a call to `-_webView:willStartInputSession:`, we'll end up calling into `-_setSuppressSoftwareKeyboard:`
+            inside the scope of `-requestAutocorrectionContextWithCompletionHandler:`, when we've received an
+            autocorrection context while sync-waiting. This is problematic because it breaks UIKeyboardTaskQueue's state,
+            since the call to `-_setSuppressSoftwareKeyboard:` will attempt to enqueue a new task after the previous task's
+            context has already returned execution to the parent.
+
+            To fix this, we instead invoke `self._suppressSoftwareKeyboard = NO;` *before* calling the completion block in
+            `-_handleAutocorrectionContext:`. This allows the request for an autocorrection context underneath
+            `-_setSuppressSoftwareKeyboard:` to be handled (and completed) as a child task of the previous task, which keeps
+            UIKeyboardTaskQueue in a valid state.
+
+            Test: fast/forms/ios/suppress-software-keyboard-while-focusing-input.html
+
+            * UIProcess/ios/WKContentViewInteraction.mm:
+            (-[WKContentView _handleAutocorrectionContext:]):
+
 2021-06-28  Kocsen Chung  <[email protected]>
 
         Cherry-pick r279352. rdar://problem/79891891

Modified: branches/safari-612.1.21-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (279375 => 279376)


--- branches/safari-612.1.21-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-06-29 18:00:06 UTC (rev 279376)
@@ -4662,8 +4662,8 @@
 - (void)_handleAutocorrectionContext:(const WebKit::WebAutocorrectionContext&)context
 {
     _lastAutocorrectionContext = context;
+    [self unsuppressSoftwareKeyboardUsingLastAutocorrectionContextIfNeeded];
     [self _invokePendingAutocorrectionContextHandler:[WKAutocorrectionContext autocorrectionContextWithWebContext:context]];
-    [self unsuppressSoftwareKeyboardUsingLastAutocorrectionContextIfNeeded];
 }
 
 - (void)updateSoftwareKeyboardSuppressionStateFromWebView

Modified: branches/safari-612.1.21-branch/Tools/ChangeLog (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/ChangeLog	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/ChangeLog	2021-06-29 18:00:06 UTC (rev 279376)
@@ -1,3 +1,124 @@
+2021-06-29  Alan Coon  <[email protected]>
+
+        Cherry-pick r279361. rdar://problem/79923766
+
+    REGRESSION (r279310): Occasional crash when focusing login fields on iPad with a software keyboard
+    https://bugs.webkit.org/show_bug.cgi?id=227472
+    rdar://79876040
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebKit:
+    
+    I added a mechanism in r279310 to defer calling `-[WKContentView _setSuppressSoftwareKeyboard:NO]` until we've
+    gotten a response from the web process containing an up-to-date autocorrection context. However, in the case
+    where the WKWebView client sets `_suppressSoftwareKeyboard` to `YES` and then immediately to `NO` underneath the
+    scope of a call to `-_webView:willStartInputSession:`, we'll end up calling into `-_setSuppressSoftwareKeyboard:`
+    inside the scope of `-requestAutocorrectionContextWithCompletionHandler:`, when we've received an
+    autocorrection context while sync-waiting. This is problematic because it breaks UIKeyboardTaskQueue's state,
+    since the call to `-_setSuppressSoftwareKeyboard:` will attempt to enqueue a new task after the previous task's
+    context has already returned execution to the parent.
+    
+    To fix this, we instead invoke `self._suppressSoftwareKeyboard = NO;` *before* calling the completion block in
+    `-_handleAutocorrectionContext:`. This allows the request for an autocorrection context underneath
+    `-_setSuppressSoftwareKeyboard:` to be handled (and completed) as a child task of the previous task, which keeps
+    UIKeyboardTaskQueue in a valid state.
+    
+    Test: fast/forms/ios/suppress-software-keyboard-while-focusing-input.html
+    
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView _handleAutocorrectionContext:]):
+    
+    Tools:
+    
+    Make it possible to induce the crash (prior to the fix) by introducing two new testing primitives on iOS:
+    
+    -   `UIScriptController.suppressSoftwareKeyboard`, a readwrite attribute that can be used to suppress the
+        appearance of the software keyboard on iOS by calling `-[WKWebView _setSuppressSoftwareKeyboard:]`.
+    
+    -   `UIScriptController.willStartInputSessionCallback`, a callback that is invoked when we're about to start a
+        UI-process-side input session. On iOS, this corresponds to
+        `-[_WKInputDelegate _webView:willStartInputSession:`].
+    
+    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+    * TestRunnerShared/UIScriptContext/UIScriptContext.h:
+    * TestRunnerShared/UIScriptContext/UIScriptController.h:
+    (WTR::UIScriptController::suppressSoftwareKeyboard const):
+    (WTR::UIScriptController::setSuppressSoftwareKeyboard):
+    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+    (WTR::UIScriptController::setWillStartInputSessionCallback):
+    (WTR::UIScriptController::willStartInputSessionCallback const):
+    * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
+    * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+    (-[TestRunnerWKWebView initWithFrame:configuration:]):
+    (-[TestRunnerWKWebView resetInteractionCallbacks]):
+    (-[TestRunnerWKWebView _webView:willStartInputSession:]):
+    * WebKitTestRunner/ios/TestControllerIOS.mm:
+    (WTR::TestController::platformResetStateToConsistentValues):
+    
+    Make sure that we revert `_suppressSoftwareKeyboard` to `NO`, in case a layout test ends while leaving this on,
+    to prevent subsequent layout tests from behaving in unexpected ways.
+    
+    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+    (WTR::UIScriptControllerIOS::setWillStartInputSessionCallback):
+    (WTR::UIScriptControllerIOS::suppressSoftwareKeyboard const):
+    (WTR::UIScriptControllerIOS::setSuppressSoftwareKeyboard):
+    
+    LayoutTests:
+    
+    Add a new layout test to exercise the crash. See Tools and Source/WebKit ChangeLogs for more information.
+    This new test suppresses and then immediately un-suppresses the software keyboard inside the
+    `-_webView:willStartInputSession:` input delegate hook while focusing a regular text field.
+    
+    * fast/forms/ios/suppress-software-keyboard-while-focusing-input-expected.txt: Added.
+    * fast/forms/ios/suppress-software-keyboard-while-focusing-input.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279361 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-06-28  Wenson Hsieh  <[email protected]>
+
+            REGRESSION (r279310): Occasional crash when focusing login fields on iPad with a software keyboard
+            https://bugs.webkit.org/show_bug.cgi?id=227472
+            rdar://79876040
+
+            Reviewed by Tim Horton.
+
+            Make it possible to induce the crash (prior to the fix) by introducing two new testing primitives on iOS:
+
+            -   `UIScriptController.suppressSoftwareKeyboard`, a readwrite attribute that can be used to suppress the
+                appearance of the software keyboard on iOS by calling `-[WKWebView _setSuppressSoftwareKeyboard:]`.
+
+            -   `UIScriptController.willStartInputSessionCallback`, a callback that is invoked when we're about to start a
+                UI-process-side input session. On iOS, this corresponds to
+                `-[_WKInputDelegate _webView:willStartInputSession:`].
+
+            * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+            * TestRunnerShared/UIScriptContext/UIScriptContext.h:
+            * TestRunnerShared/UIScriptContext/UIScriptController.h:
+            (WTR::UIScriptController::suppressSoftwareKeyboard const):
+            (WTR::UIScriptController::setSuppressSoftwareKeyboard):
+            * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+            (WTR::UIScriptController::setWillStartInputSessionCallback):
+            (WTR::UIScriptController::willStartInputSessionCallback const):
+            * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
+            * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+            (-[TestRunnerWKWebView initWithFrame:configuration:]):
+            (-[TestRunnerWKWebView resetInteractionCallbacks]):
+            (-[TestRunnerWKWebView _webView:willStartInputSession:]):
+            * WebKitTestRunner/ios/TestControllerIOS.mm:
+            (WTR::TestController::platformResetStateToConsistentValues):
+
+            Make sure that we revert `_suppressSoftwareKeyboard` to `NO`, in case a layout test ends while leaving this on,
+            to prevent subsequent layout tests from behaving in unexpected ways.
+
+            * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+            * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+            (WTR::UIScriptControllerIOS::setWillStartInputSessionCallback):
+            (WTR::UIScriptControllerIOS::suppressSoftwareKeyboard const):
+            (WTR::UIScriptControllerIOS::setSuppressSoftwareKeyboard):
+
 2021-06-28  Daniel Kolesa  <[email protected]>
 
         [GTK][WPE] Add libvpx to jhbuild

Modified: branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2021-06-29 18:00:06 UTC (rev 279376)
@@ -255,7 +255,9 @@
     attribute object didHideKeyboardCallback;
     readonly attribute boolean isShowingKeyboard;
     readonly attribute boolean hasInputSession;
+    attribute object willStartInputSessionCallback;
 
+    attribute double suppressSoftwareKeyboard;
     attribute boolean windowIsKey;
 
     attribute object didShowMenuCallback;

Modified: branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h	2021-06-29 18:00:06 UTC (rev 279376)
@@ -67,6 +67,7 @@
     CallbackTypeWindowTapRecognized,
     CallbackTypeDidShowContactPicker,
     CallbackTypeDidHideContactPicker,
+    CallbackTypeWillStartInputSession,
     CallbackTypeNonPersistent = firstNonPersistentCallbackID
 } CallbackType;
 

Modified: branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2021-06-29 18:00:06 UTC (rev 279376)
@@ -207,6 +207,9 @@
     virtual bool windowIsKey() const { notImplemented(); return false; }
     virtual void setWindowIsKey(bool) { notImplemented(); }
 
+    virtual bool suppressSoftwareKeyboard() const { notImplemented(); return false; }
+    virtual void setSuppressSoftwareKeyboard(bool) { notImplemented(); }
+
     // Stylus
 
     virtual void stylusDownAtPoint(long, long, float, float, float, JSValueRef) { notImplemented(); }
@@ -336,6 +339,9 @@
     virtual void setDidHideKeyboardCallback(JSValueRef);
     JSValueRef didHideKeyboardCallback() const;
 
+    virtual void setWillStartInputSessionCallback(JSValueRef);
+    JSValueRef willStartInputSessionCallback() const;
+
     virtual void setDidHideMenuCallback(JSValueRef);
     JSValueRef didHideMenuCallback() const;
     virtual void setDidShowMenuCallback(JSValueRef);

Modified: branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp	2021-06-29 18:00:06 UTC (rev 279376)
@@ -184,6 +184,16 @@
     return m_context->callbackWithID(CallbackTypeDidHideKeyboard);
 }
 
+void UIScriptController::setWillStartInputSessionCallback(JSValueRef callback)
+{
+    m_context->registerCallback(callback, CallbackTypeWillStartInputSession);
+}
+
+JSValueRef UIScriptController::willStartInputSessionCallback() const
+{
+    return m_context->callbackWithID(CallbackTypeWillStartInputSession);
+}
+
 void UIScriptController::setDidShowMenuCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidShowMenu);

Modified: branches/safari-612.1.21-branch/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h	2021-06-29 18:00:06 UTC (rev 279376)
@@ -39,6 +39,7 @@
 @property (nonatomic, copy) void (^didEndZoomingCallback)(void);
 @property (nonatomic, copy) void (^didShowKeyboardCallback)(void);
 @property (nonatomic, copy) void (^didHideKeyboardCallback)(void);
+@property (nonatomic, copy) void (^willStartInputSessionCallback)(void);
 @property (nonatomic, copy) void (^willPresentPopoverCallback)(void);
 @property (nonatomic, copy) void (^didDismissPopoverCallback)(void);
 @property (nonatomic, copy) void (^didEndScrollingCallback)(void);

Modified: branches/safari-612.1.21-branch/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm	2021-06-29 18:00:06 UTC (rev 279376)
@@ -30,6 +30,7 @@
 #import "WebKitTestRunnerDraggingInfo.h"
 #import <WebKit/WKUIDelegatePrivate.h>
 #import <WebKit/WKWebViewPrivateForTesting.h>
+#import <WebKit/_WKInputDelegate.h>
 #import <wtf/Assertions.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/RetainPtr.h>
@@ -59,7 +60,7 @@
     BlockPtr<void()> callback;
 };
 
-@interface TestRunnerWKWebView () <WKUIDelegatePrivate
+@interface TestRunnerWKWebView () <WKUIDelegatePrivate, _WKInputDelegate
 #if PLATFORM(IOS_FAMILY)
     , UIGestureRecognizerDelegate
 #endif
@@ -116,6 +117,7 @@
         [center addObserver:self selector:@selector(_willPresentPopover) name:@"UIPopoverControllerWillPresentPopoverNotification" object:nil];
         [center addObserver:self selector:@selector(_didDismissPopover) name:@"UIPopoverControllerDidDismissPopoverNotification" object:nil];
         self.UIDelegate = self;
+        self._inputDelegate = self;
 #endif
     }
     return self;
@@ -207,6 +209,7 @@
     self.didEndZoomingCallback = nil;
     self.didShowKeyboardCallback = nil;
     self.didHideKeyboardCallback = nil;
+    self.willStartInputSessionCallback = nil;
     self.willPresentPopoverCallback = nil;
     self.didDismissPopoverCallback = nil;
     self.didEndScrollingCallback = nil;
@@ -567,6 +570,14 @@
     [self _invokeHideKeyboardCallbackIfNecessary];
 }
 
+#pragma mark - _WKInputDelegate
+
+- (void)_webView:(WKWebView *)webView willStartInputSession:(id <_WKFormInputSession>)inputSession
+{
+    if (self.willStartInputSessionCallback)
+        self.willStartInputSessionCallback();
+}
+
 #pragma mark - UIGestureRecognizerDelegate
 
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

Modified: branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/TestControllerIOS.mm (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/TestControllerIOS.mm	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/TestControllerIOS.mm	2021-06-29 18:00:06 UTC (rev 279376)
@@ -204,6 +204,7 @@
     BOOL shouldRestoreFirstResponder = NO;
     if (PlatformWebView* platformWebView = mainWebView()) {
         TestRunnerWKWebView *webView = platformWebView->platformView();
+        webView._suppressSoftwareKeyboard = NO;
         webView._stableStateOverride = nil;
         webView._scrollingUpdatesDisabledForTesting = NO;
         webView.usesSafariLikeRotation = NO;

Modified: branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h	2021-06-29 18:00:06 UTC (rev 279376)
@@ -153,11 +153,15 @@
     void setDidEndZoomingCallback(JSValueRef) override;
     void setDidShowKeyboardCallback(JSValueRef) override;
     void setDidHideKeyboardCallback(JSValueRef) override;
+    void setWillStartInputSessionCallback(JSValueRef) override;
     void setWillPresentPopoverCallback(JSValueRef) override;
     void setDidDismissPopoverCallback(JSValueRef) override;
     void setDidEndScrollingCallback(JSValueRef) override;
     void clearAllCallbacks() override;
 
+    bool suppressSoftwareKeyboard() const final;
+    void setSuppressSoftwareKeyboard(bool) final;
+
     void waitForModalTransitionToFinish() const;
     void waitForSingleTapToReset() const;
     WebCore::FloatRect rectForMenuAction(CFStringRef) const;

Modified: branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (279375 => 279376)


--- branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2021-06-29 17:11:34 UTC (rev 279375)
+++ branches/safari-612.1.21-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2021-06-29 18:00:06 UTC (rev 279376)
@@ -979,6 +979,16 @@
     }).get();
 }
 
+void UIScriptControllerIOS::setWillStartInputSessionCallback(JSValueRef callback)
+{
+    UIScriptController::setWillStartInputSessionCallback(callback);
+    webView().willStartInputSessionCallback = makeBlockPtr([this, strongThis = makeRef(*this)] {
+        if (!m_context)
+            return;
+        m_context->fireCallback(CallbackTypeWillStartInputSession);
+    }).get();
+}
+
 void UIScriptControllerIOS::chooseMenuAction(JSStringRef jsAction, JSValueRef callback)
 {
     auto action = "" jsAction));
@@ -1272,6 +1282,16 @@
     }).get();
 }
 
+bool UIScriptControllerIOS::suppressSoftwareKeyboard() const
+{
+    return webView()._suppressSoftwareKeyboard;
 }
 
+void UIScriptControllerIOS::setSuppressSoftwareKeyboard(bool suppressSoftwareKeyboard)
+{
+    webView()._suppressSoftwareKeyboard = suppressSoftwareKeyboard;
+}
+
+}
+
 #endif // PLATFORM(IOS_FAMILY)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to