Title: [294260] branches/safari-7614.1.14.1-branch
Revision
294260
Author
alanc...@apple.com
Date
2022-05-16 14:21:17 -0700 (Mon, 16 May 2022)

Log Message

Cherry-pick r294225. rdar://problem/92978482

    Make sure calling showNotification will extend the service worker lifetime
    https://bugs.webkit.org/show_bug.cgi?id=240273
    <rdar://92978482>

    Reviewed by Chris Dumez.

    Source/WebCore:

    Update NotificationClient API so that show is taking a completion handler.
    Make use of this completion handler to resolve the promise when the show notification steps are done, as per spec.
    Register push event to ServiceWorkerGlobalScope when the event handlers are called.
    When ServiceWorkerRegistration::show is called during one of the push event handlers,
    extend the push event lifetime by adding the show notification promise to the push event.

    Covered by API test.

    * Modules/notifications/Notification.cpp:
    * Modules/notifications/Notification.h:
    * Modules/notifications/NotificationClient.h:
    * dom/ScriptExecutionContext.cpp:
    * dom/ScriptExecutionContext.h:
    * workers/service/ServiceWorkerGlobalScope.cpp:
    * workers/service/ServiceWorkerGlobalScope.h:
    * workers/service/ServiceWorkerRegistration.cpp:
    * workers/service/ServiceWorkerRegistration.h:
    * workers/service/context/ServiceWorkerThread.cpp:

    Source/WebKit:

    On WebProcess side, implement the new NoficationClient::show API that takes a callback.
    Delay calling this callback until UIProcess tells us so through async IPC.
    On UIProcess side, take a callback and call it when the show notification steps are done.

    * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
    * NetworkProcess/Notifications/NetworkNotificationManager.h:
    * Shared/Notifications/NotificationManagerMessageHandler.h:
    * Shared/Notifications/NotificationManagerMessageHandler.messages.in:
    * UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp:
    * UIProcess/Notifications/ServiceWorkerNotificationHandler.h:
    * UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
    * UIProcess/Notifications/WebNotificationManagerMessageHandler.h:
    * WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp:
    * WebProcess/Notifications/WebNotificationManager.cpp:
    * WebProcess/Notifications/WebNotificationManager.h:
    * WebProcess/WebCoreSupport/WebNotificationClient.cpp:
    * WebProcess/WebCoreSupport/WebNotificationClient.h:

    Source/WebKitLegacy/mac:

    * WebCoreSupport/WebNotificationClient.h:
    * WebCoreSupport/WebNotificationClient.mm:

    Tools:

    * TestWebKitAPI/TestNotificationProvider.cpp:
    * TestWebKitAPI/TestNotificationProvider.h:
    * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:

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

Modified Paths

Diff

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/ChangeLog (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/ChangeLog	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/ChangeLog	2022-05-16 21:21:17 UTC (rev 294260)
@@ -1,5 +1,97 @@
 2022-05-16  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r294225. rdar://problem/92978482
+
+    Make sure calling showNotification will extend the service worker lifetime
+    https://bugs.webkit.org/show_bug.cgi?id=240273
+    <rdar://92978482>
+    
+    Reviewed by Chris Dumez.
+    
+    Source/WebCore:
+    
+    Update NotificationClient API so that show is taking a completion handler.
+    Make use of this completion handler to resolve the promise when the show notification steps are done, as per spec.
+    Register push event to ServiceWorkerGlobalScope when the event handlers are called.
+    When ServiceWorkerRegistration::show is called during one of the push event handlers,
+    extend the push event lifetime by adding the show notification promise to the push event.
+    
+    Covered by API test.
+    
+    * Modules/notifications/Notification.cpp:
+    * Modules/notifications/Notification.h:
+    * Modules/notifications/NotificationClient.h:
+    * dom/ScriptExecutionContext.cpp:
+    * dom/ScriptExecutionContext.h:
+    * workers/service/ServiceWorkerGlobalScope.cpp:
+    * workers/service/ServiceWorkerGlobalScope.h:
+    * workers/service/ServiceWorkerRegistration.cpp:
+    * workers/service/ServiceWorkerRegistration.h:
+    * workers/service/context/ServiceWorkerThread.cpp:
+    
+    Source/WebKit:
+    
+    On WebProcess side, implement the new NoficationClient::show API that takes a callback.
+    Delay calling this callback until UIProcess tells us so through async IPC.
+    On UIProcess side, take a callback and call it when the show notification steps are done.
+    
+    * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
+    * NetworkProcess/Notifications/NetworkNotificationManager.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.messages.in:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.h:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.h:
+    * WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp:
+    * WebProcess/Notifications/WebNotificationManager.cpp:
+    * WebProcess/Notifications/WebNotificationManager.h:
+    * WebProcess/WebCoreSupport/WebNotificationClient.cpp:
+    * WebProcess/WebCoreSupport/WebNotificationClient.h:
+    
+    Source/WebKitLegacy/mac:
+    
+    * WebCoreSupport/WebNotificationClient.h:
+    * WebCoreSupport/WebNotificationClient.mm:
+    
+    Tools:
+    
+    * TestWebKitAPI/TestNotificationProvider.cpp:
+    * TestWebKitAPI/TestNotificationProvider.h:
+    * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294225 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-05-16  Youenn Fablet  <you...@apple.com>
+
+            Make sure calling showNotification will extend the service worker lifetime
+            https://bugs.webkit.org/show_bug.cgi?id=240273
+            <rdar://92978482>
+
+            Reviewed by Chris Dumez.
+
+            Update NotificationClient API so that show is taking a completion handler.
+            Make use of this completion handler to resolve the promise when the show notification steps are done, as per spec.
+            Register push event to ServiceWorkerGlobalScope when the event handlers are called.
+            When ServiceWorkerRegistration::show is called during one of the push event handlers,
+            extend the push event lifetime by adding the show notification promise to the push event.
+
+            Covered by API test.
+
+            * Modules/notifications/Notification.cpp:
+            * Modules/notifications/Notification.h:
+            * Modules/notifications/NotificationClient.h:
+            * dom/ScriptExecutionContext.cpp:
+            * dom/ScriptExecutionContext.h:
+            * workers/service/ServiceWorkerGlobalScope.cpp:
+            * workers/service/ServiceWorkerGlobalScope.h:
+            * workers/service/ServiceWorkerRegistration.cpp:
+            * workers/service/ServiceWorkerRegistration.h:
+            * workers/service/context/ServiceWorkerThread.cpp:
+
+2022-05-16  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r294218. rdar://problem/90400867
 
     Right click > "Open Link" should trigger a navigation action with WKNavigationTypeLinkActivated

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/Notification.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/Notification.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/Notification.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -49,6 +49,7 @@
 #include "WindowFocusAllowedIndicator.h"
 #include <wtf/CompletionHandler.h>
 #include <wtf/IsoMallocInlines.h>
+#include <wtf/Scope.h>
 
 namespace WebCore {
 
@@ -143,17 +144,23 @@
     m_state = Showing;
 }
 
-void Notification::show()
+void Notification::show(CompletionHandler<void()>&& callback)
 {
+    CompletionHandlerCallingScope scope { WTFMove(callback) };
+
     // prevent double-showing
     if (m_state != Idle)
         return;
 
-    auto* client = clientFromContext();
+    auto* context = scriptExecutionContext();
+    if (!context)
+        return;
+
+    auto* client = context->notificationClient();
     if (!client)
         return;
 
-    if (client->checkPermission(scriptExecutionContext()) != Permission::Granted) {
+    if (client->checkPermission(context) != Permission::Granted) {
         switch (m_notificationSource) {
         case NotificationSource::Document:
             dispatchErrorEvent();
@@ -163,11 +170,10 @@
             // If permission has since been revoked, then silently failing here is expected behavior.
             break;
         }
-
         return;
     }
 
-    if (client->show(*this))
+    if (client->show(*this, scope.release()))
         m_state = Showing;
 }
 

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/Notification.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/Notification.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/Notification.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -39,6 +39,7 @@
 #include "NotificationPermission.h"
 #include "ScriptExecutionContextIdentifier.h"
 #include "SerializedScriptValue.h"
+#include <wtf/CompletionHandler.h>
 #include <wtf/URL.h>
 #include <wtf/UUID.h>
 #include "WritingMode.h"
@@ -74,7 +75,7 @@
 
     WEBCORE_EXPORT virtual ~Notification();
 
-    void show();
+    void show(CompletionHandler<void()>&& = [] { });
     void close();
 
     const String& title() const { return m_title; }

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/NotificationClient.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/NotificationClient.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/Modules/notifications/NotificationClient.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -47,7 +47,7 @@
     using PermissionHandler = CompletionHandler<void(Permission)>;
 
     // Requests that a notification be shown.
-    virtual bool show(Notification&) = 0;
+    virtual bool show(Notification&, CompletionHandler<void()>&&) = 0;
 
     // Requests that a notification that has already been shown be canceled.
     virtual void cancel(Notification&) = 0;

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/dom/ScriptExecutionContext.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/dom/ScriptExecutionContext.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/dom/ScriptExecutionContext.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -176,6 +176,10 @@
     m_inScriptExecutionContextDestructor = true;
 #endif // ASSERT_ENABLED
 
+    auto callbacks = WTFMove(m_notificationCallbacks);
+    for (auto& callback : callbacks.values())
+        callback();
+
 #if ENABLE(SERVICE_WORKER)
     setActiveServiceWorker(nullptr);
 #endif
@@ -755,4 +759,16 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+ScriptExecutionContext::NotificationCallbackIdentifier ScriptExecutionContext::addNotificationCallback(CompletionHandler<void()>&& callback)
+{
+    auto identifier = NotificationCallbackIdentifier::generateThreadSafe();
+    m_notificationCallbacks.add(identifier, WTFMove(callback));
+    return identifier;
+}
+
+CompletionHandler<void()> ScriptExecutionContext::takeNotificationCallback(NotificationCallbackIdentifier identifier)
+{
+    return m_notificationCallbacks.take(identifier);
+}
+
 } // namespace WebCore

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/dom/ScriptExecutionContext.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/dom/ScriptExecutionContext.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/dom/ScriptExecutionContext.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -313,6 +313,12 @@
     enum class HasResourceAccess : uint8_t { No, Yes, DefaultForThirdParty };
     WEBCORE_EXPORT HasResourceAccess canAccessResource(ResourceType) const;
 
+    enum NotificationCallbackIdentifierType { };
+    using NotificationCallbackIdentifier = ObjectIdentifier<NotificationCallbackIdentifierType>;
+
+    WEBCORE_EXPORT NotificationCallbackIdentifier addNotificationCallback(CompletionHandler<void()>&&);
+    WEBCORE_EXPORT CompletionHandler<void()> takeNotificationCallback(NotificationCallbackIdentifier);
+
 protected:
     class AddConsoleMessageTask : public Task {
     public:
@@ -395,6 +401,8 @@
 
     bool m_hasLoggedAuthenticatedEncryptionWarning { false };
     StorageBlockingPolicy m_storageBlockingPolicy { StorageBlockingPolicy::AllowAll };
+
+    HashMap<NotificationCallbackIdentifier, CompletionHandler<void()>> m_notificationCallbacks;
 };
 
 } // namespace WebCore

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -37,6 +37,7 @@
 #include "FrameLoaderClient.h"
 #include "JSDOMPromiseDeferred.h"
 #include "NotificationEvent.h"
+#include "PushEvent.h"
 #include "SWContextManager.h"
 #include "ServiceWorker.h"
 #include "ServiceWorkerClient.h"
@@ -78,6 +79,14 @@
     callOnMainThread([notificationClient = WTFMove(m_notificationClient)] { });
 }
 
+void ServiceWorkerGlobalScope::dispatchPushEvent(PushEvent& pushEvent)
+{
+    ASSERT(!m_pushEvent);
+    m_pushEvent = &pushEvent;
+    dispatchEvent(pushEvent);
+    m_pushEvent = nullptr;
+}
+
 void ServiceWorkerGlobalScope::notifyServiceWorkerPageOfCreationIfNecessary()
 {
     auto serviceWorkerPage = this->serviceWorkerPage();

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -40,6 +40,7 @@
 class DeferredPromise;
 class ExtendableEvent;
 class Page;
+class PushEvent;
 class ServiceWorkerClient;
 class ServiceWorkerClients;
 class ServiceWorkerThread;
@@ -81,6 +82,9 @@
 
     WEBCORE_EXPORT Page* serviceWorkerPage();
 
+    void dispatchPushEvent(PushEvent&);
+    PushEvent* pushEvent() { return m_pushEvent.get(); }
+
     bool hasPendingSilentPushEvent() const { return m_hasPendingSilentPushEvent; }
     void setHasPendingSilentPushEvent(bool value) { m_hasPendingSilentPushEvent = value; }
 
@@ -112,6 +116,7 @@
     bool m_hasPendingSilentPushEvent { false };
     bool m_isProcessingUserGesture { false };
     Timer m_userGestureTimer;
+    RefPtr<PushEvent> m_pushEvent;
 };
 
 } // namespace WebCore

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -32,6 +32,7 @@
 #include "Event.h"
 #include "EventLoop.h"
 #include "EventNames.h"
+#include "JSDOMPromise.h"
 #include "JSDOMPromiseDeferred.h"
 #include "JSNotification.h"
 #include "Logging.h"
@@ -38,6 +39,7 @@
 #include "NavigationPreloadManager.h"
 #include "NotificationClient.h"
 #include "NotificationPermission.h"
+#include "PushEvent.h"
 #include "ServiceWorker.h"
 #include "ServiceWorkerContainer.h"
 #include "ServiceWorkerGlobalScope.h"
@@ -274,21 +276,21 @@
 }
 
 #if ENABLE(NOTIFICATION_EVENT)
-void ServiceWorkerRegistration::showNotification(ScriptExecutionContext& context, String&& title, NotificationOptions&& options, DOMPromiseDeferred<void>&& promise)
+void ServiceWorkerRegistration::showNotification(ScriptExecutionContext& context, String&& title, NotificationOptions&& options, Ref<DeferredPromise>&& promise)
 {
     if (!m_activeWorker) {
-        promise.reject(Exception { TypeError, "Registration does not have an active worker"_s });
+        promise->reject(Exception { TypeError, "Registration does not have an active worker"_s });
         return;
     }
 
     auto* client = context.notificationClient();
     if (!client) {
-        promise.reject(Exception { TypeError, "Registration not active"_s });
+        promise->reject(Exception { TypeError, "Registration not active"_s });
         return;
     }
 
     if (client->checkPermission(&context) != NotificationPermission::Granted) {
-        promise.reject(Exception { TypeError, "Registration does not have permission to show notifications"_s });
+        promise->reject(Exception { TypeError, "Registration does not have permission to show notifications"_s });
         return;
     }
 
@@ -295,19 +297,23 @@
     if (context.isServiceWorkerGlobalScope())
         downcast<ServiceWorkerGlobalScope>(context).setHasPendingSilentPushEvent(false);
 
-    // The Notification is kept alive by virtue of being show()'n soon.
-    // FIXME: When implementing getNotifications(), store this Notification in the registration's notification list.
     auto notificationResult = Notification::createForServiceWorker(context, WTFMove(title), WTFMove(options), m_registrationData.scopeURL);
     if (notificationResult.hasException()) {
-        promise.reject(notificationResult.releaseException());
+        promise->reject(notificationResult.releaseException());
         return;
     }
 
+    if (auto* serviceWorkerGlobalScope = dynamicDowncast<ServiceWorkerGlobalScope>(context)) {
+        if (auto* pushEvent = serviceWorkerGlobalScope->pushEvent()) {
+            auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(promise->globalObject());
+            auto& jsPromise = *JSC::jsCast<JSC::JSPromise*>(promise->promise());
+            pushEvent->waitUntil(DOMPromise::create(globalObject, jsPromise));
+        }
+    }
+
     auto notification = notificationResult.releaseReturnValue();
-    notification->showSoon();
-
-    context.eventLoop().queueTask(TaskSource::DOMManipulation, [promise = WTFMove(promise)]() mutable {
-        promise.resolve();
+    notification->show([promise = WTFMove(promise)]() mutable {
+        promise->resolve();
     });
 }
 

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerRegistration.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerRegistration.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/ServiceWorkerRegistration.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -99,7 +99,7 @@
         String tag;
     };
 
-    void showNotification(ScriptExecutionContext&, String&& title, NotificationOptions&&, DOMPromiseDeferred<void>&&);
+    void showNotification(ScriptExecutionContext&, String&& title, NotificationOptions&&, Ref<DeferredPromise>&&);
     void getNotifications(const GetNotificationOptions& filter, DOMPromiseDeferred<IDLSequence<IDLInterface<Notification>>>);
 #endif
 

Modified: branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -231,7 +231,7 @@
         serviceWorkerGlobalScope->setHasPendingSilentPushEvent(true);
 
         auto pushEvent = PushEvent::create(eventNames().pushEvent, { }, WTFMove(data), ExtendableEvent::IsTrusted::Yes);
-        serviceWorkerGlobalScope->dispatchEvent(pushEvent);
+        serviceWorkerGlobalScope->dispatchPushEvent(pushEvent);
 
         pushEvent->whenAllExtendLifetimePromisesAreSettled([serviceWorkerGlobalScope, eventCreationTime = pushEvent->timeStamp(), callback = WTFMove(callback)](auto&& extendLifetimePromises) mutable {
             bool hasRejectedAnyPromise = false;

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/ChangeLog (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/ChangeLog	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/ChangeLog	2022-05-16 21:21:17 UTC (rev 294260)
@@ -1,3 +1,94 @@
+2022-05-16  Alan Coon  <alanc...@apple.com>
+
+        Cherry-pick r294225. rdar://problem/92978482
+
+    Make sure calling showNotification will extend the service worker lifetime
+    https://bugs.webkit.org/show_bug.cgi?id=240273
+    <rdar://92978482>
+    
+    Reviewed by Chris Dumez.
+    
+    Source/WebCore:
+    
+    Update NotificationClient API so that show is taking a completion handler.
+    Make use of this completion handler to resolve the promise when the show notification steps are done, as per spec.
+    Register push event to ServiceWorkerGlobalScope when the event handlers are called.
+    When ServiceWorkerRegistration::show is called during one of the push event handlers,
+    extend the push event lifetime by adding the show notification promise to the push event.
+    
+    Covered by API test.
+    
+    * Modules/notifications/Notification.cpp:
+    * Modules/notifications/Notification.h:
+    * Modules/notifications/NotificationClient.h:
+    * dom/ScriptExecutionContext.cpp:
+    * dom/ScriptExecutionContext.h:
+    * workers/service/ServiceWorkerGlobalScope.cpp:
+    * workers/service/ServiceWorkerGlobalScope.h:
+    * workers/service/ServiceWorkerRegistration.cpp:
+    * workers/service/ServiceWorkerRegistration.h:
+    * workers/service/context/ServiceWorkerThread.cpp:
+    
+    Source/WebKit:
+    
+    On WebProcess side, implement the new NoficationClient::show API that takes a callback.
+    Delay calling this callback until UIProcess tells us so through async IPC.
+    On UIProcess side, take a callback and call it when the show notification steps are done.
+    
+    * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
+    * NetworkProcess/Notifications/NetworkNotificationManager.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.messages.in:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.h:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.h:
+    * WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp:
+    * WebProcess/Notifications/WebNotificationManager.cpp:
+    * WebProcess/Notifications/WebNotificationManager.h:
+    * WebProcess/WebCoreSupport/WebNotificationClient.cpp:
+    * WebProcess/WebCoreSupport/WebNotificationClient.h:
+    
+    Source/WebKitLegacy/mac:
+    
+    * WebCoreSupport/WebNotificationClient.h:
+    * WebCoreSupport/WebNotificationClient.mm:
+    
+    Tools:
+    
+    * TestWebKitAPI/TestNotificationProvider.cpp:
+    * TestWebKitAPI/TestNotificationProvider.h:
+    * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294225 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-05-16  Youenn Fablet  <you...@apple.com>
+
+            Make sure calling showNotification will extend the service worker lifetime
+            https://bugs.webkit.org/show_bug.cgi?id=240273
+            <rdar://92978482>
+
+            Reviewed by Chris Dumez.
+
+            On WebProcess side, implement the new NoficationClient::show API that takes a callback.
+            Delay calling this callback until UIProcess tells us so through async IPC.
+            On UIProcess side, take a callback and call it when the show notification steps are done.
+
+            * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
+            * NetworkProcess/Notifications/NetworkNotificationManager.h:
+            * Shared/Notifications/NotificationManagerMessageHandler.h:
+            * Shared/Notifications/NotificationManagerMessageHandler.messages.in:
+            * UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp:
+            * UIProcess/Notifications/ServiceWorkerNotificationHandler.h:
+            * UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
+            * UIProcess/Notifications/WebNotificationManagerMessageHandler.h:
+            * WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp:
+            * WebProcess/Notifications/WebNotificationManager.cpp:
+            * WebProcess/Notifications/WebNotificationManager.h:
+            * WebProcess/WebCoreSupport/WebNotificationClient.cpp:
+            * WebProcess/WebCoreSupport/WebNotificationClient.h:
+
 2022-05-12  Alan Coon  <alanc...@apple.com>
 
         Cherry-pick r293994. rdar://problem/87157773

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -90,10 +90,9 @@
     sendMessageWithReply<WebPushD::MessageType::GetPendingPushMessages>(WTFMove(replyHandler));
 }
 
-void NetworkNotificationManager::showNotification(IPC::Connection&, const WebCore::NotificationData&)
+void NetworkNotificationManager::showNotification(IPC::Connection&, const WebCore::NotificationData&, CompletionHandler<void()>&& callback)
 {
-    if (!m_connection)
-        return;
+    callback();
 
 //     FIXME: While we don't normally land commented-out code in the tree,
 //     this is a nice bookmark for a development milestone; Roundtrip communication with webpushd

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -70,7 +70,7 @@
     NetworkNotificationManager(NetworkSession&, const String& webPushMachServiceName, WebPushD::WebPushDaemonConnectionConfiguration&&);
 
     void requestSystemNotificationPermission(const String& originString, CompletionHandler<void(bool)>&&) final;
-    void showNotification(IPC::Connection&, const WebCore::NotificationData&) final;
+    void showNotification(IPC::Connection&, const WebCore::NotificationData&, CompletionHandler<void()>&&) final;
     void cancelNotification(const UUID& notificationID) final;
     void clearNotifications(const Vector<UUID>& notificationIDs) final;
     void didDestroyNotification(const UUID& notificationID) final;

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -41,7 +41,7 @@
     virtual ~NotificationManagerMessageHandler() = default;
 
     virtual void requestSystemNotificationPermission(const String& securityOrigin, CompletionHandler<void(bool)>&&) = 0;
-    virtual void showNotification(IPC::Connection&, const WebCore::NotificationData&) = 0;
+    virtual void showNotification(IPC::Connection&, const WebCore::NotificationData&, CompletionHandler<void()>&&) = 0;
     virtual void cancelNotification(const UUID& notificationID) = 0;
     virtual void clearNotifications(const Vector<UUID>& notificationIDs) = 0;
     virtual void didDestroyNotification(const UUID& notificationID) = 0;

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.messages.in (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.messages.in	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/Shared/Notifications/NotificationManagerMessageHandler.messages.in	2022-05-16 21:21:17 UTC (rev 294260)
@@ -22,7 +22,7 @@
 
 messages -> NotificationManagerMessageHandler NotRefCounted {
     RequestSystemNotificationPermission(String originIdentifier) -> (bool allowed)
-    ShowNotification(struct WebCore::NotificationData notificationData) WantsConnection
+    ShowNotification(struct WebCore::NotificationData notificationData) -> () WantsConnection
     CancelNotification(UUID notificationID)
     ClearNotifications(Vector<UUID> notificationIDs)
     DidDestroyNotification(UUID notificationID)

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -28,6 +28,7 @@
 
 #include "WebsiteDataStore.h"
 #include <WebCore/NotificationData.h>
+#include <wtf/Scope.h>
 
 namespace WebKit {
 
@@ -52,8 +53,10 @@
     return WebsiteDataStore::existingDataStoreForSessionID(iterator->value);
 }
 
-void ServiceWorkerNotificationHandler::showNotification(IPC::Connection& connection, const WebCore::NotificationData& data)
+void ServiceWorkerNotificationHandler::showNotification(IPC::Connection& connection, const WebCore::NotificationData& data, CompletionHandler<void()>&& callback)
 {
+    auto scope = makeScopeExit([&callback] { callback(); });
+
     auto* dataStore = WebsiteDataStore::existingDataStoreForSessionID(data.sourceSession);
     if (!dataStore)
         return;

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/ServiceWorkerNotificationHandler.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/ServiceWorkerNotificationHandler.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/ServiceWorkerNotificationHandler.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -38,7 +38,7 @@
 public:
     static ServiceWorkerNotificationHandler& singleton();
 
-    void showNotification(IPC::Connection&, const WebCore::NotificationData&) final;
+    void showNotification(IPC::Connection&, const WebCore::NotificationData&, CompletionHandler<void()>&&) final;
     void cancelNotification(const UUID& notificationID) final;
     void clearNotifications(const Vector<UUID>& notificationIDs) final;
     void didDestroyNotification(const UUID& notificationID) final;

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -41,13 +41,14 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
-void WebNotificationManagerMessageHandler::showNotification(IPC::Connection& connection, const WebCore::NotificationData& data)
+void WebNotificationManagerMessageHandler::showNotification(IPC::Connection& connection, const WebCore::NotificationData& data, CompletionHandler<void()>&& callback)
 {
     if (!data.serviceWorkerRegistrationURL.isEmpty()) {
-        ServiceWorkerNotificationHandler::singleton().showNotification(connection, data);
+        ServiceWorkerNotificationHandler::singleton().showNotification(connection, data, WTFMove(callback));
         return;
     }
     m_webPageProxy.showNotification(connection, data);
+    callback();
 }
 
 void WebNotificationManagerMessageHandler::cancelNotification(const UUID& notificationID)

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/UIProcess/Notifications/WebNotificationManagerMessageHandler.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -37,7 +37,7 @@
     explicit WebNotificationManagerMessageHandler(WebPageProxy&);
 
     void requestSystemNotificationPermission(const String&, CompletionHandler<void(bool)>&&) final;
-    void showNotification(IPC::Connection&, const WebCore::NotificationData&) final;
+    void showNotification(IPC::Connection&, const WebCore::NotificationData&, CompletionHandler<void()>&&) final;
     void cancelNotification(const UUID& notificationID) final;
     void clearNotifications(const Vector<UUID>& notificationIDs) final;
     void didDestroyNotification(const UUID& notificationID) final;

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/Notifications/WebNotificationManager.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/Notifications/WebNotificationManager.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/Notifications/WebNotificationManager.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -123,7 +123,7 @@
 }
 
 #if ENABLE(NOTIFICATIONS)
-template<typename U> bool WebNotificationManager::sendNotificationMessage(U&& message, Notification& notification, WebPage* page)
+static bool sendMessage(Notification& notification, WebPage* page, const Function<bool(IPC::Connection&, uint64_t)>& sendMessage)
 {
     if (!page && !notification.scriptExecutionContext())
         return false;
@@ -130,7 +130,7 @@
 
 #if ENABLE(BUILT_IN_NOTIFICATIONS)
     if (RuntimeEnabledFeatures::sharedFeatures().builtInNotificationsEnabled())
-        return m_process.ensureNetworkProcessConnection().connection().send(WTFMove(message), WebProcess::singleton().sessionID().toUInt64());
+        return sendMessage(WebProcess::singleton().ensureNetworkProcessConnection().connection(), WebProcess::singleton().sessionID().toUInt64());
 #endif
 
     std::optional<WebCore::PageIdentifier> pageIdentifier;
@@ -143,12 +143,25 @@
     }
 
     ASSERT(pageIdentifier);
+    return sendMessage(*WebProcess::singleton().parentProcessConnection(), pageIdentifier->toUInt64());
+}
 
-    return m_process.parentProcessConnection()->send(WTFMove(message), *pageIdentifier);
+template<typename U> bool WebNotificationManager::sendNotificationMessage(U&& message, Notification& notification, WebPage* page)
+{
+    return sendMessage(notification, page, [&] (auto& connection, auto destinationIdentifier) {
+        return connection.send(WTFMove(message), destinationIdentifier);
+    });
 }
+
+template<typename U> bool WebNotificationManager::sendNotificationMessageWithAsyncReply(U&& message, Notification& notification, WebPage* page, CompletionHandler<void()>&& callback)
+{
+    return sendMessage(notification, page, [&] (auto& connection, auto destinationIdentifier) {
+        return connection.sendWithAsyncReply(WTFMove(message), WTFMove(callback), destinationIdentifier);
+    });
+}
 #endif // ENABLE(NOTIFICATIONS)
 
-bool WebNotificationManager::show(Notification& notification, WebPage* page)
+bool WebNotificationManager::show(Notification& notification, WebPage* page, CompletionHandler<void()>&& callback)
 {
 #if ENABLE(NOTIFICATIONS)
     LOG(Notifications, "WebProcess %i going to show notification %s", getpid(), notification.identifier().toString().utf8().data());
@@ -157,7 +170,7 @@
     if (page && !page->corePage()->settings().notificationsEnabled())
         return false;
 
-    if (!sendNotificationMessage(Messages::NotificationManagerMessageHandler::ShowNotification(notification.data()), notification, page))
+    if (!sendNotificationMessageWithAsyncReply(Messages::NotificationManagerMessageHandler::ShowNotification(notification.data()), notification, page, WTFMove(callback)))
         return false;
 
     if (!notification.isPersistent()) {

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/Notifications/WebNotificationManager.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/Notifications/WebNotificationManager.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/Notifications/WebNotificationManager.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -29,6 +29,7 @@
 #include "WebProcessSupplement.h"
 #include <WebCore/NotificationClient.h>
 #include <optional>
+#include <wtf/CompletionHandler.h>
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/RefPtr.h>
@@ -55,7 +56,7 @@
 
     static const char* supplementName();
     
-    bool show(WebCore::Notification&, WebPage*);
+    bool show(WebCore::Notification&, WebPage*, CompletionHandler<void()>&&);
     void cancel(WebCore::Notification&, WebPage*);
 
     // This callback comes from WebCore, not messaged from the UI process.
@@ -82,6 +83,7 @@
     void didRemoveNotificationDecisions(const Vector<String>& originStrings);
 
     template<typename U> bool sendNotificationMessage(U&& message, WebCore::Notification&, WebPage*);
+    template<typename U> bool sendNotificationMessageWithAsyncReply(U&& message, WebCore::Notification&, WebPage*, CompletionHandler<void()>&&);
 
     WebProcess& m_process;
 

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebNotificationClient.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebNotificationClient.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebNotificationClient.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -48,11 +48,19 @@
     ASSERT(isMainRunLoop());
 }
 
-bool WebNotificationClient::show(Notification& notification)
+bool WebNotificationClient::show(Notification& notification, CompletionHandler<void()>&& callback)
 {
+    auto* context = notification.scriptExecutionContext();
+    ASSERT(context);
+
     bool result;
-    callOnMainRunLoopAndWait([&result, protectedNotification = Ref { notification }, page = m_page]() {
-        result = WebProcess::singleton().supplement<WebNotificationManager>()->show(protectedNotification.get(), page);
+    callOnMainRunLoopAndWait([&result, protectedNotification = Ref { notification }, page = m_page, contextIdentifier = context->identifier(), callbackIdentifier = context->addNotificationCallback(WTFMove(callback))]() {
+        result = WebProcess::singleton().supplement<WebNotificationManager>()->show(protectedNotification.get(), page, [contextIdentifier, callbackIdentifier] {
+            ScriptExecutionContext::postTaskTo(contextIdentifier, [callbackIdentifier](auto& context) {
+                if (auto callback = context.takeNotificationCallback(callbackIdentifier))
+                    callback();
+            });
+        });
     });
     return result;
 }

Modified: branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebNotificationClient.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebNotificationClient.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebNotificationClient.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -38,7 +38,7 @@
 
 class WebPage;
 
-class WebNotificationClient : public WebCore::NotificationClient {
+class WebNotificationClient final : public WebCore::NotificationClient {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     WebNotificationClient(WebPage*);
@@ -45,12 +45,12 @@
     virtual ~WebNotificationClient();
 
 private:
-    bool show(WebCore::Notification&) override;
-    void cancel(WebCore::Notification&) override;
-    void notificationObjectDestroyed(WebCore::Notification&) override;
-    void notificationControllerDestroyed() override;
-    void requestPermission(WebCore::ScriptExecutionContext&, PermissionHandler&&) override;
-    WebCore::NotificationClient::Permission checkPermission(WebCore::ScriptExecutionContext*) override;
+    bool show(WebCore::Notification&, CompletionHandler<void()>&&) final;
+    void cancel(WebCore::Notification&) final;
+    void notificationObjectDestroyed(WebCore::Notification&) final;
+    void notificationControllerDestroyed() final;
+    void requestPermission(WebCore::ScriptExecutionContext&, PermissionHandler&&) final;
+    WebCore::NotificationClient::Permission checkPermission(WebCore::ScriptExecutionContext*) final;
     
     WebPage* m_page { nullptr };
 };

Modified: branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/ChangeLog (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/ChangeLog	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/ChangeLog	2022-05-16 21:21:17 UTC (rev 294260)
@@ -1,3 +1,79 @@
+2022-05-16  Alan Coon  <alanc...@apple.com>
+
+        Cherry-pick r294225. rdar://problem/92978482
+
+    Make sure calling showNotification will extend the service worker lifetime
+    https://bugs.webkit.org/show_bug.cgi?id=240273
+    <rdar://92978482>
+    
+    Reviewed by Chris Dumez.
+    
+    Source/WebCore:
+    
+    Update NotificationClient API so that show is taking a completion handler.
+    Make use of this completion handler to resolve the promise when the show notification steps are done, as per spec.
+    Register push event to ServiceWorkerGlobalScope when the event handlers are called.
+    When ServiceWorkerRegistration::show is called during one of the push event handlers,
+    extend the push event lifetime by adding the show notification promise to the push event.
+    
+    Covered by API test.
+    
+    * Modules/notifications/Notification.cpp:
+    * Modules/notifications/Notification.h:
+    * Modules/notifications/NotificationClient.h:
+    * dom/ScriptExecutionContext.cpp:
+    * dom/ScriptExecutionContext.h:
+    * workers/service/ServiceWorkerGlobalScope.cpp:
+    * workers/service/ServiceWorkerGlobalScope.h:
+    * workers/service/ServiceWorkerRegistration.cpp:
+    * workers/service/ServiceWorkerRegistration.h:
+    * workers/service/context/ServiceWorkerThread.cpp:
+    
+    Source/WebKit:
+    
+    On WebProcess side, implement the new NoficationClient::show API that takes a callback.
+    Delay calling this callback until UIProcess tells us so through async IPC.
+    On UIProcess side, take a callback and call it when the show notification steps are done.
+    
+    * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
+    * NetworkProcess/Notifications/NetworkNotificationManager.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.messages.in:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.h:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.h:
+    * WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp:
+    * WebProcess/Notifications/WebNotificationManager.cpp:
+    * WebProcess/Notifications/WebNotificationManager.h:
+    * WebProcess/WebCoreSupport/WebNotificationClient.cpp:
+    * WebProcess/WebCoreSupport/WebNotificationClient.h:
+    
+    Source/WebKitLegacy/mac:
+    
+    * WebCoreSupport/WebNotificationClient.h:
+    * WebCoreSupport/WebNotificationClient.mm:
+    
+    Tools:
+    
+    * TestWebKitAPI/TestNotificationProvider.cpp:
+    * TestWebKitAPI/TestNotificationProvider.h:
+    * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294225 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-05-16  Youenn Fablet  <you...@apple.com>
+
+            Make sure calling showNotification will extend the service worker lifetime
+            https://bugs.webkit.org/show_bug.cgi?id=240273
+            <rdar://92978482>
+
+            Reviewed by Chris Dumez.
+
+            * WebCoreSupport/WebNotificationClient.h:
+            * WebCoreSupport/WebNotificationClient.mm:
+
 2022-05-06  Brent Fulgham  <bfulg...@apple.com>
 
         Remove the viewportFitEnabled WKPreference now that it is always on 

Modified: branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebNotificationClient.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebNotificationClient.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebNotificationClient.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -35,7 +35,7 @@
 @class WebNotificationPolicyListener;
 @class WebView;
 
-class WebNotificationClient : public WebCore::NotificationClient {
+class WebNotificationClient final : public WebCore::NotificationClient {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     WebNotificationClient(WebView *);
@@ -45,12 +45,12 @@
     uint64_t notificationIDForTesting(WebCore::Notification*);
 
 private:
-    bool show(WebCore::Notification&) override;
-    void cancel(WebCore::Notification&) override;
-    void notificationObjectDestroyed(WebCore::Notification&) override;
-    void notificationControllerDestroyed() override;
-    void requestPermission(WebCore::ScriptExecutionContext&, PermissionHandler&&) override;
-    WebCore::NotificationClient::Permission checkPermission(WebCore::ScriptExecutionContext*) override;
+    bool show(WebCore::Notification&, CompletionHandler<void()>&&) final;
+    void cancel(WebCore::Notification&) final;
+    void notificationObjectDestroyed(WebCore::Notification&) final;
+    void notificationControllerDestroyed() final;
+    void requestPermission(WebCore::ScriptExecutionContext&, PermissionHandler&&) final;
+    WebCore::NotificationClient::Permission checkPermission(WebCore::ScriptExecutionContext*) final;
 
     void requestPermission(WebCore::ScriptExecutionContext&, WebNotificationPolicyListener *);
 

Modified: branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebNotificationClient.mm (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebNotificationClient.mm	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebNotificationClient.mm	2022-05-16 21:21:17 UTC (rev 294260)
@@ -36,6 +36,7 @@
 #import <WebCore/ScriptExecutionContext.h>
 #import <wtf/BlockObjCExceptions.h>
 #import <wtf/CompletionHandler.h>
+#import <wtf/Scope.h>
 #import <wtf/cocoa/VectorCocoa.h>
 
 using namespace WebCore;
@@ -58,8 +59,10 @@
 {
 }
 
-bool WebNotificationClient::show(Notification& notification)
+bool WebNotificationClient::show(Notification& notification, CompletionHandler<void()>&& callback)
 {
+    auto scope = makeScopeExit([&callback] { callback(); });
+
     if (![m_webView _notificationProvider])
         return false;
 

Modified: branches/safari-7614.1.14.1-branch/Tools/ChangeLog (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Tools/ChangeLog	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Tools/ChangeLog	2022-05-16 21:21:17 UTC (rev 294260)
@@ -1,5 +1,82 @@
 2022-05-16  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r294225. rdar://problem/92978482
+
+    Make sure calling showNotification will extend the service worker lifetime
+    https://bugs.webkit.org/show_bug.cgi?id=240273
+    <rdar://92978482>
+    
+    Reviewed by Chris Dumez.
+    
+    Source/WebCore:
+    
+    Update NotificationClient API so that show is taking a completion handler.
+    Make use of this completion handler to resolve the promise when the show notification steps are done, as per spec.
+    Register push event to ServiceWorkerGlobalScope when the event handlers are called.
+    When ServiceWorkerRegistration::show is called during one of the push event handlers,
+    extend the push event lifetime by adding the show notification promise to the push event.
+    
+    Covered by API test.
+    
+    * Modules/notifications/Notification.cpp:
+    * Modules/notifications/Notification.h:
+    * Modules/notifications/NotificationClient.h:
+    * dom/ScriptExecutionContext.cpp:
+    * dom/ScriptExecutionContext.h:
+    * workers/service/ServiceWorkerGlobalScope.cpp:
+    * workers/service/ServiceWorkerGlobalScope.h:
+    * workers/service/ServiceWorkerRegistration.cpp:
+    * workers/service/ServiceWorkerRegistration.h:
+    * workers/service/context/ServiceWorkerThread.cpp:
+    
+    Source/WebKit:
+    
+    On WebProcess side, implement the new NoficationClient::show API that takes a callback.
+    Delay calling this callback until UIProcess tells us so through async IPC.
+    On UIProcess side, take a callback and call it when the show notification steps are done.
+    
+    * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
+    * NetworkProcess/Notifications/NetworkNotificationManager.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.h:
+    * Shared/Notifications/NotificationManagerMessageHandler.messages.in:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.cpp:
+    * UIProcess/Notifications/ServiceWorkerNotificationHandler.h:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.cpp:
+    * UIProcess/Notifications/WebNotificationManagerMessageHandler.h:
+    * WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp:
+    * WebProcess/Notifications/WebNotificationManager.cpp:
+    * WebProcess/Notifications/WebNotificationManager.h:
+    * WebProcess/WebCoreSupport/WebNotificationClient.cpp:
+    * WebProcess/WebCoreSupport/WebNotificationClient.h:
+    
+    Source/WebKitLegacy/mac:
+    
+    * WebCoreSupport/WebNotificationClient.h:
+    * WebCoreSupport/WebNotificationClient.mm:
+    
+    Tools:
+    
+    * TestWebKitAPI/TestNotificationProvider.cpp:
+    * TestWebKitAPI/TestNotificationProvider.h:
+    * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294225 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-05-16  Youenn Fablet  <you...@apple.com>
+
+            Make sure calling showNotification will extend the service worker lifetime
+            https://bugs.webkit.org/show_bug.cgi?id=240273
+            <rdar://92978482>
+
+            Reviewed by Chris Dumez.
+
+            * TestWebKitAPI/TestNotificationProvider.cpp:
+            * TestWebKitAPI/TestNotificationProvider.h:
+            * TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm:
+
+2022-05-16  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r294218. rdar://problem/90400867
 
     Right click > "Open Link" should trigger a navigation action with WKNavigationTypeLinkActivated

Modified: branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/TestNotificationProvider.cpp (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/TestNotificationProvider.cpp	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/TestNotificationProvider.cpp	2022-05-16 21:21:17 UTC (rev 294260)
@@ -121,6 +121,8 @@
 
 void TestNotificationProvider::showWebNotification(WKPageRef page, WKNotificationRef notification)
 {
+    m_hasReceivedNotification = true;
+
     auto notificationManager = notificationManagerForPage(page);
     uint64_t identifier = WKNotificationGetID(notification);
     WKNotificationManagerProviderDidShowNotification(notificationManager, identifier);

Modified: branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/TestNotificationProvider.h (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/TestNotificationProvider.h	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/TestNotificationProvider.h	2022-05-16 21:21:17 UTC (rev 294260)
@@ -47,11 +47,15 @@
     void showWebNotification(WKPageRef, WKNotificationRef);
     void simulateNotificationClick();
 
+    bool hasReceivedNotification() const { return m_hasReceivedNotification; }
+    void resetHasReceivedNotification() { m_hasReceivedNotification = false; }
+
 private:
     Vector<WKNotificationManagerRef> m_managers;
     HashMap<String, bool> m_permissions;
     WKNotificationProviderV0 m_provider;
 
+    bool m_hasReceivedNotification { false };
     std::pair<WKNotificationManagerRef, uint64_t> m_pendingNotification;
 };
 

Modified: branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm (294259 => 294260)


--- branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm	2022-05-16 21:21:12 UTC (rev 294259)
+++ branches/safari-7614.1.14.1-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/PushAPI.mm	2022-05-16 21:21:17 UTC (rev 294260)
@@ -677,6 +677,9 @@
 
     TestWebKitAPI::Util::run(&done);
 
+    provider.resetHasReceivedNotification();
+    auto& providerRef = provider;
+
     done = false;
     pushMessageProcessed = false;
     pushMessageSuccessful = false;
@@ -684,6 +687,7 @@
     expectedMessage = "Received: Sweet Potatoes"_s;
 
     [[configuration websiteDataStore] _processPushMessage:messageDictionary([message dataUsingEncoding:NSUTF8StringEncoding], [server.request() URL]) completionHandler:^(bool result) {
+        EXPECT_TRUE(providerRef.hasReceivedNotification());
         pushMessageSuccessful = result;
         pushMessageProcessed = true;
     }];
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to