Title: [283438] trunk
Revision
283438
Author
[email protected]
Date
2021-10-02 04:57:48 -0700 (Sat, 02 Oct 2021)

Log Message

Add support for ServiceWorkerGlobalScope push event handler
https://bugs.webkit.org/show_bug.cgi?id=231008
<rdar://problem/83710760>

Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

* web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt:

Source/WebCore:

Implement https://w3c.github.io/push-api/#receiving-a-push-message step 6.
In particular we ensure that if any waitUntil promise rejects, the push event is considered to fail.
This status should then be sent back to the emiter of the push message to decide whether to acknowledge the message, retry it or discard it.

We keep push API completion handler in a map to ensure we respond to them even if the service worker gets terminated while processing the push event.

Add necessary internals API to enable testing within the service worker itself.

Covered by added subtests in http/wpt/service-workers/pushEvent.any.serviceworker.html.

* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl: Added.
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/WebCoreBuiltinNames.h:
* dom/EventNames.h:
* testing/ServiceWorkerInternals.cpp:
* testing/ServiceWorkerInternals.h:
* testing/ServiceWorkerInternals.idl:
* workers/service/context/SWContextManager.cpp:
* workers/service/context/SWContextManager.h:
* workers/service/context/ServiceWorkerThread.cpp:
* workers/service/context/ServiceWorkerThread.h:
* workers/service/context/ServiceWorkerThreadProxy.cpp:
* workers/service/context/ServiceWorkerThreadProxy.h:

LayoutTests:

* http/wpt/push-api/pushEvent.any.js:
* http/wpt/push-api/pushEvent.any.serviceworker-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (283437 => 283438)


--- trunk/LayoutTests/ChangeLog	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/LayoutTests/ChangeLog	2021-10-02 11:57:48 UTC (rev 283438)
@@ -1,3 +1,14 @@
+2021-10-02  Youenn Fablet  <[email protected]>
+
+        Add support for ServiceWorkerGlobalScope push event handler
+        https://bugs.webkit.org/show_bug.cgi?id=231008
+        <rdar://problem/83710760>
+
+        Reviewed by Chris Dumez.
+
+        * http/wpt/push-api/pushEvent.any.js:
+        * http/wpt/push-api/pushEvent.any.serviceworker-expected.txt:
+
 2021-10-01  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r283293.

Modified: trunk/LayoutTests/http/wpt/push-api/pushEvent.any.js (283437 => 283438)


--- trunk/LayoutTests/http/wpt/push-api/pushEvent.any.js	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/LayoutTests/http/wpt/push-api/pushEvent.any.js	2021-10-02 11:57:48 UTC (rev 283438)
@@ -52,3 +52,53 @@
     const event = new PushEvent("push", { data : "{test : 1}" });
     assert_throws_dom("SyntaxError", () => event.data.json());
 }, "PushEvent with bad json");
+
+let activatePromise = new Promise(resolve => self._onactivate_ = resolve);
+promise_test(async () => {
+   return activatePromise;
+}, "Wait for activate promise");
+
+promise_test(async () => {
+    const promise = self.internals.schedulePushEvent("test");
+    const event = await new Promise(resolve => self._onpush_ = resolve);
+    assert_equals(event.data.text(), "test");
+    assert_true(await promise);
+}, "Simulating firing of a push event");
+
+promise_test(async () => {
+    if (!self.internals)
+        return;
+
+    let resolveWaitUntilPromise;
+    const waitUntilPromise = new Promise(resolve => resolveWaitUntilPromise = resolve);
+
+    let isPushEventPromiseResolved = false;
+    const promise = internals.schedulePushEvent("test");
+    promise.then(() => isPushEventPromiseResolved = true);
+
+    const event = await new Promise(resolve => self._onpush_ = (event) => {
+        event.waitUntil(waitUntilPromise);
+        resolve(event);
+    });
+    assert_equals(event.data.text(), "test");
+
+    await new Promise(resolve => self.setTimeout(resolve, 100));
+    assert_false(isPushEventPromiseResolved);
+
+    resolveWaitUntilPromise();
+    assert_true(await promise);
+}, "Simulating firing of a push event - successful waitUntil");
+
+promise_test(async () => {
+    if (!self.internals)
+        return;
+
+    const promise = internals.schedulePushEvent("test");
+    const event = await new Promise(resolve => self._onpush_ = (event) => {
+        event.waitUntil(Promise.resolve());
+        event.waitUntil(Promise.reject('error'));
+        resolve(event);
+    });
+    assert_equals(event.data.text(), "test");
+    assert_false(await promise);
+}, "Simulating firing of a push event - unsuccessful waitUntil");

Modified: trunk/LayoutTests/http/wpt/push-api/pushEvent.any.serviceworker-expected.txt (283437 => 283438)


--- trunk/LayoutTests/http/wpt/push-api/pushEvent.any.serviceworker-expected.txt	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/LayoutTests/http/wpt/push-api/pushEvent.any.serviceworker-expected.txt	2021-10-02 11:57:48 UTC (rev 283438)
@@ -3,4 +3,8 @@
 PASS PushEvent with data
 PASS PushEvent arrayBuffer handling
 PASS PushEvent with bad json
+PASS Wait for activate promise
+PASS Simulating firing of a push event
+PASS Simulating firing of a push event - successful waitUntil
+PASS Simulating firing of a push event - unsuccessful waitUntil
 

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (283437 => 283438)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-02 11:57:48 UTC (rev 283438)
@@ -1,3 +1,13 @@
+2021-10-02  Youenn Fablet  <[email protected]>
+
+        Add support for ServiceWorkerGlobalScope push event handler
+        https://bugs.webkit.org/show_bug.cgi?id=231008
+        <rdar://problem/83710760>
+
+        Reviewed by Chris Dumez.
+
+        * web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt:
+
 2021-10-01  Nikos Mouchtaris  <[email protected]>
 
         Allow NaN, infinity, and -infinity in calc

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt (283437 => 283438)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/push-api/idlharness.https.any.serviceworker-expected.txt	2021-10-02 11:57:48 UTC (rev 283438)
@@ -79,8 +79,8 @@
 FAIL PushSubscriptionChangeEvent interface: new PushSubscriptionChangeEvent("pushsubscriptionchange") must inherit property "oldSubscription" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: Can't find variable: PushSubscriptionChangeEvent"
 FAIL ServiceWorkerRegistration interface: attribute pushManager assert_true: The prototype object must have a property "pushManager" expected true got false
 FAIL ServiceWorkerRegistration interface: registration must inherit property "pushManager" with the proper type assert_inherits: property "pushManager" not found in prototype chain
-FAIL ServiceWorkerGlobalScope interface: attribute onpush assert_own_property: The global object must have a property "onpush" expected property "onpush" missing
+PASS ServiceWorkerGlobalScope interface: attribute onpush
 FAIL ServiceWorkerGlobalScope interface: attribute onpushsubscriptionchange assert_own_property: The global object must have a property "onpushsubscriptionchange" expected property "onpushsubscriptionchange" missing
-FAIL ServiceWorkerGlobalScope interface: self must inherit property "onpush" with the proper type assert_own_property: expected property "onpush" missing
+PASS ServiceWorkerGlobalScope interface: self must inherit property "onpush" with the proper type
 FAIL ServiceWorkerGlobalScope interface: self must inherit property "onpushsubscriptionchange" with the proper type assert_own_property: expected property "onpushsubscriptionchange" missing
 

Modified: trunk/Source/WebCore/CMakeLists.txt (283437 => 283438)


--- trunk/Source/WebCore/CMakeLists.txt	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/CMakeLists.txt	2021-10-02 11:57:48 UTC (rev 283438)
@@ -501,6 +501,7 @@
     Modules/push-api/PushEvent.idl
     Modules/push-api/PushEventInit.idl
     Modules/push-api/PushMessageData.idl
+    Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl
 
     Modules/remoteplayback/RemotePlayback.idl
     Modules/remoteplayback/RemotePlaybackAvailabilityCallback.idl

Modified: trunk/Source/WebCore/ChangeLog (283437 => 283438)


--- trunk/Source/WebCore/ChangeLog	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/ChangeLog	2021-10-02 11:57:48 UTC (rev 283438)
@@ -1,3 +1,39 @@
+2021-10-02  Youenn Fablet  <[email protected]>
+
+        Add support for ServiceWorkerGlobalScope push event handler
+        https://bugs.webkit.org/show_bug.cgi?id=231008
+        <rdar://problem/83710760>
+
+        Reviewed by Chris Dumez.
+
+        Implement https://w3c.github.io/push-api/#receiving-a-push-message step 6.
+        In particular we ensure that if any waitUntil promise rejects, the push event is considered to fail.
+        This status should then be sent back to the emiter of the push message to decide whether to acknowledge the message, retry it or discard it.
+
+        We keep push API completion handler in a map to ensure we respond to them even if the service worker gets terminated while processing the push event.
+
+        Add necessary internals API to enable testing within the service worker itself.
+
+        Covered by added subtests in http/wpt/service-workers/pushEvent.any.serviceworker.html.
+
+        * CMakeLists.txt:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl: Added.
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/WebCoreBuiltinNames.h:
+        * dom/EventNames.h:
+        * testing/ServiceWorkerInternals.cpp:
+        * testing/ServiceWorkerInternals.h:
+        * testing/ServiceWorkerInternals.idl:
+        * workers/service/context/SWContextManager.cpp:
+        * workers/service/context/SWContextManager.h:
+        * workers/service/context/ServiceWorkerThread.cpp:
+        * workers/service/context/ServiceWorkerThread.h:
+        * workers/service/context/ServiceWorkerThreadProxy.cpp:
+        * workers/service/context/ServiceWorkerThreadProxy.h:
+
 2021-10-02  Philippe Normand  <[email protected]>
 
         [GLib] Media session manager unable to handle more than one session

Modified: trunk/Source/WebCore/DerivedSources-input.xcfilelist (283437 => 283438)


--- trunk/Source/WebCore/DerivedSources-input.xcfilelist	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/DerivedSources-input.xcfilelist	2021-10-02 11:57:48 UTC (rev 283438)
@@ -424,6 +424,7 @@
 $(PROJECT_DIR)/Modules/push-api/PushEvent.idl
 $(PROJECT_DIR)/Modules/push-api/PushEventInit.idl
 $(PROJECT_DIR)/Modules/push-api/PushMessageData.idl
+$(PROJECT_DIR)/Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl
 $(PROJECT_DIR)/Modules/remoteplayback/HTMLMediaElement+RemotePlayback.idl
 $(PROJECT_DIR)/Modules/remoteplayback/RemotePlayback.idl
 $(PROJECT_DIR)/Modules/remoteplayback/RemotePlaybackAvailabilityCallback.idl

Modified: trunk/Source/WebCore/DerivedSources-output.xcfilelist (283437 => 283438)


--- trunk/Source/WebCore/DerivedSources-output.xcfilelist	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/DerivedSources-output.xcfilelist	2021-10-02 11:57:48 UTC (rev 283438)
@@ -2229,6 +2229,8 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerClients.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerContainer.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerContainer.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope+PushAPI.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope+PushAPI.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerGlobalScope.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSServiceWorkerInternals.cpp

Modified: trunk/Source/WebCore/DerivedSources.make (283437 => 283438)


--- trunk/Source/WebCore/DerivedSources.make	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/DerivedSources.make	2021-10-02 11:57:48 UTC (rev 283438)
@@ -349,6 +349,7 @@
     $(WebCore)/Modules/push-api/PushEvent.idl \
     $(WebCore)/Modules/push-api/PushEventInit.idl \
     $(WebCore)/Modules/push-api/PushMessageData.idl \
+    $(WebCore)/Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl \
     $(WebCore)/Modules/remoteplayback/HTMLMediaElement+RemotePlayback.idl \
     $(WebCore)/Modules/remoteplayback/RemotePlayback.idl \
     $(WebCore)/Modules/remoteplayback/RemotePlaybackAvailabilityCallback.idl \

Added: trunk/Source/WebCore/Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl (0 => 283438)


--- trunk/Source/WebCore/Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl	                        (rev 0)
+++ trunk/Source/WebCore/Modules/push-api/ServiceWorkerGlobalScope+PushAPI.idl	2021-10-02 11:57:48 UTC (rev 283438)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    EnabledAtRuntime=ServiceWorker,
+    ImplementedBy=ServiceWorkerGlobalScopePushAPI
+] partial interface ServiceWorkerGlobalScope {
+    attribute EventHandler onpush;
+};

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (283437 => 283438)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-10-02 11:57:48 UTC (rev 283438)
@@ -8113,6 +8113,9 @@
 		418FCBBF2706E4F800F96ECA /* PushEventInit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PushEventInit.h; sourceTree = "<group>"; };
 		418FCBC02706E4F800F96ECA /* PushEvent.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushEvent.idl; sourceTree = "<group>"; };
 		418FCBC32706E62C00F96ECA /* PushEventInit.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushEventInit.idl; sourceTree = "<group>"; };
+		418FCBCB2706F3CD00F96ECA /* ServiceWorkerGlobalScope+PushAPI.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ServiceWorkerGlobalScope+PushAPI.idl"; sourceTree = "<group>"; };
+		418FCBCC2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerGlobalScopePushAPI.h; sourceTree = "<group>"; };
+		418FCBCD2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerGlobalScopePushAPI.cpp; sourceTree = "<group>"; };
 		4190F3A1249D152700531C57 /* FrameRateMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameRateMonitor.cpp; sourceTree = "<group>"; };
 		4190F3A3249D152800531C57 /* FrameRateMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameRateMonitor.h; sourceTree = "<group>"; };
 		419242472127B7CC00634FCF /* RealtimeOutgoingVideoSourceCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RealtimeOutgoingVideoSourceCocoa.mm; sourceTree = "<group>"; };
@@ -19883,6 +19886,9 @@
 				418FCBBE2706E4F700F96ECA /* PushMessageData.cpp */,
 				418FCBBC2706E4F600F96ECA /* PushMessageData.h */,
 				418FCBBA2706E4F500F96ECA /* PushMessageData.idl */,
+				418FCBCB2706F3CD00F96ECA /* ServiceWorkerGlobalScope+PushAPI.idl */,
+				418FCBCD2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.cpp */,
+				418FCBCC2706F43400F96ECA /* ServiceWorkerGlobalScopePushAPI.h */,
 			);
 			path = "push-api";
 			sourceTree = "<group>";

Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (283437 => 283438)


--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h	2021-10-02 11:57:48 UTC (rev 283438)
@@ -402,7 +402,7 @@
     macro(makeThisTypeError) \
     macro(matchingElementInFlatTree) \
     macro(mediaStreamTrackConstraints) \
-    macro(openDatabase) \
+    macro(onpush) \
     macro(onrtctransform) \
     macro(ontouchcancel) \
     macro(ontouchend) \
@@ -417,6 +417,7 @@
     macro(onvrdisplaydisconnect) \
     macro(onvrdisplayfocus) \
     macro(onvrdisplaypresentchange) \
+    macro(openDatabase) \
     macro(opener) \
     macro(operations) \
     macro(ownerReadableStream) \

Modified: trunk/Source/WebCore/dom/EventNames.h (283437 => 283438)


--- trunk/Source/WebCore/dom/EventNames.h	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/dom/EventNames.h	2021-10-02 11:57:48 UTC (rev 283438)
@@ -221,6 +221,7 @@
     macro(previoustrack) \
     macro(processorerror) \
     macro(progress) \
+    macro(push) \
     macro(ratechange) \
     macro(readystatechange) \
     macro(rejectionhandled) \

Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp (283437 => 283438)


--- trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp	2021-10-02 11:57:48 UTC (rev 283438)
@@ -57,6 +57,30 @@
     });
 }
 
+void ServiceWorkerInternals::schedulePushEvent(const String& message, RefPtr<DeferredPromise>&& promise)
+{
+    auto counter = ++m_pushEventCounter;
+    m_pushEventPromises.add(counter, WTFMove(promise));
+
+    std::optional<Vector<uint8_t>> data;
+    if (!message.isNull()) {
+        auto utf8 = message.utf8();
+        data = "" { reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length()};
+    }
+    callOnMainThread([identifier = m_identifier, data = "" weakThis = makeWeakPtr(this), counter]() mutable {
+        SWContextManager::singleton().firePushEvent(identifier, WTFMove(data), [identifier, weakThis = WTFMove(weakThis), counter](bool result) mutable {
+            if (auto* proxy = SWContextManager::singleton().workerByID(identifier)) {
+                proxy->thread().runLoop().postTaskForMode([weakThis = WTFMove(weakThis), counter, result](auto&) {
+                    if (!weakThis)
+                        return;
+                    if (auto promise = weakThis->m_pushEventPromises.take(counter))
+                        promise->resolve<IDLBoolean>(result);
+                }, WorkerRunLoop::defaultMode());
+            }
+        });
+    });
+}
+
 void ServiceWorkerInternals::waitForFetchEventToFinish(FetchEvent& event, DOMPromiseDeferred<IDLInterface<FetchResponse>>&& promise)
 {
     event.onResponse([promise = WTFMove(promise), event = Ref { event }] (auto&& result) mutable {

Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.h (283437 => 283438)


--- trunk/Source/WebCore/testing/ServiceWorkerInternals.h	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.h	2021-10-02 11:57:48 UTC (rev 283438)
@@ -52,6 +52,7 @@
     Ref<FetchEvent> createBeingDispatchedFetchEvent(ScriptExecutionContext&);
     Ref<FetchResponse> createOpaqueWithBlobBodyResponse(ScriptExecutionContext&);
 
+    void schedulePushEvent(const String&, RefPtr<DeferredPromise>&&);
     Vector<String> fetchResponseHeaderList(FetchResponse&);
 
     String processName() const;
@@ -67,6 +68,8 @@
 
     ServiceWorkerIdentifier m_identifier;
     RefPtr<DeferredPromise> m_lastNavigationWasAppInitiatedPromise;
+    HashMap<uint64_t, RefPtr<DeferredPromise>> m_pushEventPromises;
+    uint64_t m_pushEventCounter { 0 };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.idl (283437 => 283438)


--- trunk/Source/WebCore/testing/ServiceWorkerInternals.idl	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.idl	2021-10-02 11:57:48 UTC (rev 283438)
@@ -38,6 +38,8 @@
 
     sequence<ByteString> fetchResponseHeaderList(FetchResponse response);
 
+    Promise<boolean> schedulePushEvent(optional DOMString data);
+
     readonly attribute DOMString processName;
     readonly attribute boolean isThrottleable;
 

Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.cpp (283437 => 283438)


--- trunk/Source/WebCore/workers/service/context/SWContextManager.cpp	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.cpp	2021-10-02 11:57:48 UTC (rev 283438)
@@ -109,6 +109,18 @@
     serviceWorker->fireActivateEvent();
 }
 
+void SWContextManager::firePushEvent(ServiceWorkerIdentifier identifier, std::optional<Vector<uint8_t>>&& data, CompletionHandler<void(bool)>&& callback)
+{
+    auto* serviceWorker = m_workerMap.get(identifier);
+    if (!serviceWorker) {
+        callback(false);
+        return;
+    }
+
+    serviceWorker->firePushEvent(WTFMove(data), WTFMove(callback));
+}
+
+
 void SWContextManager::terminateWorker(ServiceWorkerIdentifier identifier, Seconds timeout, Function<void()>&& completionHandler)
 {
     auto serviceWorker = m_workerMap.take(identifier);

Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.h (283437 => 283438)


--- trunk/Source/WebCore/workers/service/context/SWContextManager.h	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.h	2021-10-02 11:57:48 UTC (rev 283438)
@@ -90,6 +90,8 @@
     WEBCORE_EXPORT void postMessageToServiceWorker(ServiceWorkerIdentifier destination, MessageWithMessagePorts&&, ServiceWorkerOrClientData&& sourceData);
     WEBCORE_EXPORT void fireInstallEvent(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void fireActivateEvent(ServiceWorkerIdentifier);
+    WEBCORE_EXPORT void firePushEvent(ServiceWorkerIdentifier, std::optional<Vector<uint8_t>>&&, CompletionHandler<void(bool)>&&);
+
     WEBCORE_EXPORT void terminateWorker(ServiceWorkerIdentifier, Seconds timeout, Function<void()>&&);
     WEBCORE_EXPORT void didSaveScriptsToDisk(ServiceWorkerIdentifier, ScriptBuffer&&, HashMap<URL, ScriptBuffer>&& importedScripts);
 

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp (283437 => 283438)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp	2021-10-02 11:57:48 UTC (rev 283438)
@@ -37,6 +37,7 @@
 #include "LoaderStrategy.h"
 #include "Logging.h"
 #include "PlatformStrategies.h"
+#include "PushEvent.h"
 #include "SWContextManager.h"
 #include "SecurityOrigin.h"
 #include "ServiceWorkerFetch.h"
@@ -212,6 +213,28 @@
     });
 }
 
+void ServiceWorkerThread::queueTaskToFirePushEvent(std::optional<Vector<uint8_t>>&& data, Function<void(bool)>&& callback)
+{
+    auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(*globalScope());
+    serviceWorkerGlobalScope.eventLoop().queueTask(TaskSource::DOMManipulation, [weakThis = makeWeakPtr(this), serviceWorkerGlobalScope = Ref { serviceWorkerGlobalScope }, data = "" callback = WTFMove(callback)]() mutable {
+        RELEASE_LOG(ServiceWorker, "ServiceWorkerThread::queueTaskToFirePushEvent firing event for worker %" PRIu64, serviceWorkerGlobalScope->thread().identifier().toUInt64());
+
+        auto pushEvent = PushEvent::create(eventNames().pushEvent, { }, WTFMove(data), ExtendableEvent::IsTrusted::Yes);
+        serviceWorkerGlobalScope->dispatchEvent(pushEvent);
+
+        pushEvent->whenAllExtendLifetimePromisesAreSettled([weakThis = WTFMove(weakThis), callback = WTFMove(callback)](auto&& extendLifetimePromises) mutable {
+            bool hasRejectedAnyPromise = false;
+            for (auto& promise : extendLifetimePromises) {
+                if (promise->status() == DOMPromise::Status::Rejected) {
+                    hasRejectedAnyPromise = true;
+                    break;
+                }
+            }
+            callback(!hasRejectedAnyPromise);
+        });
+    });
+}
+
 void ServiceWorkerThread::finishedEvaluatingScript()
 {
     ASSERT(globalScope()->isContextThread());
@@ -244,6 +267,12 @@
     startHeartBeatTimer();
 }
 
+void ServiceWorkerThread::startPushEventMonitoring()
+{
+    m_isHandlingPushEvent = true;
+    startHeartBeatTimer();
+}
+
 void ServiceWorkerThread::startHeartBeatTimer()
 {
     // We cannot detect responsiveness for service workers running on the main thread by using a main thread timer.
@@ -266,7 +295,7 @@
 void ServiceWorkerThread::heartBeatTimerFired()
 {
     if (!m_ongoingHeartBeatCheck) {
-        if (m_state == State::Installing || m_state == State::Activating || m_isHandlingFetchEvent || m_messageEventCount)
+        if (m_state == State::Installing || m_state == State::Activating || m_isHandlingFetchEvent || m_isHandlingPushEvent || m_messageEventCount)
             startHeartBeatTimer();
         return;
     }

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h (283437 => 283438)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h	2021-10-02 11:57:48 UTC (rev 283438)
@@ -66,6 +66,7 @@
     void queueTaskToPostMessage(MessageWithMessagePorts&&, ServiceWorkerOrClientData&& sourceData);
     void queueTaskToFireInstallEvent();
     void queueTaskToFireActivateEvent();
+    void queueTaskToFirePushEvent(std::optional<Vector<uint8_t>>&&, Function<void(bool)>&&);
 
     ServiceWorkerIdentifier identifier() const { return m_serviceWorkerIdentifier; }
     std::optional<ServiceWorkerJobDataIdentifier> jobDataIdentifier() const { return m_jobDataIdentifier; }
@@ -73,6 +74,8 @@
 
     void startFetchEventMonitoring();
     void stopFetchEventMonitoring() { m_isHandlingFetchEvent = false; }
+    void startPushEventMonitoring();
+    void stopPushEventMonitoring() { m_isHandlingPushEvent = false; }
 
 protected:
     Ref<WorkerGlobalScope> createWorkerGlobalScope(const WorkerParameters&, Ref<SecurityOrigin>&&, Ref<SecurityOrigin>&& topOrigin) final;
@@ -101,6 +104,7 @@
     bool m_doesHandleFetch { false };
 
     bool m_isHandlingFetchEvent { false };
+    bool m_isHandlingPushEvent { false };
     uint64_t m_messageEventCount { 0 };
     enum class State { Idle, Starting, Installing, Activating };
     State m_state { State::Idle };

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp (283437 => 283438)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp	2021-10-02 11:57:48 UTC (rev 283438)
@@ -122,6 +122,10 @@
 {
     ASSERT(allServiceWorkerThreadProxies().contains(this));
     allServiceWorkerThreadProxies().remove(this);
+
+    auto pushTasks = WTFMove(m_ongoingPushTasks);
+    for (auto& callback : pushTasks.values())
+        callback(false);
 }
 
 void ServiceWorkerThreadProxy::setLastNavigationWasAppInitiated(bool wasAppInitiated)
@@ -294,6 +298,28 @@
     });
 }
 
+void ServiceWorkerThreadProxy::firePushEvent(std::optional<Vector<uint8_t>>&& data, CompletionHandler<void(bool)>&& callback)
+{
+    if (m_ongoingPushTasks.isEmpty())
+        thread().startPushEventMonitoring();
+
+    auto identifier = ++m_pushTasksCounter;
+    ASSERT(!m_ongoingPushTasks.contains(identifier));
+    m_ongoingPushTasks.add(identifier, WTFMove(callback));
+    bool isPosted = postTaskForModeToWorkerOrWorkletGlobalScope([this, protectedThis = Ref { *this }, identifier, data = "" mutable {
+        thread().queueTaskToFirePushEvent(WTFMove(data), [this, protectedThis = WTFMove(protectedThis), identifier](bool result) mutable {
+            callOnMainThread([this, protectedThis = WTFMove(protectedThis), identifier, result]() mutable {
+                if (auto callback = m_ongoingPushTasks.take(identifier))
+                    callback(result);
+                if (m_ongoingPushTasks.isEmpty())
+                    thread().stopPushEventMonitoring();
+            });
+        });
+    }, WorkerRunLoop::defaultMode());
+    if (!isPosted)
+        m_ongoingPushTasks.take(identifier)(false);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h (283437 => 283438)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h	2021-10-02 09:07:12 UTC (rev 283437)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h	2021-10-02 11:57:48 UTC (rev 283438)
@@ -80,6 +80,8 @@
     void postMessageToServiceWorker(MessageWithMessagePorts&&, ServiceWorkerOrClientData&&);
     void fireInstallEvent();
     void fireActivateEvent();
+    void firePushEvent(std::optional<Vector<uint8_t>>&&, CompletionHandler<void(bool)>&&);
+
     void didSaveScriptsToDisk(ScriptBuffer&&, HashMap<URL, ScriptBuffer>&& importedScripts);
 
     WEBCORE_EXPORT void setLastNavigationWasAppInitiated(bool);
@@ -112,6 +114,8 @@
 
     ServiceWorkerInspectorProxy m_inspectorProxy;
     HashMap<std::pair<SWServerConnectionIdentifier, FetchIdentifier>, Ref<ServiceWorkerFetch::Client>> m_ongoingFetchTasks;
+    uint64_t m_pushTasksCounter { 0 };
+    HashMap<uint64_t, CompletionHandler<void(bool)>> m_ongoingPushTasks;
 };
 
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to