Title: [292218] trunk
Revision
292218
Author
[email protected]
Date
2022-04-01 06:12:02 -0700 (Fri, 01 Apr 2022)

Log Message

ServiceWorkerRegistration.getNotifications should list all persistent notifications
https://bugs.webkit.org/show_bug.cgi?id=238544

Reviewed by Darin Adler.

Source/WebCore:

Remove context based notification list since the list is global.
Add creation time to notification data.
Instead of reading the list locally, use the SWClient connection to get it.

Covered by updated test.

* Modules/notifications/Notification.cpp:
* Modules/notifications/Notification.h:
* Modules/notifications/NotificationData.h:
* workers/service/SWClientConnection.h:
* workers/service/ServiceWorkerContainer.cpp:
* workers/service/ServiceWorkerContainer.h:
* workers/service/ServiceWorkerRegistration.cpp:
* workers/service/ServiceWorkerRegistration.h:
* workers/service/ServiceWorkerRegistration.idl:
* workers/service/WorkerSWClientConnection.cpp:
* workers/service/WorkerSWClientConnection.h:

Source/WebKit:

Go from WebProcess to UIProcess to read the notification map through IPC messaging.
Filter out the notifications according tag, origin and session.
Sort the notifications according creationTime with UIProcess identifier as tie breaker.

* UIProcess/Notifications/WebNotificationManagerProxy.cpp:
* UIProcess/Notifications/WebNotificationManagerProxy.h:
* UIProcess/WebProcessProxy.cpp:
* UIProcess/WebProcessProxy.h:
* UIProcess/WebProcessProxy.messages.in:
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
* WebProcess/Notifications/WebNotificationManager.cpp:
* WebProcess/Storage/WebSWClientConnection.cpp:
* WebProcess/Storage/WebSWClientConnection.h:

LayoutTests:

* http/tests/workers/service/getnotifications-expected.txt:
* http/tests/workers/service/getnotifications.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (292217 => 292218)


--- trunk/LayoutTests/ChangeLog	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/LayoutTests/ChangeLog	2022-04-01 13:12:02 UTC (rev 292218)
@@ -1,5 +1,15 @@
 2022-04-01  Youenn Fablet  <[email protected]>
 
+        ServiceWorkerRegistration.getNotifications should list all persistent notifications
+        https://bugs.webkit.org/show_bug.cgi?id=238544
+
+        Reviewed by Darin Adler.
+
+        * http/tests/workers/service/getnotifications-expected.txt:
+        * http/tests/workers/service/getnotifications.html:
+
+2022-04-01  Youenn Fablet  <[email protected]>
+
         Notification should be exposed to ServiceWorker contexts
         https://bugs.webkit.org/show_bug.cgi?id=238548
 

Modified: trunk/LayoutTests/http/tests/workers/service/getnotifications-expected.txt (292217 => 292218)


--- trunk/LayoutTests/http/tests/workers/service/getnotifications-expected.txt	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/LayoutTests/http/tests/workers/service/getnotifications-expected.txt	2022-04-01 13:12:02 UTC (rev 292218)
@@ -37,6 +37,11 @@
 Body: Body3
 Tag: tag-b
 
+Retrieving notifications from page registration object - 3
+Notification: Hello / Body1 / tag-a
+Notification: There / Body2 / tag-b
+Notification: Buddy / Body3 / tag-b
+Retrieving notifications from page registration object - end
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/http/tests/workers/service/getnotifications.html (292217 => 292218)


--- trunk/LayoutTests/http/tests/workers/service/getnotifications.html	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/LayoutTests/http/tests/workers/service/getnotifications.html	2022-04-01 13:12:02 UTC (rev 292218)
@@ -2,7 +2,6 @@
 <script src=""
 <script src=""
 <script>
-
 function failTheTest(msg)
 {
     testFailed(msg);
@@ -19,8 +18,9 @@
 
 shouldBeEqualToString("Notification.permission", "granted");
 
+var registration;
 async function registerServiceWorker() {
-    var registration = await navigator.serviceWorker.register('resources/shownotification-worker.js');
+    registration = await navigator.serviceWorker.register('resources/shownotification-worker.js');
     
     if (!registration)
         return testFailed("No registration");
@@ -44,7 +44,7 @@
 var numberShown = 0;
 var numberGot = 0;
 
-function gotNotes(event)
+async function gotNotes(event)
 {
     ++numberGot;
 
@@ -58,6 +58,13 @@
         event.source.postMessage("tryshow|There|Body2|tag-b");
         event.source.postMessage("tryshow|Buddy|Body3|tag-b");
     } else if (numberGot == 4) {
+        const notifications = await registration.getNotifications({ tag: "" });
+        debug("Retrieving notifications from page registration object - " + notifications.length);
+        notifications.forEach(notification => {
+            debug("Notification: " + notification.title + " / " + notification.body + " / " + notification.tag);
+        });    
+        debug("Retrieving notifications from page registration object - end");
+
         testCompleted();
     }
 }

Modified: trunk/Source/WebCore/ChangeLog (292217 => 292218)


--- trunk/Source/WebCore/ChangeLog	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/ChangeLog	2022-04-01 13:12:02 UTC (rev 292218)
@@ -1,5 +1,30 @@
 2022-04-01  Youenn Fablet  <[email protected]>
 
+        ServiceWorkerRegistration.getNotifications should list all persistent notifications
+        https://bugs.webkit.org/show_bug.cgi?id=238544
+
+        Reviewed by Darin Adler.
+
+        Remove context based notification list since the list is global.
+        Add creation time to notification data.
+        Instead of reading the list locally, use the SWClient connection to get it.
+
+        Covered by updated test.
+
+        * Modules/notifications/Notification.cpp:
+        * Modules/notifications/Notification.h:
+        * Modules/notifications/NotificationData.h:
+        * workers/service/SWClientConnection.h:
+        * workers/service/ServiceWorkerContainer.cpp:
+        * workers/service/ServiceWorkerContainer.h:
+        * workers/service/ServiceWorkerRegistration.cpp:
+        * workers/service/ServiceWorkerRegistration.h:
+        * workers/service/ServiceWorkerRegistration.idl:
+        * workers/service/WorkerSWClientConnection.cpp:
+        * workers/service/WorkerSWClientConnection.h:
+
+2022-04-01  Youenn Fablet  <[email protected]>
+
         Notification should be exposed to ServiceWorker contexts
         https://bugs.webkit.org/show_bug.cgi?id=238548
 

Modified: trunk/Source/WebCore/Modules/notifications/Notification.cpp (292217 => 292218)


--- trunk/Source/WebCore/Modules/notifications/Notification.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/Modules/notifications/Notification.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -94,10 +94,9 @@
 {
     if (context.isDocument())
         m_notificationSource = NotificationSource::Document;
-    else if (context.isServiceWorkerGlobalScope()) {
+    else if (context.isServiceWorkerGlobalScope())
         m_notificationSource = NotificationSource::ServiceWorker;
-        downcast<ServiceWorkerGlobalScope>(context).registration().addNotificationToList(*this);
-    } else
+    else
         RELEASE_ASSERT_NOT_REACHED();
 
     if (!options.icon.isEmpty()) {
@@ -124,10 +123,6 @@
 
 Notification::~Notification()
 {
-    if (auto* context = scriptExecutionContext()) {
-        if (context->isServiceWorkerGlobalScope())
-            downcast<ServiceWorkerGlobalScope>(context)->registration().removeNotificationFromList(*this);
-    }
 }
 
 Ref<Notification> Notification::copyForGetNotifications() const
@@ -135,17 +130,6 @@
     return adoptRef(*new Notification(*this));
 }
 
-void Notification::contextDestroyed()
-{
-    auto* context = scriptExecutionContext();
-    RELEASE_ASSERT(context);
-    if (context->isServiceWorkerGlobalScope())
-        downcast<ServiceWorkerGlobalScope>(context)->registration().removeNotificationFromList(*this);
-
-    ActiveDOMObject::contextDestroyed();
-}
-
-
 void Notification::showSoon()
 {
     queueTaskKeepingObjectAlive(*this, TaskSource::UserInteraction, [this] {
@@ -191,15 +175,10 @@
     switch (m_state) {
     case Idle:
         break;
-    case Showing: {
+    case Showing:
         if (auto* client = clientFromContext())
             client->cancel(*this);
-        if (auto* context = scriptExecutionContext()) {
-            if (context->isServiceWorkerGlobalScope())
-                downcast<ServiceWorkerGlobalScope>(context)->registration().removeNotificationFromList(*this);
-        }
         break;
-    }
     case Closed:
         break;
     }
@@ -346,6 +325,7 @@
         m_serviceWorkerRegistrationURL.isolatedCopy(),
         identifier(),
         *sessionID,
+        MonotonicTime::now()
     };
 }
 

Modified: trunk/Source/WebCore/Modules/notifications/Notification.h (292217 => 292218)


--- trunk/Source/WebCore/Modules/notifications/Notification.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/Modules/notifications/Notification.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -112,8 +112,6 @@
     Notification(ScriptExecutionContext&, String&& title, Options&&);
     Notification(const Notification&);
 
-    void contextDestroyed() final;
-
     NotificationClient* clientFromContext();
     EventTargetInterface eventTargetInterface() const final { return NotificationEventTargetInterfaceType; }
 

Modified: trunk/Source/WebCore/Modules/notifications/NotificationData.cpp (292217 => 292218)


--- trunk/Source/WebCore/Modules/notifications/NotificationData.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/Modules/notifications/NotificationData.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -30,12 +30,12 @@
 
 NotificationData NotificationData::isolatedCopy() const &
 {
-    return { title.isolatedCopy(), body.isolatedCopy(), iconURL.isolatedCopy(), tag.isolatedCopy(), language.isolatedCopy(), direction, originString.isolatedCopy(), serviceWorkerRegistrationURL.isolatedCopy(), notificationID, sourceSession };
+    return { title.isolatedCopy(), body.isolatedCopy(), iconURL.isolatedCopy(), tag.isolatedCopy(), language.isolatedCopy(), direction, originString.isolatedCopy(), serviceWorkerRegistrationURL.isolatedCopy(), notificationID, sourceSession, creationTime };
 }
 
 NotificationData NotificationData::isolatedCopy() &&
 {
-    return { WTFMove(title).isolatedCopy(), WTFMove(body).isolatedCopy(), WTFMove(iconURL).isolatedCopy(), WTFMove(tag).isolatedCopy(), WTFMove(language).isolatedCopy(), direction, WTFMove(originString).isolatedCopy(), WTFMove(serviceWorkerRegistrationURL).isolatedCopy(), notificationID, sourceSession };
+    return { WTFMove(title).isolatedCopy(), WTFMove(body).isolatedCopy(), WTFMove(iconURL).isolatedCopy(), WTFMove(tag).isolatedCopy(), WTFMove(language).isolatedCopy(), direction, WTFMove(originString).isolatedCopy(), WTFMove(serviceWorkerRegistrationURL).isolatedCopy(), notificationID, sourceSession, creationTime };
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/notifications/NotificationData.h (292217 => 292218)


--- trunk/Source/WebCore/Modules/notifications/NotificationData.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/Modules/notifications/NotificationData.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -27,6 +27,7 @@
 
 #include <optional>
 #include <pal/SessionID.h>
+#include <wtf/MonotonicTime.h>
 #include <wtf/URL.h>
 #include <wtf/UUID.h>
 #include <wtf/text/WTFString.h>
@@ -52,12 +53,13 @@
     URL serviceWorkerRegistrationURL;
     UUID notificationID;
     PAL::SessionID sourceSession;
+    MonotonicTime creationTime;
 };
 
 template<class Encoder>
 void NotificationData::encode(Encoder& encoder) const
 {
-    encoder << title << body << iconURL << tag << language << direction << originString << serviceWorkerRegistrationURL << notificationID << sourceSession;
+    encoder << title << body << iconURL << tag << language << direction << originString << serviceWorkerRegistrationURL << notificationID << sourceSession << creationTime;
 }
 
 template<class Decoder>
@@ -113,6 +115,11 @@
     if (!sourceSession)
         return std::nullopt;
 
+    std::optional<MonotonicTime> creationTime;
+    decoder >> creationTime;
+    if (!creationTime)
+        return std::nullopt;
+
     return { {
         WTFMove(*title),
         WTFMove(*body),
@@ -124,6 +131,7 @@
         WTFMove(*serviceWorkerRegistrationURL),
         WTFMove(*notificationID),
         WTFMove(*sourceSession),
+        WTFMove(*creationTime)
     } };
 }
 

Modified: trunk/Source/WebCore/workers/service/SWClientConnection.h (292217 => 292218)


--- trunk/Source/WebCore/workers/service/SWClientConnection.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/SWClientConnection.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -29,6 +29,7 @@
 
 #include "ExceptionOr.h"
 #include "NavigationPreloadState.h"
+#include "NotificationData.h"
 #include "PushPermissionState.h"
 #include "PushSubscriptionData.h"
 #include "ScriptExecutionContextIdentifier.h"
@@ -42,6 +43,7 @@
 
 class ResourceError;
 class SecurityOrigin;
+class ScriptExecutionContext;
 class SerializedScriptValue;
 class ServiceWorkerContainer;
 class ServiceWorkerRegistration;
@@ -50,6 +52,7 @@
 enum class ShouldNotifyWhenResolved : bool;
 struct ExceptionData;
 struct MessageWithMessagePorts;
+struct NotificationData;
 struct ServiceWorkerClientData;
 struct ServiceWorkerData;
 struct ServiceWorkerRegistrationData;
@@ -101,6 +104,9 @@
     using GetPushPermissionStateCallback = CompletionHandler<void(ExceptionOr<PushPermissionState>&&)>;
     virtual void getPushPermissionState(ServiceWorkerRegistrationIdentifier, GetPushPermissionStateCallback&&) = 0;
 
+    using GetNotificationsCallback = CompletionHandler<void(ExceptionOr<Vector<NotificationData>>&&)>;
+    virtual void getNotifications(const URL&, const String&, GetNotificationsCallback&&) = 0;
+
     using ExceptionOrVoidCallback = CompletionHandler<void(ExceptionOr<void>&&)>;
     virtual void enableNavigationPreload(ServiceWorkerRegistrationIdentifier, ExceptionOrVoidCallback&&) = 0;
     virtual void disableNavigationPreload(ServiceWorkerRegistrationIdentifier, ExceptionOrVoidCallback&&) = 0;

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (292217 => 292218)


--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -610,6 +610,28 @@
     });
 }
 
+#if ENABLE(NOTIFICATIONS)
+void ServiceWorkerContainer::getNotifications(const URL& serviceWorkerRegistrationURL, const String& tag, DOMPromiseDeferred<IDLSequence<IDLInterface<Notification>>>&& promise)
+{
+    ensureSWClientConnection().getNotifications(serviceWorkerRegistrationURL, tag, [promise = WTFMove(promise), protectedThis = Ref { *this }](auto&& result) mutable {
+        auto* context = protectedThis->scriptExecutionContext();
+        if (!context)
+            return;
+
+        if (result.hasException()) {
+            promise.reject(result.releaseException());
+            return;
+        }
+
+        auto data = ""
+        auto notifications = map(data, [context](auto&& data) {
+            return Notification::create(*context, WTFMove(data));
+        });
+        promise.resolve(WTFMove(notifications));
+    });
+}
+#endif
+
 void ServiceWorkerContainer::queueTaskToDispatchControllerChangeEvent()
 {
     ASSERT(m_creationThread.ptr() == &Thread::current());

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (292217 => 292218)


--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -91,6 +91,9 @@
     void unsubscribeFromPushService(ServiceWorkerRegistrationIdentifier, PushSubscriptionIdentifier, DOMPromiseDeferred<IDLBoolean>&&);
     void getPushSubscription(ServiceWorkerRegistration&, DOMPromiseDeferred<IDLNullable<IDLInterface<PushSubscription>>>&&);
     void getPushPermissionState(ServiceWorkerRegistrationIdentifier, DOMPromiseDeferred<IDLEnumeration<PushPermissionState>>&&);
+#if ENABLE(NOTIFICATIONS)
+    void getNotifications(const URL&, const String&, DOMPromiseDeferred<IDLSequence<IDLInterface<Notification>>>&&);
+#endif
 
     ServiceWorkerJob* job(ServiceWorkerJobIdentifier);
 

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp (292217 => 292218)


--- trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -300,49 +300,10 @@
     });
 }
 
-void ServiceWorkerRegistration::getNotifications(ScriptExecutionContext& context, const GetNotificationOptions& filter, DOMPromiseDeferred<IDLSequence<IDLInterface<Notification>>> promise)
+void ServiceWorkerRegistration::getNotifications(const GetNotificationOptions& filter, DOMPromiseDeferred<IDLSequence<IDLInterface<Notification>>> promise)
 {
-    auto notifications = filteredNotificationList(filter.tag);
-    context.eventLoop().queueTask(TaskSource::DOMManipulation, [promise = WTFMove(promise), notifications = WTFMove(notifications)]() mutable {
-        promise.resolve(WTFMove(notifications));
-    });
+    m_container->getNotifications(m_registrationData.scopeURL, filter.tag, WTFMove(promise));
 }
-
-void ServiceWorkerRegistration::addNotificationToList(Notification& notification)
-{
-    // A Notification at this exact address might previously have been in the list but not successfully removed.
-    // The WeakHashSet captures that possibility here to help us maintain consistency.
-    auto iter = m_notificationList.find(&notification);
-    if (iter != m_notificationList.end()) {
-        RELEASE_ASSERT(!m_notificationSet.contains(notification));
-        m_notificationList.remove(iter);
-    }
-
-    m_notificationList.add(&notification);
-    auto result = m_notificationSet.add(notification);
-    ASSERT_UNUSED(result, result.isNewEntry);
-}
-
-void ServiceWorkerRegistration::removeNotificationFromList(Notification& notification)
-{
-    // The same notification might try to remove itself from this list more than once, and that's fine.
-    m_notificationList.remove(&notification);
-    m_notificationSet.remove(notification);
-}
-
-Vector<Ref<Notification>> ServiceWorkerRegistration::filteredNotificationList(const String& filteredTag)
-{
-    Vector<Ref<Notification>> results;
-    for (auto* notification : m_notificationList) {
-        if (!m_notificationSet.contains(*notification))
-            continue;
-        if (filteredTag.isEmpty() || notification->tag() == filteredTag)
-            results.append(notification->copyForGetNotifications());
-    }
-
-    return results;
-}
-
 #endif // ENABLE(NOTIFICATION_EVENT)
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.h (292217 => 292218)


--- trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -100,11 +100,7 @@
     };
 
     void showNotification(ScriptExecutionContext&, String&& title, NotificationOptions&&, DOMPromiseDeferred<void>&&);
-    void getNotifications(ScriptExecutionContext&, const GetNotificationOptions& filter, DOMPromiseDeferred<IDLSequence<IDLInterface<Notification>>>);
-
-    void addNotificationToList(Notification&);
-    void removeNotificationFromList(Notification&);
-    Vector<Ref<Notification>> filteredNotificationList(const String& filteredTag);
+    void getNotifications(const GetNotificationOptions& filter, DOMPromiseDeferred<IDLSequence<IDLInterface<Notification>>>);
 #endif
 
 private:
@@ -128,11 +124,6 @@
     RefPtr<ServiceWorker> m_activeWorker;
 
     std::unique_ptr<NavigationPreloadManager> m_navigationPreload;
-
-#if ENABLE(NOTIFICATION_EVENT)
-    ListHashSet<Notification*> m_notificationList;
-    WeakHashSet<Notification> m_notificationSet;
-#endif
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.idl (292217 => 292218)


--- trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.idl	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.idl	2022-04-01 13:12:02 UTC (rev 292218)
@@ -46,7 +46,7 @@
     [NewObject] Promise<boolean> unregister();
 
     [Conditional=NOTIFICATION_EVENT, EnabledAtRuntime=NotificationEventEnabled, CallWith=CurrentScriptExecutionContext] Promise<undefined> showNotification(DOMString title, optional NotificationOptions options);
-    [Conditional=NOTIFICATION_EVENT, EnabledAtRuntime=NotificationEventEnabled, CallWith=CurrentScriptExecutionContext] Promise<sequence<Notification>> getNotifications(optional GetNotificationOptions filter);
+    [Conditional=NOTIFICATION_EVENT, EnabledAtRuntime=NotificationEventEnabled] Promise<sequence<Notification>> getNotifications(optional GetNotificationOptions filter);
 
     // event
     attribute EventHandler onupdatefound;

Modified: trunk/Source/WebCore/workers/service/WorkerSWClientConnection.cpp (292217 => 292218)


--- trunk/Source/WebCore/workers/service/WorkerSWClientConnection.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/WorkerSWClientConnection.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -28,6 +28,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "NotificationData.h"
 #include "SecurityOrigin.h"
 #include "ServiceWorkerClientData.h"
 #include "ServiceWorkerJobData.h"
@@ -79,8 +80,12 @@
         callback(Exception { AbortError, "context stopped"_s });
 
     auto navigationPreloadStateCallbacks = WTFMove(m_navigationPreloadStateCallbacks);
-    for (auto& callback : m_navigationPreloadStateCallbacks.values())
+    for (auto& callback : navigationPreloadStateCallbacks.values())
         callback(Exception { AbortError, "context stopped"_s });
+
+    auto getNotificationsCallbacks = WTFMove(m_getNotificationsCallbacks);
+    for (auto& callback : getNotificationsCallbacks.values())
+        callback(Exception { AbortError, "context stopped"_s });
 }
 
 void WorkerSWClientConnection::matchRegistration(SecurityOriginData&& topOrigin, const URL& clientURL, RegistrationCallback&& callback)
@@ -293,6 +298,22 @@
     });
 }
 
+void WorkerSWClientConnection::getNotifications(const URL& serviceWorkerRegistrationURL, const String& tag, GetNotificationsCallback&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_getNotificationsCallbacks.add(requestIdentifier, WTFMove(callback));
+    
+    callOnMainThread([thread = m_thread, requestIdentifier, serviceWorkerRegistrationURL = serviceWorkerRegistrationURL.isolatedCopy(), tag = tag.isolatedCopy()]() mutable {
+        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
+        connection.getNotifications(serviceWorkerRegistrationURL, tag, [thread = WTFMove(thread), requestIdentifier](auto&& result) {
+            thread->runLoop().postTaskForMode([requestIdentifier, result = crossThreadCopy(WTFMove(result))](auto& scope) mutable {
+                auto callback = downcast<WorkerGlobalScope>(scope).swClientConnection().m_getNotificationsCallbacks.take(requestIdentifier);
+                callback(WTFMove(result));
+            }, WorkerRunLoop::defaultMode());
+        });
+    });
+}
+
 void WorkerSWClientConnection::enableNavigationPreload(ServiceWorkerRegistrationIdentifier registrationIdentifier, ExceptionOrVoidCallback&& callback)
 {
     uint64_t requestIdentifier = ++m_lastRequestIdentifier;

Modified: trunk/Source/WebCore/workers/service/WorkerSWClientConnection.h (292217 => 292218)


--- trunk/Source/WebCore/workers/service/WorkerSWClientConnection.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebCore/workers/service/WorkerSWClientConnection.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -61,6 +61,7 @@
     void unsubscribeFromPushService(ServiceWorkerRegistrationIdentifier, PushSubscriptionIdentifier, UnsubscribeFromPushServiceCallback&&) final;
     void getPushSubscription(ServiceWorkerRegistrationIdentifier, GetPushSubscriptionCallback&&) final;
     void getPushPermissionState(ServiceWorkerRegistrationIdentifier, GetPushPermissionStateCallback&&) final;
+    void getNotifications(const URL&, const String&, GetNotificationsCallback&&) final;
 
     void enableNavigationPreload(ServiceWorkerRegistrationIdentifier, ExceptionOrVoidCallback&&) final;
     void disableNavigationPreload(ServiceWorkerRegistrationIdentifier, ExceptionOrVoidCallback&&) final;
@@ -80,6 +81,7 @@
     HashMap<uint64_t, GetPushPermissionStateCallback> m_getPushPermissionStateCallbacks;
     HashMap<uint64_t, ExceptionOrVoidCallback> m_voidCallbacks;
     HashMap<uint64_t, ExceptionOrNavigationPreloadStateCallback> m_navigationPreloadStateCallbacks;
+    HashMap<uint64_t, GetNotificationsCallback> m_getNotificationsCallbacks;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (292217 => 292218)


--- trunk/Source/WebKit/ChangeLog	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/ChangeLog	2022-04-01 13:12:02 UTC (rev 292218)
@@ -1,3 +1,24 @@
+2022-04-01  Youenn Fablet  <[email protected]>
+
+        ServiceWorkerRegistration.getNotifications should list all persistent notifications
+        https://bugs.webkit.org/show_bug.cgi?id=238544
+
+        Reviewed by Darin Adler.
+
+        Go from WebProcess to UIProcess to read the notification map through IPC messaging.
+        Filter out the notifications according tag, origin and session.
+        Sort the notifications according creationTime with UIProcess identifier as tie breaker.
+
+        * UIProcess/Notifications/WebNotificationManagerProxy.cpp:
+        * UIProcess/Notifications/WebNotificationManagerProxy.h:
+        * UIProcess/WebProcessProxy.cpp:
+        * UIProcess/WebProcessProxy.h:
+        * UIProcess/WebProcessProxy.messages.in:
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        * WebProcess/Notifications/WebNotificationManager.cpp:
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        * WebProcess/Storage/WebSWClientConnection.h:
+
 2022-04-01  Carlos Garcia Campos  <[email protected]>
 
         REGRESSION(r290360): [GLX] Crash on process exit

Modified: trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp (292217 => 292218)


--- trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -347,4 +347,24 @@
         processPool()->sendToAllProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(apiArrayToSecurityOriginStrings(origins)));
 }
 
+void WebNotificationManagerProxy::getNotifications(const URL& url, const String& tag, PAL::SessionID sessionID, CompletionHandler<void(Vector<NotificationData>&&)>&& callback)
+{
+    Vector<WebNotification*> notifications;
+    for (auto& notification : m_notifications.values()) {
+        auto& data = ""
+        if (data.serviceWorkerRegistrationURL != url || data.sourceSession != sessionID)
+            continue;
+        if (!tag.isEmpty() && data.tag != tag)
+            continue;
+        notifications.append(notification.ptr());
+    }
+    // Let's sort as per https://notifications.spec.whatwg.org/#dom-serviceworkerregistration-getnotifications.
+    std::sort(notifications.begin(), notifications.end(), [](auto& a, auto& b) {
+        if (a->data().creationTime < b->data().creationTime)
+            return true;
+        return a->data().creationTime == b->data().creationTime && a->identifier() < b->identifier();
+    });
+    callback(map(notifications, [](auto& notification) { return notification->data(); }));
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.h (292217 => 292218)


--- trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -68,6 +68,8 @@
     void clearNotifications(WebPageProxy*, const Vector<UUID>& pageNotificationIDs);
     void didDestroyNotification(WebPageProxy*, const UUID& pageNotificationID);
 
+    void getNotifications(const URL&, const String&, PAL::SessionID, CompletionHandler<void(Vector<WebCore::NotificationData>&&)>&&);
+
     void providerDidShowNotification(uint64_t notificationID);
     void providerDidClickNotification(uint64_t notificationID);
     void providerDidClickNotification(const UUID& notificationID);

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (292217 => 292218)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -2104,6 +2104,11 @@
     PAL::systemBeep();
 }
 
+void WebProcessProxy::getNotifications(const URL& registrationURL, const String& tag, CompletionHandler<void(Vector<NotificationData>&&)>&& callback)
+{
+    WebNotificationManagerProxy::sharedServiceWorkerManager().getNotifications(registrationURL, tag, sessionID(), WTFMove(callback));
+}
+
 } // namespace WebKit
 
 #undef MESSAGE_CHECK

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (292217 => 292218)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -74,6 +74,7 @@
 namespace WebCore {
 class DeferrableOneShotTimer;
 class ResourceRequest;
+struct NotificationData;
 struct PluginInfo;
 struct PrewarmInformation;
 struct SecurityOriginData;
@@ -427,6 +428,7 @@
     void setCaptionDisplayMode(WebCore::CaptionUserPreferences::CaptionDisplayMode);
     void setCaptionLanguage(const String&);
 #endif
+    void getNotifications(const URL&, const String&, CompletionHandler<void(Vector<WebCore::NotificationData>&&)>&&);
 
     WebCore::CrossOriginMode crossOriginMode() const { return m_crossOriginMode; }
     CaptivePortalMode captivePortalMode() const { return m_captivePortalMode; }

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in (292217 => 292218)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in	2022-04-01 13:12:02 UTC (rev 292218)
@@ -91,4 +91,6 @@
     SetCaptionDisplayMode(WebCore::CaptionUserPreferences::CaptionDisplayMode mode)
     SetCaptionLanguage(String language)
 #endif
+
+    GetNotifications(URL registrationURL, String tag) -> (Vector<WebCore::NotificationData> result)
 }

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp (292217 => 292218)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp	2022-04-01 13:12:02 UTC (rev 292218)
@@ -38,7 +38,7 @@
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
 #include "WebProcess.h"
-#include "WebProcessPoolMessages.h"
+#include "WebProcessProxyMessages.h"
 #include "WebSWOriginTable.h"
 #include "WebSWServerConnectionMessages.h"
 #include <WebCore/Document.h>
@@ -269,6 +269,11 @@
     });
 }
 
+void WebSWClientConnection::getNotifications(const URL& registrationURL, const String& tag, GetNotificationsCallback&& callback)
+{
+    WebProcess::singleton().parentProcessConnection()->sendWithAsyncReply(Messages::WebProcessProxy::GetNotifications { registrationURL, tag }, WTFMove(callback));
+}
+
 void WebSWClientConnection::enableNavigationPreload(WebCore::ServiceWorkerRegistrationIdentifier registrationIdentifier, ExceptionOrVoidCallback&& callback)
 {
     sendWithAsyncReply(Messages::WebSWServerConnection::EnableNavigationPreload { registrationIdentifier }, [callback = WTFMove(callback)](auto&& error) mutable {

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h (292217 => 292218)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h	2022-04-01 12:08:06 UTC (rev 292217)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h	2022-04-01 13:12:02 UTC (rev 292218)
@@ -94,6 +94,7 @@
     void unsubscribeFromPushService(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::PushSubscriptionIdentifier, UnsubscribeFromPushServiceCallback&&) final;
     void getPushSubscription(WebCore::ServiceWorkerRegistrationIdentifier, GetPushSubscriptionCallback&&) final;
     void getPushPermissionState(WebCore::ServiceWorkerRegistrationIdentifier, GetPushPermissionStateCallback&&) final;
+    void getNotifications(const URL&, const String&, GetNotificationsCallback&&) final;
 
     void enableNavigationPreload(WebCore::ServiceWorkerRegistrationIdentifier, ExceptionOrVoidCallback&&) final;
     void disableNavigationPreload(WebCore::ServiceWorkerRegistrationIdentifier, ExceptionOrVoidCallback&&) final;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to