Diff
Modified: trunk/LayoutTests/ChangeLog (292157 => 292158)
--- trunk/LayoutTests/ChangeLog 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/LayoutTests/ChangeLog 2022-03-31 15:08:16 UTC (rev 292158)
@@ -1,3 +1,14 @@
+2022-03-31 Ben Nham <n...@apple.com>
+
+ Remove push subscriptions when permissions are reset
+ https://bugs.webkit.org/show_bug.cgi?id=238068
+
+ Reviewed by Youenn Fablet.
+
+ Fix an issue with a layout test that didn't register for notification permissions.
+
+ * http/wpt/service-workers/service-worker-spinning-push.https.html:
+
2022-03-31 Alan Bujtas <za...@apple.com>
[CSS contain] Containment disables the special handling of the HTML body element for overflow viewport propagation [part2]
Modified: trunk/LayoutTests/http/wpt/service-workers/service-worker-spinning-push.https.html (292157 => 292158)
--- trunk/LayoutTests/http/wpt/service-workers/service-worker-spinning-push.https.html 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/LayoutTests/http/wpt/service-workers/service-worker-spinning-push.https.html 2022-03-31 15:08:16 UTC (rev 292158)
@@ -7,6 +7,9 @@
</head>
<body>
<script>
+if (window.testRunner)
+ testRunner.grantWebNotificationPermission(window.origin);
+
promise_test(async (test) => {
const registration = await navigator.serviceWorker.register("service-worker-spinning-worker.js", { scope : "spin-push" });
const worker = registration.installing;
Modified: trunk/Source/WebKit/ChangeLog (292157 => 292158)
--- trunk/Source/WebKit/ChangeLog 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Source/WebKit/ChangeLog 2022-03-31 15:08:16 UTC (rev 292158)
@@ -1,3 +1,40 @@
+2022-03-31 Ben Nham <n...@apple.com>
+
+ Remove push subscriptions when permissions are reset
+ https://bugs.webkit.org/show_bug.cgi?id=238068
+
+ Reviewed by Youenn Fablet.
+
+ When the notification permission for an origin is reset (i.e. is in the prompt state), we
+ should delete any push subscriptions associated with that origin. We do this by having the
+ providerDidRemoveNotificationPolicies API call deletePushAndNotificationRegistration in
+ webpushd.
+
+ We also do this when processing a push message, since it's possible for the state to get out
+ of sync due to the number of processes involved. For instance, removing the policy from
+ System Preferences rather than the browser's notification preference pane can result in the
+ providerDidRemoveNotificationPolicies call in the browser to be delayed or dropped.
+
+ Note that we don't delete the subscription if the permission is simply toggled off (i.e. the
+ permission is in the Denied state). In that case, the user can easily toggle the permission
+ back on. We want the subscription object to stay the same after the preference is toggled
+ back on so that the server can still send pushes to that push endpoint. In a future patch
+ we'll add subscriptions in this state to the ignored topics list in webpushd, which will
+ prevent pushes for those subscriptions from being delivered to the device without actually
+ unsubscribing.
+
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::processPushMessage):
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkProcess.messages.in:
+ * UIProcess/Network/NetworkProcessProxy.cpp:
+ (WebKit::NetworkProcessProxy::processPushMessage):
+ * UIProcess/Notifications/WebNotificationManagerProxy.cpp:
+ (WebKit::removePushSubscriptionsForOrigins):
+ (WebKit::WebNotificationManagerProxy::providerDidRemoveNotificationPolicies):
+ * webpushd/WebPushDaemon.mm:
+ (WebPushD::Daemon::deletePushAndNotificationRegistration):
+
2022-03-31 Alex Christensen <achristen...@webkit.org>
Remove EXPERIMENTAL_FEATURES flag on Cocoa platforms
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (292157 => 292158)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2022-03-31 15:08:16 UTC (rev 292158)
@@ -2309,11 +2309,29 @@
LOG(Notifications, "NetworkProcess could not find session for ID %llu to get pending push messages", sessionID.toUInt64());
}
-void NetworkProcess::processPushMessage(PAL::SessionID sessionID, WebPushMessage&& pushMessage, CompletionHandler<void(bool)>&& callback)
+void NetworkProcess::processPushMessage(PAL::SessionID sessionID, WebPushMessage&& pushMessage, PushPermissionState permissionState, CompletionHandler<void(bool)>&& callback)
{
if (auto* session = networkSession(sessionID)) {
LOG(Push, "Networking process handling a push message from UI process in session %llu", sessionID.toUInt64());
auto origin = SecurityOriginData::fromURL(pushMessage.registrationURL);
+
+ if (permissionState == PushPermissionState::Prompt) {
+ RELEASE_LOG(Push, "Push message from %" PRIVATE_LOG_STRING " won't be processed since permission is in the prompt state; removing push subscription", origin.toString().utf8().data());
+ session->notificationManager().removePushSubscriptionsForOrigin(SecurityOriginData { origin }, [callback = WTFMove(callback)](auto&&) mutable {
+ callback(false);
+ return;
+ });
+ return;
+ }
+
+ if (permissionState == PushPermissionState::Denied) {
+ RELEASE_LOG(Push, "Push message from %" PRIVATE_LOG_STRING " won't be processed since permission is in the denied state", origin.toString().utf8().data());
+ // FIXME: move topic to ignore list in webpushd if permission is denied.
+ callback(false);
+ return;
+ }
+
+ ASSERT(permissionState == PushPermissionState::Granted);
session->ensureSWServer().processPushMessage(WTFMove(pushMessage.pushData), WTFMove(pushMessage.registrationURL), [this, protectedThis = Ref { *this }, sessionID, origin = WTFMove(origin), callback = WTFMove(callback)](bool result) mutable {
NetworkSession* session;
if (!result && (session = networkSession(sessionID))) {
@@ -2336,7 +2354,7 @@
callback({ });
}
-void NetworkProcess::processPushMessage(PAL::SessionID, WebPushMessage&&, CompletionHandler<void(bool)>&& callback)
+void NetworkProcess::processPushMessage(PAL::SessionID, WebPushMessage&&, PushPermissionState, CompletionHandler<void(bool)>&& callback)
{
callback(false);
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (292157 => 292158)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2022-03-31 15:08:16 UTC (rev 292158)
@@ -49,6 +49,7 @@
#include <WebCore/NotificationEventType.h>
#include <WebCore/PageIdentifier.h>
#include <WebCore/PrivateClickMeasurement.h>
+#include <WebCore/PushPermissionState.h>
#include <WebCore/RegistrableDomain.h>
#include <WebCore/ServiceWorkerIdentifier.h>
#include <WebCore/ServiceWorkerTypes.h>
@@ -375,7 +376,7 @@
#if ENABLE(SERVICE_WORKER)
void getPendingPushMessages(PAL::SessionID, CompletionHandler<void(const Vector<WebPushMessage>&)>&&);
- void processPushMessage(PAL::SessionID, WebPushMessage&&, CompletionHandler<void(bool)>&&);
+ void processPushMessage(PAL::SessionID, WebPushMessage&&, WebCore::PushPermissionState, CompletionHandler<void(bool)>&&);
void processNotificationEvent(WebCore::NotificationData&&, WebCore::NotificationEventType);
#endif
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (292157 => 292158)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2022-03-31 15:08:16 UTC (rev 292158)
@@ -212,7 +212,7 @@
#if ENABLE(SERVICE_WORKER)
GetPendingPushMessages(PAL::SessionID sessionID) -> (Vector<WebKit::WebPushMessage> messages)
- ProcessPushMessage(PAL::SessionID sessionID, struct WebKit::WebPushMessage pushMessage) -> (bool didSucceed)
+ ProcessPushMessage(PAL::SessionID sessionID, struct WebKit::WebPushMessage pushMessage, enum:uint8_t WebCore::PushPermissionState pushPermissionState) -> (bool didSucceed)
ProcessNotificationEvent(struct WebCore::NotificationData data, enum:bool WebCore::NotificationEventType eventType)
#endif
DeletePushAndNotificationRegistration(PAL::SessionID sessionID, struct WebCore::SecurityOriginData origin) -> (String errorMessage)
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (292157 => 292158)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2022-03-31 15:08:16 UTC (rev 292158)
@@ -50,6 +50,7 @@
#include "StorageAccessStatus.h"
#include "WebCompiledContentRuleList.h"
#include "WebCookieManagerProxy.h"
+#include "WebNotificationManagerProxy.h"
#include "WebPageMessages.h"
#include "WebPageProxy.h"
#include "WebProcessMessages.h"
@@ -62,6 +63,7 @@
#include "WebsiteDataStoreClient.h"
#include "WebsiteDataStoreParameters.h"
#include <WebCore/ClientOrigin.h>
+#include <WebCore/PushPermissionState.h>
#include <WebCore/RegistrableDomain.h>
#include <WebCore/ResourceError.h>
#include <wtf/CallbackAggregator.h>
@@ -1761,7 +1763,19 @@
void NetworkProcessProxy::processPushMessage(PAL::SessionID sessionID, const WebPushMessage& pushMessage, CompletionHandler<void(bool wasProcessed)>&& callback)
{
- sendWithAsyncReply(Messages::NetworkProcess::ProcessPushMessage { sessionID, pushMessage }, WTFMove(callback));
+ auto permission = PushPermissionState::Prompt;
+ auto permissions = WebNotificationManagerProxy::sharedServiceWorkerManager().notificationPermissions();
+ auto origin = SecurityOriginData::fromURL(pushMessage.registrationURL).toString();
+
+ if (auto it = permissions.find(origin); it != permissions.end())
+ permission = it->value ? PushPermissionState::Granted : PushPermissionState::Denied;
+
+ if (permission == PushPermissionState::Denied) {
+ callback(false);
+ return;
+ }
+
+ sendWithAsyncReply(Messages::NetworkProcess::ProcessPushMessage { sessionID, pushMessage, permission }, WTFMove(callback));
}
void NetworkProcessProxy::processNotificationEvent(const NotificationData& data, NotificationEventType eventType)
Modified: trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp (292157 => 292158)
--- trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp 2022-03-31 15:08:16 UTC (rev 292158)
@@ -34,7 +34,9 @@
#include "WebPageProxy.h"
#include "WebProcessPool.h"
#include "WebProcessProxy.h"
+#include "WebsiteDataStore.h"
#include <WebCore/NotificationData.h>
+#include <WebCore/SecurityOriginData.h>
namespace WebKit {
using namespace WebCore;
@@ -280,25 +282,69 @@
processPool()->sendToAllProcesses(Messages::WebNotificationManager::DidUpdateNotificationDecision(origin->securityOrigin().toString(), allowed));
}
-void WebNotificationManagerProxy::providerDidRemoveNotificationPolicies(API::Array* origins)
+static void removePushSubscriptionsForOrigins(const Vector<WebCore::SecurityOriginData>& origins)
{
- if (!processPool())
+ RefPtr<NetworkProcessProxy> networkProcess;
+ auto sessionID = PAL::SessionID::defaultSessionID();
+
+ WebsiteDataStore::forEachWebsiteDataStore([&networkProcess, &sessionID](WebsiteDataStore& dataStore) {
+ if (!networkProcess && dataStore.isPersistent()) {
+ networkProcess = &dataStore.networkProcess();
+ sessionID = dataStore.sessionID();
+ }
+ });
+
+ if (!networkProcess)
return;
+ for (auto& origin : origins)
+ networkProcess->deletePushAndNotificationRegistration(sessionID, origin, [originString = origin.toString()](auto&&) { });
+}
+
+static Vector<WebCore::SecurityOriginData> apiArrayToSecurityOrigins(API::Array* origins)
+{
+ if (!origins)
+ return { };
+
+ Vector<WebCore::SecurityOriginData> securityOrigins;
size_t size = origins->size();
- if (!size)
- return;
-
+ securityOrigins.reserveInitialCapacity(size);
+
+ for (size_t i = 0; i < size; ++i)
+ securityOrigins.uncheckedAppend(origins->at<API::SecurityOrigin>(i)->securityOrigin());
+
+ return securityOrigins;
+}
+
+static Vector<String> apiArrayToSecurityOriginStrings(API::Array* origins)
+{
+ if (!origins)
+ return { };
+
Vector<String> originStrings;
+ size_t size = origins->size();
originStrings.reserveInitialCapacity(size);
+
for (size_t i = 0; i < size; ++i)
originStrings.uncheckedAppend(origins->at<API::SecurityOrigin>(i)->securityOrigin().toString());
- WebProcessPool::sendToAllRemoteWorkerProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(originStrings));
+ return originStrings;
+}
- if (!processPool())
+void WebNotificationManagerProxy::providerDidRemoveNotificationPolicies(API::Array* origins)
+{
+ size_t size = origins->size();
+ if (!size)
return;
- processPool()->sendToAllProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(originStrings));
+
+ if (this == &sharedServiceWorkerManager()) {
+ removePushSubscriptionsForOrigins(apiArrayToSecurityOrigins(origins));
+ WebProcessPool::sendToAllRemoteWorkerProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(apiArrayToSecurityOriginStrings(origins)));
+ return;
+ }
+
+ if (processPool())
+ processPool()->sendToAllProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(apiArrayToSecurityOriginStrings(origins)));
}
} // namespace WebKit
Modified: trunk/Source/WebKit/webpushd/WebPushDaemon.mm (292157 => 292158)
--- trunk/Source/WebKit/webpushd/WebPushDaemon.mm 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Source/WebKit/webpushd/WebPushDaemon.mm 2022-03-31 15:08:16 UTC (rev 292158)
@@ -499,7 +499,18 @@
return;
}
- connection->enqueueAppBundleRequest(makeUnique<AppBundleDeletionRequest>(*connection, originString, WTFMove(replySender)));
+ connection->enqueueAppBundleRequest(makeUnique<AppBundleDeletionRequest>(*connection, originString, [this, originString = String { originString }, replySender = WTFMove(replySender), bundleIdentifier = connection->hostAppCodeSigningIdentifier()](auto result) mutable {
+ runAfterStartingPushService([this, bundleIdentifier = WTFMove(bundleIdentifier), originString = WTFMove(originString), replySender = WTFMove(replySender), result]() mutable {
+ if (!m_pushService) {
+ replySender(result);
+ return;
+ }
+
+ m_pushService->removeRecordsForBundleIdentifierAndOrigin(bundleIdentifier, originString, [replySender = WTFMove(replySender), result](auto&&) mutable {
+ replySender(result);
+ });
+ });
+ }));
}
void Daemon::setDebugModeIsEnabled(ClientConnection* clientConnection, bool enabled)
Modified: trunk/Tools/ChangeLog (292157 => 292158)
--- trunk/Tools/ChangeLog 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Tools/ChangeLog 2022-03-31 15:08:16 UTC (rev 292158)
@@ -1,3 +1,24 @@
+2022-03-31 Ben Nham <n...@apple.com>
+
+ Remove push subscriptions when permissions are reset
+ https://bugs.webkit.org/show_bug.cgi?id=238068
+
+ Reviewed by Youenn Fablet.
+
+ Add a test to make sure push subscriptions are removed when the notification policy for a
+ website is reset.
+
+ Also fixed an issue with a PushAPI test that didn't properly register for notification permissions.
+
+ * TestWebKitAPI/TestNotificationProvider.cpp:
+ (TestWebKitAPI::TestNotificationProvider::TestNotificationProvider):
+ (TestWebKitAPI::TestNotificationProvider::notificationPermissions const):
+ (TestWebKitAPI::TestNotificationProvider::setPermission):
+ (TestWebKitAPI::TestNotificationProvider::resetPermission):
+ * TestWebKitAPI/TestNotificationProvider.h:
+ * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:
+ * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
+
2022-03-31 Chris Dumez <cdu...@apple.com>
Drop bad adoptNS() in NetworkProcess.LaunchOnlyWhenNecessary
Modified: trunk/Tools/TestWebKitAPI/TestNotificationProvider.cpp (292157 => 292158)
--- trunk/Tools/TestWebKitAPI/TestNotificationProvider.cpp 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Tools/TestWebKitAPI/TestNotificationProvider.cpp 2022-03-31 15:08:16 UTC (rev 292158)
@@ -27,6 +27,8 @@
#include "TestNotificationProvider.h"
#include "WTFStringUtilities.h"
+#include <WebKit/WKArray.h>
+#include <WebKit/WKMutableDictionary.h>
#include <WebKit/WKNotificationManager.h>
#include <WebKit/WKNumber.h>
#include <WebKit/WKSecurityOriginRef.h>
@@ -42,7 +44,6 @@
TestNotificationProvider::TestNotificationProvider(Vector<WKNotificationManagerRef>&& managers)
: m_managers(WTFMove(managers))
- , m_permissions(adoptWK(WKMutableDictionaryCreate()))
{
m_provider = {
{ 0, this },
@@ -67,19 +68,39 @@
WKDictionaryRef TestNotificationProvider::notificationPermissions() const
{
- WKRetain(m_permissions.get());
- return m_permissions.get();
+ auto permissions = WKMutableDictionaryCreate();
+
+ for (auto& [origin, allowed] : m_permissions) {
+ auto wkOriginString = adoptWK(WKStringCreateWithUTF8CString(origin.utf8().data()));
+ auto wkAllowed = adoptWK(WKBooleanCreate(allowed));
+ WKDictionarySetItem(permissions, wkOriginString.get(), wkAllowed.get());
+ }
+
+ return permissions;
}
void TestNotificationProvider::setPermission(const String& origin, bool allowed)
{
- auto wkAllowed = adoptWK(WKBooleanCreate(allowed));
+ m_permissions.set(origin, allowed);
+
auto wkOriginString = adoptWK(WKStringCreateWithUTF8CString(origin.utf8().data()));
- WKDictionarySetItem(m_permissions.get(), wkOriginString.get(), wkAllowed.get());
+ auto wkOrigin = adoptWK(WKSecurityOriginCreateFromString(wkOriginString.get()));
- auto wkOrigin = adoptWK(WKSecurityOriginCreateFromString(wkOriginString.get()));
for (auto& manager : m_managers)
WKNotificationManagerProviderDidUpdateNotificationPolicy(manager, wkOrigin.get(), allowed);
}
+void TestNotificationProvider::resetPermission(const String& origin)
+{
+ m_permissions.remove(origin);
+
+ auto wkOriginString = adoptWK(WKStringCreateWithUTF8CString(origin.utf8().data()));
+ auto wkOrigin = adoptWK(WKSecurityOriginCreateFromString(wkOriginString.get()));
+ auto wkOriginTypeRef = static_cast<WKTypeRef>(wkOrigin.get());
+ auto wkOriginArray = adoptWK(WKArrayCreate(&wkOriginTypeRef, 1));
+
+ for (auto& manager : m_managers)
+ WKNotificationManagerProviderDidRemoveNotificationPolicies(manager, wkOriginArray.get());
+}
+
} // namespace TestWebKitAPI
Modified: trunk/Tools/TestWebKitAPI/TestNotificationProvider.h (292157 => 292158)
--- trunk/Tools/TestWebKitAPI/TestNotificationProvider.h 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Tools/TestWebKitAPI/TestNotificationProvider.h 2022-03-31 15:08:16 UTC (rev 292158)
@@ -25,11 +25,11 @@
#pragma once
-#include <WebKit/WKMutableDictionary.h>
#include <WebKit/WKNotificationManager.h>
#include <WebKit/WKNotificationProvider.h>
#include <WebKit/WKRetainPtr.h>
#include <wtf/FastMalloc.h>
+#include <wtf/HashMap.h>
#include <wtf/Vector.h>
namespace TestWebKitAPI {
@@ -42,10 +42,11 @@
WKDictionaryRef notificationPermissions() const;
void setPermission(const String& origin, bool allowed);
+ void resetPermission(const String& origin);
private:
Vector<WKNotificationManagerRef> m_managers;
- WKRetainPtr<WKMutableDictionaryRef> m_permissions;
+ HashMap<String, bool> m_permissions;
WKNotificationProviderV0 m_provider;
};
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm (292157 => 292158)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm 2022-03-31 15:08:16 UTC (rev 292158)
@@ -336,6 +336,9 @@
configuration.get().websiteDataStore = dataStore.get();
clearWebsiteDataStore([configuration websiteDataStore]);
+ auto provider = TestWebKitAPI::TestNotificationProvider({ [[configuration processPool] _notificationManagerForTesting], WKNotificationManagerGetSharedServiceWorkerNotificationManager() });
+ provider.setPermission(server.origin(), true);
+
auto messageHandler = adoptNS([[PushAPIMessageHandlerWithExpectedMessage alloc] init]);
[[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm (292157 => 292158)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm 2022-03-31 13:56:29 UTC (rev 292157)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm 2022-03-31 15:08:16 UTC (rev 292158)
@@ -869,6 +869,56 @@
ASSERT_FALSE(hasPushSubscription());
}
+TEST_F(WebPushDTest, UnsubscribesOnPermissionReset)
+{
+ static const char* source = R"HTML(
+ <script src=""
+ <script>
+ navigator.serviceWorker.register('/sw.js').then(async () => {
+ const registration = await navigator.serviceWorker.ready;
+ let result = null;
+ try {
+ let subscription = await registration.pushManager.subscribe({
+ userVisibleOnly: true,
+ applicationServerKey: VALID_SERVER_KEY
+ });
+ result = "Subscribed";
+ } catch (e) {
+ result = "Error: " + e;
+ }
+ window.webkit.messageHandlers.note.postMessage(result);
+ });
+ </script>
+ )HTML";
+
+ __block RetainPtr<id> result = nil;
+ __block bool done = false;
+ [m_notificationMessageHandler setMessageHandler:^(id message) {
+ result = message;
+ done = true;
+ }];
+
+ loadRequest(source, "");
+ TestWebKitAPI::Util::run(&done);
+
+ ASSERT_TRUE([result isEqualToString:@"Subscribed"]);
+ ASSERT_TRUE(hasPushSubscription());
+
+ m_notificationProvider->resetPermission(m_server->origin());
+
+ bool isSubscribed = true;
+ TestWebKitAPI::Util::waitForConditionWithLogging([this, &isSubscribed] {
+ isSubscribed = hasPushSubscription();
+ if (!isSubscribed)
+ return true;
+
+ sleep(1);
+ return false;
+ }, 5, @"Timed out waiting for push subscription to be removed.");
+
+ ASSERT_FALSE(isSubscribed);
+}
+
#if ENABLE(INSTALL_COORDINATION_BUNDLES)
#if USE(APPLE_INTERNAL_SDK)
static void deleteAllRegistrationsForDataStore(WKWebsiteDataStore *dataStore)