Title: [291737] trunk
Revision
291737
Author
[email protected]
Date
2022-03-22 23:47:41 -0700 (Tue, 22 Mar 2022)

Log Message

Only show notification permission prompt on transient activation
https://bugs.webkit.org/show_bug.cgi?id=238188

Reviewed by Youenn Fablet.

Source/WebCore:

In r291427, we changed Notification.requestPermission and PushManager.subscribe to only show
a permission prompt when processing a user gesture. This ended up being too restrictive and
causes compatibility problems with some large sites.

Instead, match Chrome and Firefox by allowing these prompts after a transient activiation,
i.e. a user gesture within the past second.

Per Maciej's suggestion, we also consume the activation to help combat prompt spam.

Covered by new and existing layout tests.

* Modules/notifications/Notification.cpp:
(WebCore::Notification::requestPermission):
* Modules/push-api/PushManager.cpp:
(WebCore::PushManager::subscribe):

Tools:

Add an internal API denyWebNotificationPermissionOnPrompt to WebKitTestRunner that allows a
notification permission prompt to first be displayed and then rejected. This differs from
the existing denyNotificationPermission call, which denied notification permissions before
prompting.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::denyWebNotificationPermission):
(WTR::TestRunner::denyWebNotificationPermissionOnPrompt):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::originUserVisibleName):
(WTR::TestController::denyNotificationPermissionOnPrompt):
(WTR::TestController::resetStateToConsistentValues):
(WTR::TestController::decidePolicyForNotificationPermissionRequest):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):

LayoutTests:

Add test cases to make sure that showing a permission prompt consumes a user gesture.

* http/tests/notifications/notification-request-permission-no-callback.html:
* http/tests/notifications/notification-request-permission.html:
* http/tests/notifications/request-consumes-activation-expected.txt: Added.
* http/tests/notifications/request-consumes-activation.html: Added.
* http/tests/push-api/resources/subscribe-tests.js:
(async testDocumentSubscribeWithUserGesture):
(async testDocumentSubscribeWithoutUserGesture):
(async testDocumentSubscribeImpl):
* http/tests/push-api/subscribe-deny-permissions-expected.txt:
* http/tests/push-api/subscribe-deny-permissions-on-prompt-expected.txt:
* http/tests/push-api/subscribe-deny-permissions-on-prompt.html: Added.
* http/tests/push-api/subscribe-deny-permissions.html:
* platform/gtk/TestExpectations:
* platform/mac-wk1/TestExpectations:
* platform/win/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (291736 => 291737)


--- trunk/LayoutTests/ChangeLog	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/ChangeLog	2022-03-23 06:47:41 UTC (rev 291737)
@@ -1,3 +1,28 @@
+2022-03-22  Ben Nham  <[email protected]>
+
+        Only show notification permission prompt on transient activation
+        https://bugs.webkit.org/show_bug.cgi?id=238188
+
+        Reviewed by Youenn Fablet.
+
+        Add test cases to make sure that showing a permission prompt consumes a user gesture.
+
+        * http/tests/notifications/notification-request-permission-no-callback.html:
+        * http/tests/notifications/notification-request-permission.html:
+        * http/tests/notifications/request-consumes-activation-expected.txt: Added.
+        * http/tests/notifications/request-consumes-activation.html: Added.
+        * http/tests/push-api/resources/subscribe-tests.js:
+        (async testDocumentSubscribeWithUserGesture):
+        (async testDocumentSubscribeWithoutUserGesture):
+        (async testDocumentSubscribeImpl):
+        * http/tests/push-api/subscribe-deny-permissions-expected.txt:
+        * http/tests/push-api/subscribe-deny-permissions-on-prompt-expected.txt:
+        * http/tests/push-api/subscribe-deny-permissions-on-prompt.html: Added.
+        * http/tests/push-api/subscribe-deny-permissions.html:
+        * platform/gtk/TestExpectations:
+        * platform/mac-wk1/TestExpectations:
+        * platform/win/TestExpectations:
+
 2022-03-22  Tyler Wilcock  <[email protected]>
 
         Expose the AX tree of PDFs loaded via iframes on the Mac

Modified: trunk/LayoutTests/http/tests/notifications/notification-request-permission-no-callback.html (291736 => 291737)


--- trunk/LayoutTests/http/tests/notifications/notification-request-permission-no-callback.html	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/http/tests/notifications/notification-request-permission-no-callback.html	2022-03-23 06:47:41 UTC (rev 291737)
@@ -15,11 +15,15 @@
 internals.withUserGesture(() => {
     window.Notification.requestPermission();
     testPassed("Notification.requestPermission does not crash.");
+});
 
+internals.withUserGesture(() => {
     testRunner.grantWebNotificationPermission(testURL);
     window.Notification.requestPermission();
     testPassed("Notification.requestPermission does not crash.");
+});
 
+internals.withUserGesture(() => {
     testRunner.denyWebNotificationPermission(testURL);
     window.Notification.requestPermission();
     testPassed("Notification.requestPermission does not crash.");

Modified: trunk/LayoutTests/http/tests/notifications/notification-request-permission.html (291736 => 291737)


--- trunk/LayoutTests/http/tests/notifications/notification-request-permission.html	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/http/tests/notifications/notification-request-permission.html	2022-03-23 06:47:41 UTC (rev 291737)
@@ -15,11 +15,15 @@
 internals.withUserGesture(() => {
     window.Notification.requestPermission(function() { });
     testPassed("Notification.requestPermission does not crash.");
+});
 
+internals.withUserGesture(() => {
     testRunner.grantWebNotificationPermission(testURL);
     window.Notification.requestPermission(function() { });
     testPassed("Notification.requestPermission does not crash.");
+});
 
+internals.withUserGesture(() => {
     testRunner.denyWebNotificationPermission(testURL);
     window.Notification.requestPermission(function() { });
     testPassed("Notification.requestPermission does not crash.");

Added: trunk/LayoutTests/http/tests/notifications/request-consumes-activation-expected.txt (0 => 291737)


--- trunk/LayoutTests/http/tests/notifications/request-consumes-activation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/notifications/request-consumes-activation-expected.txt	2022-03-23 06:47:41 UTC (rev 291737)
@@ -0,0 +1,12 @@
+CONSOLE MESSAGE: Notification prompting can only be done from a user gesture.
+This tests that Notification.requestPermission can only be called once per user gesture.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS both permission requests denied
+PASS Notification.permission is "denied"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/http/tests/notifications/request-consumes-activation.html (0 => 291737)


--- trunk/LayoutTests/http/tests/notifications/request-consumes-activation.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/notifications/request-consumes-activation.html	2022-03-23 06:47:41 UTC (rev 291737)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<script src=""
+<script>
+description("This tests that Notification.requestPermission can only be called once per user gesture.");
+jsTestIsAsync = true;
+
+if (!window.internals)
+    finishJSTest();
+
+function run() {
+    testRunner.denyWebNotificationPermission(self.origin);
+    internals.withUserGesture(() => {
+        let prompt1 = Notification.requestPermission();
+        let prompt2 = Notification.requestPermission();
+        Promise.all([prompt1, prompt2]).then(([permission1, permission2]) => {
+            if (permission1 == 'denied' && permission2 == 'denied')
+                testPassed("both permission requests denied");
+            else
+                testFailed("both permission requests should be denied, but was " + permission1 + " and then " + permission2);
+            shouldBeEqualToString("Notification.permission", "denied");
+            finishJSTest();
+        });
+    });
+}
+
+run();
+</script>

Modified: trunk/LayoutTests/http/tests/push-api/resources/subscribe-tests.js (291736 => 291737)


--- trunk/LayoutTests/http/tests/push-api/resources/subscribe-tests.js	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/http/tests/push-api/resources/subscribe-tests.js	2022-03-23 06:47:41 UTC (rev 291737)
@@ -38,19 +38,24 @@
         log(`FAIL: service worker subscribe should be ${expected}, but was ${result}`);
 }
 
-async function testDocumentSubscribeWithUserGesture(registration, domExceptionName)
+async function testDocumentSubscribeWithUserGesture(registration, domExceptionName, domMessage)
 {
-    await testDocumentSubscribeImpl(registration, domExceptionName, true);
+    await testDocumentSubscribeImpl(registration, domExceptionName, domMessage, true);
 }
 
-async function testDocumentSubscribeWithoutUserGesture(registration, domExceptionName)
+async function testDocumentSubscribeWithoutUserGesture(registration, domExceptionName, domMessage)
 {
-    await testDocumentSubscribeImpl(registration, domExceptionName, false);
+    await testDocumentSubscribeImpl(registration, domExceptionName, domMessage, false);
 }
 
-async function testDocumentSubscribeImpl(registration, domExceptionName, withUserGesture)
+async function testDocumentSubscribeImpl(registration, domExceptionName, domMessage, withUserGesture)
 {
-    let expected = domExceptionName ? `error: ${domExceptionName}` : "successful";
+    let expected = "successful";
+    if (domMessage)
+        expected = `error: ${domExceptionName}: ${domMessage}`
+    else if (domExceptionName)
+        expected = `error: ${domExceptionName}`
+
     let result = null;
 
     let subscription = null;
@@ -79,8 +84,10 @@
         // point where we attempt to communicate with webpushd (an AbortError).
         if (e.name == 'AbortError')
             result = 'successful';
+        else if (domMessage)
+            result = `error: ${e?.name}: ${e?.message}`
         else
-            result = 'error: ' + (e ? e.name : null);
+            result = `error: ${e?.name}`;
     }
 
     if (subscription)

Modified: trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-expected.txt (291736 => 291737)


--- trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-expected.txt	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-expected.txt	2022-03-23 06:47:41 UTC (rev 291737)
@@ -1,6 +1,6 @@
 PASS: service worker permissionState was denied
 PASS: document permissionState was denied
 PASS: service worker subscribe was error: NotAllowedError
-PASS: document subscribe without user gesture was error: NotAllowedError
+PASS: document subscribe without user gesture was error: NotAllowedError: User denied push permission
 PASS: document subscribe with user gesture was error: NotAllowedError
 

Copied: trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-on-prompt-expected.txt (from rev 291736, trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-expected.txt) (0 => 291737)


--- trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-on-prompt-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-on-prompt-expected.txt	2022-03-23 06:47:41 UTC (rev 291737)
@@ -0,0 +1,7 @@
+PASS: service worker permissionState was prompt
+PASS: document permissionState was prompt
+PASS: service worker subscribe was error: NotAllowedError
+PASS: document subscribe without user gesture was error: NotAllowedError
+PASS: document subscribe with user gesture was error: NotAllowedError
+PASS: document subscribe with consumed user gesture failed with user gesture error
+

Added: trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-on-prompt.html (0 => 291737)


--- trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-on-prompt.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions-on-prompt.html	2022-03-23 06:47:41 UTC (rev 291737)
@@ -0,0 +1,57 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+if (window.testRunner)
+    testRunner.denyWebNotificationPermissionOnPrompt(window.origin);
+
+navigator.serviceWorker.register("resources/subscribe-worker.js", { }).then(async (registration) => {
+    try {
+        await waitForState(registration.installing, "activated");
+        await testServiceWorkerPermissionState(registration, 'prompt');
+        await testDocumentPermissionState(registration, 'prompt');
+        await testServiceWorkerSubscribe(registration, 'NotAllowedError');
+        await testDocumentSubscribeWithoutUserGesture(registration, 'NotAllowedError');
+
+        let promise = new Promise((resolve, reject) => {
+            if (!window.internals) {
+                reject('Test requires internals.');
+                return;
+            }
+
+            internals.withUserGesture(() => {
+                let request1 = registration.pushManager.subscribe({
+                    userVisibleOnly: true,
+                    applicationServerKey: VALID_SERVER_KEY
+                });
+                let request2 = registration.pushManager.subscribe({
+                    userVisibleOnly: true,
+                    applicationServerKey: VALID_SERVER_KEY
+                });
+                Promise.allSettled([request1, request2]).then(resolve);
+            });
+        });
+        let [result1, result2] = await(promise);
+        
+        if (result1.reason && result1.reason.name == 'NotAllowedError')
+            log('PASS: document subscribe with user gesture was error: NotAllowedError')
+        else
+            log(`FAIL: first subscribe failed with unexpected result ${result1.value || result1.reason}`);
+
+        if (result2.reason && result2.reason.name == 'NotAllowedError' && result2.reason.message.includes('user gesture'))
+            log('PASS: document subscribe with consumed user gesture failed with user gesture error')
+        else
+            log(`FAIL: second subscribe failed with unexpected result ${result2.value || result2.reason}`)
+    } catch (e) {
+        log(`FAIL: unexpected exception ${e}`);
+    } finally {
+        await registration.unregister();
+        finishPushAPITest();
+    }
+});
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions.html (291736 => 291737)


--- trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions.html	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/http/tests/push-api/subscribe-deny-permissions.html	2022-03-23 06:47:41 UTC (rev 291737)
@@ -14,7 +14,7 @@
         await testServiceWorkerPermissionState(registration, 'denied');
         await testDocumentPermissionState(registration, 'denied');
         await testServiceWorkerSubscribe(registration, 'NotAllowedError');
-        await testDocumentSubscribeWithoutUserGesture(registration, 'NotAllowedError');
+        await testDocumentSubscribeWithoutUserGesture(registration, 'NotAllowedError', 'User denied push permission');
         await testDocumentSubscribeWithUserGesture(registration, 'NotAllowedError');
     } catch (e) {
         log(`FAIL: unexpected exception ${e}`);

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (291736 => 291737)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2022-03-23 06:47:41 UTC (rev 291737)
@@ -1873,6 +1873,7 @@
 http/tests/push-api/subscribe-default-permissions-iframe-cross-origin.html [ Failure ]
 http/tests/push-api/subscribe-default-permissions-iframe-same-origin.html [ Failure ]
 http/tests/push-api/subscribe-default-permissions.html [ Failure ]
+http/tests/push-api/subscribe-deny-permissions-on-prompt.html [ Failure ]
 http/tests/push-api/subscribe-deny-permissions.html [ Failure ]
 http/tests/push-api/subscribe-grant-permissions.html [ Failure ]
 

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (291736 => 291737)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2022-03-23 06:47:41 UTC (rev 291737)
@@ -1788,6 +1788,7 @@
 http/tests/push-api/subscribe-default-permissions-iframe-cross-origin.html [ Skip ]
 http/tests/push-api/subscribe-default-permissions-iframe-same-origin.html [ Skip ]
 http/tests/push-api/subscribe-default-permissions.html [ Skip ]
+http/tests/push-api/subscribe-deny-permissions-on-prompt.html [ Failure ]
 http/tests/push-api/subscribe-deny-permissions.html [ Skip ]
 http/tests/push-api/subscribe-grant-permissions.html [ Skip ]
 

Modified: trunk/LayoutTests/platform/win/TestExpectations (291736 => 291737)


--- trunk/LayoutTests/platform/win/TestExpectations	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/LayoutTests/platform/win/TestExpectations	2022-03-23 06:47:41 UTC (rev 291737)
@@ -5015,6 +5015,7 @@
 http/tests/push-api/subscribe-default-permissions-iframe-cross-origin.html [ Failure ]
 http/tests/push-api/subscribe-default-permissions-iframe-same-origin.html [ Failure ]
 http/tests/push-api/subscribe-default-permissions.html [ Failure ]
+http/tests/push-api/subscribe-deny-permissions-on-prompt.html [ Failure ]
 http/tests/push-api/subscribe-deny-permissions.html [ Failure ]
 http/tests/push-api/subscribe-grant-permissions.html [ Failure ]
 

Modified: trunk/Source/WebCore/ChangeLog (291736 => 291737)


--- trunk/Source/WebCore/ChangeLog	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Source/WebCore/ChangeLog	2022-03-23 06:47:41 UTC (rev 291737)
@@ -1,3 +1,26 @@
+2022-03-22  Ben Nham  <[email protected]>
+
+        Only show notification permission prompt on transient activation
+        https://bugs.webkit.org/show_bug.cgi?id=238188
+
+        Reviewed by Youenn Fablet.
+
+        In r291427, we changed Notification.requestPermission and PushManager.subscribe to only show
+        a permission prompt when processing a user gesture. This ended up being too restrictive and
+        causes compatibility problems with some large sites.
+
+        Instead, match Chrome and Firefox by allowing these prompts after a transient activiation,
+        i.e. a user gesture within the past second.
+
+        Per Maciej's suggestion, we also consume the activation to help combat prompt spam.
+
+        Covered by new and existing layout tests.
+
+        * Modules/notifications/Notification.cpp:
+        (WebCore::Notification::requestPermission):
+        * Modules/push-api/PushManager.cpp:
+        (WebCore::PushManager::subscribe):
+
 2022-03-22  Alex Christensen  <[email protected]>
 
         Implement PCM to SKAdNetwork bridge

Modified: trunk/Source/WebCore/Modules/notifications/Notification.cpp (291736 => 291737)


--- trunk/Source/WebCore/Modules/notifications/Notification.cpp	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Source/WebCore/Modules/notifications/Notification.cpp	2022-03-23 06:47:41 UTC (rev 291737)
@@ -35,6 +35,7 @@
 
 #include "Notification.h"
 
+#include "DOMWindow.h"
 #include "Event.h"
 #include "EventNames.h"
 #include "JSDOMPromiseDeferred.h"
@@ -43,7 +44,6 @@
 #include "NotificationEvent.h"
 #include "NotificationPermissionCallback.h"
 #include "ServiceWorkerGlobalScope.h"
-#include "UserGestureIndicator.h"
 #include "WindowEventLoop.h"
 #include "WindowFocusAllowedIndicator.h"
 #include <wtf/CompletionHandler.h>
@@ -297,7 +297,8 @@
         return resolvePromiseAndCallback(Permission::Denied);
     }
 
-    if (!UserGestureIndicator::processingUserGesture()) {
+    auto* window = document.frame() ? document.frame()->window() : nullptr;
+    if (!window || !window->consumeTransientActivation()) {
         document.addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Notification prompting can only be done from a user gesture."_s);
         return resolvePromiseAndCallback(Permission::Denied);
     }

Modified: trunk/Source/WebCore/Modules/push-api/PushManager.cpp (291736 => 291737)


--- trunk/Source/WebCore/Modules/push-api/PushManager.cpp	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Source/WebCore/Modules/push-api/PushManager.cpp	2022-03-23 06:47:41 UTC (rev 291737)
@@ -28,6 +28,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "DOMWindow.h"
 #include "DocumentInlines.h"
 #include "EventLoop.h"
 #include "Exception.h"
@@ -37,7 +38,6 @@
 #include "PushCrypto.h"
 #include "ScriptExecutionContext.h"
 #include "ServiceWorkerRegistration.h"
-#include "UserGestureIndicator.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/Vector.h>
 #include <wtf/text/Base64.h>
@@ -72,7 +72,7 @@
 {
     RELEASE_ASSERT(context.isSecureContext());
 
-    context.eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = Ref { *this }, context = Ref { context }, options = WTFMove(options), promise = WTFMove(promise), processingUserGesture = UserGestureIndicator::processingUserGesture()]() mutable {
+    context.eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = Ref { *this }, context = Ref { context }, options = WTFMove(options), promise = WTFMove(promise)]() mutable {
         if (!options || !options->userVisibleOnly) {
             promise.reject(Exception { NotAllowedError, "Subscribing for push requires userVisibleOnly to be true"_s });
             return;
@@ -131,12 +131,14 @@
             RELEASE_ASSERT(client);
             RELEASE_ASSERT(context->isDocument());
 
-            if (!downcast<Document>(context.get()).isSameOriginAsTopDocument()) {
+            auto& document = downcast<Document>(context.get());
+            if (!document.isSameOriginAsTopDocument()) {
                 promise.reject(Exception { NotAllowedError, "Cannot request permission from cross-origin iframe"_s });
                 return;
             }
 
-            if (!processingUserGesture) {
+            auto* window = document.frame() ? document.frame()->window() : nullptr;
+            if (!window || !window->consumeTransientActivation()) {
                 promise.reject(Exception { NotAllowedError, "Push notification prompting can only be done from a user gesture"_s });
                 return;
             }

Modified: trunk/Tools/ChangeLog (291736 => 291737)


--- trunk/Tools/ChangeLog	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Tools/ChangeLog	2022-03-23 06:47:41 UTC (rev 291737)
@@ -1,3 +1,29 @@
+2022-03-22  Ben Nham  <[email protected]>
+
+        Only show notification permission prompt on transient activation
+        https://bugs.webkit.org/show_bug.cgi?id=238188
+
+        Reviewed by Youenn Fablet.
+
+        Add an internal API denyWebNotificationPermissionOnPrompt to WebKitTestRunner that allows a
+        notification permission prompt to first be displayed and then rejected. This differs from
+        the existing denyNotificationPermission call, which denied notification permissions before
+        prompting.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::denyWebNotificationPermission):
+        (WTR::TestRunner::denyWebNotificationPermissionOnPrompt):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::originUserVisibleName):
+        (WTR::TestController::denyNotificationPermissionOnPrompt):
+        (WTR::TestController::resetStateToConsistentValues):
+        (WTR::TestController::decidePolicyForNotificationPermissionRequest):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2022-03-22  Yusuke Suzuki  <[email protected]>
 
         [JSC] Test DFG / FTL DataIC

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (291736 => 291737)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2022-03-23 06:47:41 UTC (rev 291737)
@@ -206,6 +206,7 @@
     // Web notifications support
     undefined grantWebNotificationPermission(DOMString origin);
     undefined denyWebNotificationPermission(DOMString origin);
+    undefined denyWebNotificationPermissionOnPrompt(DOMString origin);
     undefined removeAllWebNotificationPermissions();
     undefined simulateWebNotificationClick(object notification);
     undefined simulateWebNotificationClickForServiceWorkerNotifications();

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (291736 => 291737)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2022-03-23 06:47:41 UTC (rev 291737)
@@ -876,6 +876,11 @@
     postSynchronousPageMessageWithReturnValue("DenyNotificationPermission", toWK(origin));
 }
 
+void TestRunner::denyWebNotificationPermissionOnPrompt(JSStringRef origin)
+{
+    postSynchronousPageMessageWithReturnValue("DenyNotificationPermissionOnPrompt", toWK(origin));
+}
+
 void TestRunner::removeAllWebNotificationPermissions()
 {
     WKBundleRemoveAllWebNotificationPermissions(InjectedBundle::singleton().bundle(), page());

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (291736 => 291737)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2022-03-23 06:47:41 UTC (rev 291737)
@@ -292,6 +292,7 @@
     // Web notifications.
     static void grantWebNotificationPermission(JSStringRef origin);
     static void denyWebNotificationPermission(JSStringRef origin);
+    static void denyWebNotificationPermissionOnPrompt(JSStringRef origin);
     static void removeAllWebNotificationPermissions();
     static void simulateWebNotificationClick(JSValueRef notification);
     static void simulateWebNotificationClickForServiceWorkerNotifications();

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (291736 => 291737)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2022-03-23 06:47:41 UTC (rev 291737)
@@ -719,6 +719,23 @@
     return pageConfiguration;
 }
 
+static String originUserVisibleName(WKSecurityOriginRef origin)
+{
+    if (!origin)
+        return emptyString();
+
+    auto host = toWTFString(adoptWK(WKSecurityOriginCopyHost(origin)));
+    auto protocol = toWTFString(adoptWK(WKSecurityOriginCopyProtocol(origin)));
+
+    if (host.isEmpty() || protocol.isEmpty())
+        return emptyString();
+
+    if (int port = WKSecurityOriginGetPort(origin))
+        return makeString(protocol, "://", host, ':', port);
+
+    return makeString(protocol, "://", host);
+}
+
 bool TestController::grantNotificationPermission(WKStringRef originString)
 {
     m_webNotificationProvider.setPermission(toWTFString(originString), true);
@@ -737,6 +754,14 @@
     return true;
 }
 
+bool TestController::denyNotificationPermissionOnPrompt(WKStringRef originString)
+{
+    auto origin = adoptWK(WKSecurityOriginCreateFromString(originString));
+    auto originName = originUserVisibleName(origin.get());
+    m_notificationOriginsToDenyOnPrompt.add(originName);
+    return true;
+}
+
 void TestController::createWebViewWithOptions(const TestOptions& options)
 {
     auto applicationBundleIdentifier = options.applicationBundleIdentifier();
@@ -1046,6 +1071,7 @@
 
     // Reset notification permissions
     m_webNotificationProvider.reset();
+    m_notificationOriginsToDenyOnPrompt.clear();
 
     // Reset Geolocation permissions.
     m_geolocationPermissionRequests.clear();
@@ -2412,23 +2438,6 @@
     return m_geolocationProvider->isActive();
 }
 
-static String originUserVisibleName(WKSecurityOriginRef origin)
-{
-    if (!origin)
-        return emptyString();
-
-    auto host = toWTFString(adoptWK(WKSecurityOriginCopyHost(origin)));
-    auto protocol = toWTFString(adoptWK(WKSecurityOriginCopyProtocol(origin)));
-
-    if (host.isEmpty() || protocol.isEmpty())
-        return emptyString();
-
-    if (int port = WKSecurityOriginGetPort(origin))
-        return makeString(protocol, "://", host, ':', port);
-
-    return makeString(protocol, "://", host);
-}
-
 static String userMediaOriginHash(WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin)
 {
     String userMediaDocumentOriginString = originUserVisibleName(userMediaDocumentOrigin);
@@ -2651,8 +2660,14 @@
     TestController::singleton().decidePolicyForNotificationPermissionRequest(page, origin, request);
 }
 
-void TestController::decidePolicyForNotificationPermissionRequest(WKPageRef, WKSecurityOriginRef, WKNotificationPermissionRequestRef request)
+void TestController::decidePolicyForNotificationPermissionRequest(WKPageRef, WKSecurityOriginRef origin, WKNotificationPermissionRequestRef request)
 {
+    auto originName = originUserVisibleName(origin);
+    if (m_notificationOriginsToDenyOnPrompt.contains(originName)) {
+        WKNotificationPermissionRequestDeny(request);
+        return;
+    }
+
     WKNotificationPermissionRequestAllow(request);
 }
 

Modified: trunk/Tools/WebKitTestRunner/TestController.h (291736 => 291737)


--- trunk/Tools/WebKitTestRunner/TestController.h	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2022-03-23 06:47:41 UTC (rev 291737)
@@ -376,6 +376,7 @@
 
     bool grantNotificationPermission(WKStringRef origin);
     bool denyNotificationPermission(WKStringRef origin);
+    bool denyNotificationPermissionOnPrompt(WKStringRef origin);
 
 private:
     WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(const TestOptions&);
@@ -575,6 +576,7 @@
     WKRetainPtr<WKStringRef> m_testPluginDirectory;
 
     WebNotificationProvider m_webNotificationProvider;
+    HashSet<String> m_notificationOriginsToDenyOnPrompt;
 
     std::unique_ptr<PlatformWebView> m_mainWebView;
     Vector<UniqueRef<PlatformWebView>> m_auxiliaryWebViews;

Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (291736 => 291737)


--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2022-03-23 06:45:52 UTC (rev 291736)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2022-03-23 06:47:41 UTC (rev 291737)
@@ -1039,6 +1039,9 @@
     if (WKStringIsEqualToUTF8CString(messageName, "DenyNotificationPermission"))
         return adoptWK(WKBooleanCreate(TestController::singleton().denyNotificationPermission(stringValue(messageBody))));
 
+    if (WKStringIsEqualToUTF8CString(messageName, "DenyNotificationPermissionOnPrompt"))
+        return adoptWK(WKBooleanCreate(TestController::singleton().denyNotificationPermissionOnPrompt(stringValue(messageBody))));
+
     if (WKStringIsEqualToUTF8CString(messageName, "IsDoingMediaCapture"))
         return adoptWK(WKBooleanCreate(TestController::singleton().isDoingMediaCapture()));
     
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to