Implement https://w3c.github.io/ServiceWorker/#clients-getall
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 Dec 2017 19:41:00 +0000 (19:41 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 Dec 2017 19:41:00 +0000 (19:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180276

Patch by Youenn Fablet <youenn@apple.com> on 2017-12-02
Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

* web-platform-tests/service-workers/cache-storage/serviceworker/credentials.https-expected.txt:
* web-platform-tests/service-workers/service-worker/navigate-window.https-expected.txt:

Source/WebCore:

Test: http/tests/workers/service/serviceworkerclients-matchAll.https.html

Move Clients QueryOptions to its own class since it is used by various parties.
Add encoder/decoder routines.

Add a ServieWorkerClientInformation which replaces SWServer::ClientInformation structure.
This is what is sent back as a result to matchAll requests.
Add encoder/decoder routines.

Implement matchAll by hopping to the main thread, making IPC to the storage process.
SWServer in storage process then iterates through the relevant service workers and does some filtering.
Additional filtering and information should be gathered in future patches to fully implement the algorithm.

Add to SWServer a HashMap to easily identify by which service worker a client is controlled, if any.
This map is updated at the same time registrations are updated.

matchAll is given a callback as in the future, window client information will be retrieved asynchronously.

* WebCore.xcodeproj/project.pbxproj:
* workers/service/ServiceWorkerClientInformation.h: Added.
(WebCore::ServiceWorkerClientInformation::isolatedCopy const):
(WebCore::ServiceWorkerClientInformation::encode const):
(WebCore::ServiceWorkerClientInformation::decode):
* workers/service/ServiceWorkerClientQueryOptions.h: Added.
(WebCore::ServiceWorkerClientQueryOptions::encode const):
(WebCore::ServiceWorkerClientQueryOptions::decode):
* workers/service/ServiceWorkerClients.cpp:
(WebCore::ServiceWorkerClients::matchAll):
* workers/service/ServiceWorkerClients.h:
* workers/service/context/SWContextManager.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::matchAll):
(WebCore::SWServer::registerServiceWorkerClient):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerToContextConnection.cpp:
(WebCore::SWServerToContextConnection::matchAll):
* workers/service/server/SWServerToContextConnection.h:
* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::matchAll):
* workers/service/server/SWServerWorker.h:

Source/WebKit:

Add IPC plumbery for clients.matchAll between ServiceWorker process and Storage process.

* StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::matchAllCompleted):
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::matchAll):
(WebKit::WebSWContextManagerConnection::matchAllCompleted):
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:

LayoutTests:

* http/tests/workers/service/serviceworkerclients-matchAll-worker.js: Added.
* http/tests/workers/service/serviceworkerclients-matchAll.https-expected.txt: Added.
* http/tests/workers/service/serviceworkerclients-matchAll.https.html: Added.

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

28 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll-worker.js [new file with mode: 0644]
LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll.https-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll.https.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/serviceworker/credentials.https-expected.txt
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigate-window.https-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/workers/service/ServiceWorkerClientInformation.h [new file with mode: 0644]
Source/WebCore/workers/service/ServiceWorkerClientQueryOptions.h [new file with mode: 0644]
Source/WebCore/workers/service/ServiceWorkerClients.cpp
Source/WebCore/workers/service/ServiceWorkerClients.h
Source/WebCore/workers/service/ServiceWorkerClients.idl
Source/WebCore/workers/service/context/SWContextManager.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerToContextConnection.cpp
Source/WebCore/workers/service/server/SWServerToContextConnection.h
Source/WebCore/workers/service/server/SWServerWorker.cpp
Source/WebCore/workers/service/server/SWServerWorker.h
Source/WebKit/ChangeLog
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in

index ee80feb..3e41b8b 100644 (file)
@@ -1,3 +1,14 @@
+2017-12-02  Youenn Fablet  <youenn@apple.com>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-getall
+        https://bugs.webkit.org/show_bug.cgi?id=180276
+
+        Reviewed by Chris Dumez.
+
+        * http/tests/workers/service/serviceworkerclients-matchAll-worker.js: Added.
+        * http/tests/workers/service/serviceworkerclients-matchAll.https-expected.txt: Added.
+        * http/tests/workers/service/serviceworkerclients-matchAll.https.html: Added.
+
 2017-12-01  Alicia Boya GarcĂ­a  <aboya@igalia.com>
 
         [MSE] Use correct range end checks in sourceBufferPrivateDidReceiveSample()
diff --git a/LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll-worker.js b/LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll-worker.js
new file mode 100644 (file)
index 0000000..f1cd153
--- /dev/null
@@ -0,0 +1,41 @@
+var matchAllPromise1 = self.clients.matchAll().then((clients) => {
+    return clients.length === 0 ? "PASS" : "FAIL: expected no matched client, got " + clients.length;
+}, (e) => {
+    return "FAIL: matchAll 1 rejected with " + e;
+});
+
+
+var matchedClients;
+matchAllPromise2 = self.clients.matchAll({ includeUncontrolled : true }).then((c) => {
+    matchedClients = c;
+    return matchedClients.length === 1 ? "PASS" : "FAIL: expected one matched client, got " + matchedClients.length;
+}, (e) => {
+    return "FAIL: matchAll 2 rejected with " + e;
+});
+
+async function doTestAfterMessage(event)
+{
+    try {
+        if (event.data !== "start") {
+            event.source.postMessage("FAIL: received unexpected message from client");
+            return;
+        }
+
+        var result = await matchAllPromise1;
+        if (result !== "PASS") {
+            event.source.postMessage(result);
+            return;
+        }
+
+        var result = await matchAllPromise2;
+        if (result !== "PASS") {
+            event.source.postMessage(result);
+            return;
+        }
+        event.source.postMessage("PASS");
+    } catch (e) {
+        event.source.postMessage("FAIL: received exception " + e);
+    }
+}
+
+self.addEventListener("message", doTestAfterMessage);
diff --git a/LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll.https-expected.txt b/LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll.https-expected.txt
new file mode 100644 (file)
index 0000000..5928425
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS Setup worker 
+PASS Test self.clients.matchAll 
+
diff --git a/LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll.https.html b/LayoutTests/http/tests/workers/service/serviceworkerclients-matchAll.https.html
new file mode 100644 (file)
index 0000000..9af4d98
--- /dev/null
@@ -0,0 +1,42 @@
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+var scope = "/workers/service/serviceworkerclients-claim.https.html";
+var activeWorker;
+
+promise_test(async (test) => {
+    var registration = await navigator.serviceWorker.getRegistration(scope);
+    if (registration && registration.scope === scope)
+        await registration.unregister();
+
+    var registration = await navigator.serviceWorker.register("serviceworkerclients-matchAll-worker.js", { scope : scope });
+    activeWorker = registration.active;
+    if (activeWorker)
+        return;
+    activeWorker = registration.installing;
+    return new Promise(resolve => {
+        activeWorker.addEventListener('statechange', () => {
+            if (activeWorker.state === "activated")
+                resolve();
+        });
+    });
+}, "Setup worker");
+
+promise_test(async (test) => {
+    var promise = new Promise((resolve, reject) => {
+        navigator.serviceWorker.addEventListener("message", test.step_func((event) => {
+            assert_equals(event.data, "PASS");
+            resolve();
+        }));
+    });
+
+    activeWorker.postMessage("start");
+    await promise;
+}, "Test self.clients.matchAll");
+</script>
+</body>
+</html>
index 2713eae..e459a7c 100644 (file)
@@ -1,3 +1,13 @@
+2017-12-02  Youenn Fablet  <youenn@apple.com>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-getall
+        https://bugs.webkit.org/show_bug.cgi?id=180276
+
+        Reviewed by Chris Dumez.
+
+        * web-platform-tests/service-workers/cache-storage/serviceworker/credentials.https-expected.txt:
+        * web-platform-tests/service-workers/service-worker/navigate-window.https-expected.txt:
+
 2017-12-01  Chris Dumez  <cdumez@apple.com>
 
         Drop clientCreationURL from ServiceWorkerRegistrationKey
index a8165a7..7d4e69d 100644 (file)
@@ -1,4 +1,4 @@
 
-FAIL Clients.matchAll() should not show an old window as controlled after it navigates. assert_unreached: unexpected rejection: matchAll() rejected with "NotSupportedError: clients.matchAll() is not yet supported" Reached unreachable code
-FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: matchAll() rejected with "NotSupportedError: clients.matchAll() is not yet supported" Reached unreachable code
+PASS Clients.matchAll() should not show an old window as controlled after it navigates. 
+FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: assert_equals: expected number of clients expected 3 but got 2 Reached unreachable code
 
index 26cad89..97efa2b 100644 (file)
@@ -1,3 +1,51 @@
+2017-12-02  Youenn Fablet  <youenn@apple.com>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-getall
+        https://bugs.webkit.org/show_bug.cgi?id=180276
+
+        Reviewed by Chris Dumez.
+
+        Test: http/tests/workers/service/serviceworkerclients-matchAll.https.html
+
+        Move Clients QueryOptions to its own class since it is used by various parties.
+        Add encoder/decoder routines.
+
+        Add a ServieWorkerClientInformation which replaces SWServer::ClientInformation structure.
+        This is what is sent back as a result to matchAll requests.
+        Add encoder/decoder routines.
+
+        Implement matchAll by hopping to the main thread, making IPC to the storage process.
+        SWServer in storage process then iterates through the relevant service workers and does some filtering.
+        Additional filtering and information should be gathered in future patches to fully implement the algorithm.
+
+        Add to SWServer a HashMap to easily identify by which service worker a client is controlled, if any.
+        This map is updated at the same time registrations are updated.
+
+        matchAll is given a callback as in the future, window client information will be retrieved asynchronously.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * workers/service/ServiceWorkerClientInformation.h: Added.
+        (WebCore::ServiceWorkerClientInformation::isolatedCopy const):
+        (WebCore::ServiceWorkerClientInformation::encode const):
+        (WebCore::ServiceWorkerClientInformation::decode):
+        * workers/service/ServiceWorkerClientQueryOptions.h: Added.
+        (WebCore::ServiceWorkerClientQueryOptions::encode const):
+        (WebCore::ServiceWorkerClientQueryOptions::decode):
+        * workers/service/ServiceWorkerClients.cpp:
+        (WebCore::ServiceWorkerClients::matchAll):
+        * workers/service/ServiceWorkerClients.h:
+        * workers/service/context/SWContextManager.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::matchAll):
+        (WebCore::SWServer::registerServiceWorkerClient):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerToContextConnection.cpp:
+        (WebCore::SWServerToContextConnection::matchAll):
+        * workers/service/server/SWServerToContextConnection.h:
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::matchAll):
+        * workers/service/server/SWServerWorker.h:
+
 2017-12-02  Brady Eidson  <beidson@apple.com>
 
         Factor out the "databaseTaskQueue" parts of IDBServer into something reusable.
index 0efdcdc..6773bc5 100644 (file)
                415080361E3F00AD0051D75D /* LibWebRTCAudioModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 415080341E3F00AA0051D75D /* LibWebRTCAudioModule.cpp */; };
                415080371E3F00B00051D75D /* LibWebRTCAudioModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 415080351E3F00AA0051D75D /* LibWebRTCAudioModule.h */; };
                4150F9F112B6E0E70008C860 /* SliderThumbElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4150F9EF12B6E0E70008C860 /* SliderThumbElement.h */; };
+               41519CB81FD1F02E007F623C /* ServiceWorkerClientQueryOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 413FC4CD1FD1DD8C00541C4B /* ServiceWorkerClientQueryOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4151E5BB1FBA4C7A00E47E2D /* SWOriginStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4151E5B71FBA4C7500E47E2D /* SWOriginStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
                415747471E3869A400E914D8 /* LibWebRTCMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 415747431E38699E00E914D8 /* LibWebRTCMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
                415747481E3869A700E914D8 /* LibWebRTCProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 415747441E38699E00E914D8 /* LibWebRTCProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41B2A6261EF1BF6D002B9D7A /* WebAudioSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 41B2A6251EF1BF60002B9D7A /* WebAudioSourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41BF700C0FE86F49005E8DEC /* MessagePortChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41BF70100FE86F61005E8DEC /* PlatformMessagePortChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 41BF700E0FE86F61005E8DEC /* PlatformMessagePortChannel.h */; };
+               41C68AF51FD2279000AAA3B3 /* ServiceWorkerClientInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C68AF31FD21E8E00AAA3B3 /* ServiceWorkerClientInformation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41C760B10EDE03D300C1655F /* ScriptState.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C760B00EDE03D300C1655F /* ScriptState.h */; settings = {ATTRIBUTES = (Private, ); }; };
                41CAD71E1EA090A100178164 /* VideoToolBoxEncoderFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41CAD71C1EA0905700178164 /* VideoToolBoxEncoderFactory.cpp */; };
                41D015CA0F4B5C71004A662F /* ContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D015C80F4B5C71004A662F /* ContentType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                413E00771DB0E4DE002341D2 /* MemoryRelease.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryRelease.cpp; sourceTree = "<group>"; };
                413E00781DB0E4DE002341D2 /* MemoryRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryRelease.h; sourceTree = "<group>"; };
                413E007B1DB0E707002341D2 /* MemoryReleaseCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryReleaseCocoa.mm; sourceTree = "<group>"; };
+               413FC4CD1FD1DD8C00541C4B /* ServiceWorkerClientQueryOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerClientQueryOptions.h; sourceTree = "<group>"; };
                4147E2B21C88337F00A7E715 /* FetchBodyOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchBodyOwner.h; sourceTree = "<group>"; };
                4147E2B31C89912600A7E715 /* FetchBodyOwner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchBodyOwner.cpp; sourceTree = "<group>"; };
                4147E2B41C89912600A7E715 /* FetchLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchLoader.cpp; sourceTree = "<group>"; };
                41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagePortChannel.h; sourceTree = "<group>"; };
                41BF700D0FE86F61005E8DEC /* PlatformMessagePortChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformMessagePortChannel.cpp; path = default/PlatformMessagePortChannel.cpp; sourceTree = "<group>"; };
                41BF700E0FE86F61005E8DEC /* PlatformMessagePortChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatformMessagePortChannel.h; path = default/PlatformMessagePortChannel.h; sourceTree = "<group>"; };
+               41C68AF31FD21E8E00AAA3B3 /* ServiceWorkerClientInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerClientInformation.h; sourceTree = "<group>"; };
                41C760B00EDE03D300C1655F /* ScriptState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptState.h; sourceTree = "<group>"; };
                41C7E1051E6A54360027B4DE /* CanvasCaptureMediaStreamTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasCaptureMediaStreamTrack.cpp; sourceTree = "<group>"; };
                41C7E1061E6A54360027B4DE /* CanvasCaptureMediaStreamTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasCaptureMediaStreamTrack.h; sourceTree = "<group>"; };
                                8379363C1FBBB0A400C8023C /* ServiceWorkerClientData.cpp */,
                                8379363E1FBBB0A500C8023C /* ServiceWorkerClientData.h */,
                                837D46251FA2A8C50054E1FA /* ServiceWorkerClientIdentifier.h */,
+                               41C68AF31FD21E8E00AAA3B3 /* ServiceWorkerClientInformation.h */,
+                               413FC4CD1FD1DD8C00541C4B /* ServiceWorkerClientQueryOptions.h */,
                                46EF14211F97B7BA00C2A524 /* ServiceWorkerClients.cpp */,
                                46EF14221F97B7BA00C2A524 /* ServiceWorkerClients.h */,
                                46EF14231F97B7BA00C2A524 /* ServiceWorkerClients.idl */,
                                46EF142D1F97B7D800C2A524 /* ServiceWorkerClient.h in Headers */,
                                8379363F1FBBB0B400C8023C /* ServiceWorkerClientData.h in Headers */,
                                837D46271FA2A8CE0054E1FA /* ServiceWorkerClientIdentifier.h in Headers */,
+                               41C68AF51FD2279000AAA3B3 /* ServiceWorkerClientInformation.h in Headers */,
+                               41519CB81FD1F02E007F623C /* ServiceWorkerClientQueryOptions.h in Headers */,
                                46EF142C1F97B7D800C2A524 /* ServiceWorkerClients.h in Headers */,
                                8369FDFC1FA102E300C1FF1F /* ServiceWorkerClientType.h in Headers */,
                                51F1755F1F3EBC8300C74950 /* ServiceWorkerContainer.h in Headers */,
diff --git a/Source/WebCore/workers/service/ServiceWorkerClientInformation.h b/Source/WebCore/workers/service/ServiceWorkerClientInformation.h
new file mode 100644 (file)
index 0000000..c9f7f64
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "ServiceWorkerClientData.h"
+#include "ServiceWorkerClientIdentifier.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class ScriptExecutionContext;
+
+struct ServiceWorkerClientInformation {
+    ServiceWorkerClientIdentifier identifier;
+    ServiceWorkerClientData data;
+
+    ServiceWorkerClientInformation isolatedCopy() const { return { identifier, data.isolatedCopy() }; }
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<ServiceWorkerClientInformation> decode(Decoder&);
+};
+
+using ServiceWorkerClientsMatchAllCallback = WTF::CompletionHandler<void(Vector<ServiceWorkerClientInformation>&&)>;
+
+template<class Encoder>
+void ServiceWorkerClientInformation::encode(Encoder& encoder) const
+{
+    encoder << identifier << data;
+}
+
+template<class Decoder>
+std::optional<ServiceWorkerClientInformation> ServiceWorkerClientInformation::decode(Decoder& decoder)
+{
+    std::optional<ServiceWorkerClientIdentifier> identifier;
+    decoder >> identifier;
+    if (!identifier)
+        return std::nullopt;
+
+    std::optional<ServiceWorkerClientData> data;
+    decoder >> data;
+    if (!data)
+        return std::nullopt;
+
+    return { { WTFMove(*identifier), WTFMove(*data) } };
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
diff --git a/Source/WebCore/workers/service/ServiceWorkerClientQueryOptions.h b/Source/WebCore/workers/service/ServiceWorkerClientQueryOptions.h
new file mode 100644 (file)
index 0000000..14aaef6
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#if ENABLE(SERVICE_WORKER)
+
+#include "ServiceWorkerClientType.h"
+
+namespace WebCore {
+
+struct ServiceWorkerClientQueryOptions {
+    bool includeUncontrolled { false };
+    ServiceWorkerClientType type { ServiceWorkerClientType::Window };
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<ServiceWorkerClientQueryOptions> decode(Decoder&);
+};
+
+template<class Encoder>
+void ServiceWorkerClientQueryOptions::encode(Encoder& encoder) const
+{
+    encoder << includeUncontrolled << type;
+}
+
+template<class Decoder>
+std::optional<ServiceWorkerClientQueryOptions> ServiceWorkerClientQueryOptions::decode(Decoder& decoder)
+{
+    std::optional<bool> includeUncontrolled;
+    decoder >> includeUncontrolled;
+    if (!includeUncontrolled)
+        return std::nullopt;
+
+    std::optional<ServiceWorkerClientType> type;
+    decoder >> type;
+    if (!type)
+        return std::nullopt;
+
+    return { { *includeUncontrolled, *type } };
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index a4ebc7a..4504f53 100644 (file)
@@ -74,18 +74,40 @@ void ServiceWorkerClients::get(ScriptExecutionContext& context, const String& id
     });
 }
 
-void ServiceWorkerClients::matchAll(const ClientQueryOptions&, Ref<DeferredPromise>&& promise)
+
+static inline void matchAllCompleted(ServiceWorkerGlobalScope& scope, DeferredPromise& promise, Vector<ServiceWorkerClientInformation>&& clientsData)
 {
-    promise->reject(Exception { NotSupportedError, ASCIILiteral("clients.matchAll() is not yet supported") });
+    auto clients = WTF::map(clientsData, [&] (auto&& client) {
+        return ServiceWorkerClient::getOrCreate(scope, client.identifier, WTFMove(client.data));
+    });
+    promise.resolve<IDLSequence<IDLInterface<ServiceWorkerClient>>>(WTFMove(clients));
+}
+
+void ServiceWorkerClients::matchAll(ScriptExecutionContext& context, const ClientQueryOptions& options, Ref<DeferredPromise>&& promise)
+{
+    auto promisePointer = promise.ptr();
+    m_pendingPromises.add(promisePointer, WTFMove(promise));
+
+    auto serviceWorkerIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
+
+    callOnMainThread([promisePointer, serviceWorkerIdentifier, options] () mutable {
+        auto connection = SWContextManager::singleton().connection();
+        connection->matchAll(serviceWorkerIdentifier, options, [promisePointer, serviceWorkerIdentifier] (auto&& clientsData) mutable {
+            SWContextManager::singleton().postTaskToServiceWorker(serviceWorkerIdentifier, [promisePointer, clientsData = crossThreadCopy(clientsData)] (auto& scope) mutable {
+                if (auto promise = scope.clients().m_pendingPromises.take(promisePointer))
+                    matchAllCompleted(scope, *promise, WTFMove(clientsData));
+            });
+        });
+    });
 }
 
-void ServiceWorkerClients::openWindow(const String& url, Ref<DeferredPromise>&& promise)
+void ServiceWorkerClients::openWindow(ScriptExecutionContext&, const String& url, Ref<DeferredPromise>&& promise)
 {
     UNUSED_PARAM(url);
     promise->reject(Exception { NotSupportedError, ASCIILiteral("clients.openWindow() is not yet supported") });
 }
 
-void ServiceWorkerClients::claim(Ref<DeferredPromise>&& promise)
+void ServiceWorkerClients::claim(ScriptExecutionContext&, Ref<DeferredPromise>&& promise)
 {
     promise->reject(Exception { NotSupportedError, ASCIILiteral("clients.claim() is not yet supported") });
 }
index 9cac0f6..4075da5 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "ServiceWorkerClientQueryOptions.h"
 #include "ServiceWorkerClientType.h"
 #include "ServiceWorkerIdentifier.h"
 #include <wtf/Ref.h>
@@ -46,15 +47,12 @@ public:
         return adoptRef(*new ServiceWorkerClients);
     }
 
-    struct ClientQueryOptions {
-        bool includeUncontrolled { false };
-        ServiceWorkerClientType type { ServiceWorkerClientType::Window };
-    };
+    using ClientQueryOptions = ServiceWorkerClientQueryOptions;
 
     void get(ScriptExecutionContext&, const String& id, Ref<DeferredPromise>&&);
-    void matchAll(const ClientQueryOptions&, Ref<DeferredPromise>&&);
-    void openWindow(const String& url, Ref<DeferredPromise>&&);
-    void claim(Ref<DeferredPromise>&&);
+    void matchAll(ScriptExecutionContext&, const ClientQueryOptions&, Ref<DeferredPromise>&&);
+    void openWindow(ScriptExecutionContext&, const String& url, Ref<DeferredPromise>&&);
+    void claim(ScriptExecutionContext&, Ref<DeferredPromise>&&);
 
 private:
     ServiceWorkerClients() = default;
index 48a2082..0203d7d 100644 (file)
@@ -33,9 +33,9 @@
 ] interface ServiceWorkerClients {
     // The objects returned will be new instances every time
     [NewObject, CallWith=ScriptExecutionContext] Promise<any> get(DOMString id);
-    [NewObject] Promise<sequence<Client>> matchAll(optional ClientQueryOptions options);
-    [NewObject] Promise<WindowClient?> openWindow(USVString url);
-    [NewObject] Promise<void> claim();
+    [NewObject, CallWith=ScriptExecutionContext] Promise<sequence<Client>> matchAll(optional ClientQueryOptions options);
+    [NewObject, CallWith=ScriptExecutionContext] Promise<WindowClient?> openWindow(USVString url);
+    [NewObject, CallWith=ScriptExecutionContext] Promise<void> claim();
 };
 
 dictionary ClientQueryOptions {
index 7b0e8a6..f0b10a0 100644 (file)
@@ -28,6 +28,8 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "ExceptionOr.h"
+#include "ServiceWorkerClientInformation.h"
+#include "ServiceWorkerClientQueryOptions.h"
 #include "ServiceWorkerIdentifier.h"
 #include "ServiceWorkerThreadProxy.h"
 #include <wtf/CompletionHandler.h>
@@ -36,7 +38,6 @@
 namespace WebCore {
 
 class SerializedScriptValue;
-struct ServiceWorkerClientIdentifier;
 class ServiceWorkerGlobalScope;
 
 class SWContextManager {
@@ -56,6 +57,7 @@ public:
 
         using FindClientByIdentifierCallback = WTF::CompletionHandler<void(ExceptionOr<std::optional<ServiceWorkerClientData>>&&)>;
         virtual void findClientByIdentifier(ServiceWorkerIdentifier, ServiceWorkerClientIdentifier, FindClientByIdentifierCallback&&) = 0;
+        virtual void matchAll(ServiceWorkerIdentifier, const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&) = 0;
     };
 
     WEBCORE_EXPORT void setConnection(std::unique_ptr<Connection>&&);
index 0c37e2d..bbcb4c8 100644 (file)
@@ -41,6 +41,7 @@
 #include "ServiceWorkerContextData.h"
 #include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerJobData.h"
+#include <wtf/CompletionHandler.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/text/WTFString.h>
 
@@ -312,8 +313,11 @@ void SWServer::didFinishActivation(SWServerWorker& worker)
         SWServerJobQueue::didFinishActivation(*registration, worker.identifier());
 }
 
+// https://w3c.github.io/ServiceWorker/#clients-get
 std::optional<ServiceWorkerClientData> SWServer::findClientByIdentifier(const ClientOrigin& origin, ServiceWorkerClientIdentifier clientIdentifier)
 {
+    // FIXME: Support WindowClient additional properties.
+
     auto iterator = m_clients.find(origin);
     if (iterator == m_clients.end())
         return std::nullopt;
@@ -326,6 +330,27 @@ std::optional<ServiceWorkerClientData> SWServer::findClientByIdentifier(const Cl
     return (position != notFound) ? std::make_optional(clients[position].data) : std::nullopt;
 }
 
+// https://w3c.github.io/ServiceWorker/#clients-getall
+void SWServer::matchAll(SWServerWorker& worker, const ServiceWorkerClientQueryOptions& options, ServiceWorkerClientsMatchAllCallback&& callback)
+{
+    // FIXME: Support reserved client filtering.
+    // FIXME: Support WindowClient additional properties.
+
+    auto clients = m_clients.get(worker.origin());
+
+    if (!options.includeUncontrolled) {
+        clients.removeAllMatching([&] (const auto& client) {
+            return worker.identifier() != m_clientToControllingWorker.get(client.identifier);
+        });
+    }
+    if (options.type != ServiceWorkerClientType::All) {
+        clients.removeAllMatching([&] (const auto& client) {
+            return options.type != client.data.type;
+        });
+    }
+    callback(WTFMove(clients));
+}
+
 void SWServer::didResolveRegistrationPromise(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey)
 {
     ASSERT_UNUSED(connection, m_connections.contains(connection.identifier()));
@@ -356,22 +381,31 @@ void SWServer::removeClientServiceWorkerRegistration(Connection& connection, Ser
     registration->removeClientServiceWorkerRegistration(connection.identifier());
 }
 
-void SWServer::serviceWorkerStartedControllingClient(Connection& connection, ServiceWorkerIdentifier, ServiceWorkerRegistrationIdentifier registrationIdentifier, DocumentIdentifier contextIdentifier)
+void SWServer::serviceWorkerStartedControllingClient(Connection& connection, ServiceWorkerIdentifier serviceWorkerIdentifier, ServiceWorkerRegistrationIdentifier registrationIdentifier, DocumentIdentifier contextIdentifier)
 {
     auto* registration = m_registrationsByID.get(registrationIdentifier);
     if (!registration)
         return;
 
-    registration->addClientUsingRegistration({ connection.identifier(), contextIdentifier });
+    ServiceWorkerClientIdentifier clientIdentifier { connection.identifier(), contextIdentifier };
+    registration->addClientUsingRegistration(clientIdentifier);
+
+    auto result = m_clientToControllingWorker.add(clientIdentifier, serviceWorkerIdentifier);
+    ASSERT_UNUSED(result, result.isNewEntry);
 }
 
-void SWServer::serviceWorkerStoppedControllingClient(Connection& connection, ServiceWorkerIdentifier, ServiceWorkerRegistrationIdentifier registrationIdentifier, DocumentIdentifier contextIdentifier)
+void SWServer::serviceWorkerStoppedControllingClient(Connection& connection, ServiceWorkerIdentifier serviceWorkerIdentifier, ServiceWorkerRegistrationIdentifier registrationIdentifier, DocumentIdentifier contextIdentifier)
 {
+    UNUSED_PARAM(serviceWorkerIdentifier);
     auto* registration = m_registrationsByID.get(registrationIdentifier);
     if (!registration)
         return;
 
-    registration->removeClientUsingRegistration({ connection.identifier(), contextIdentifier });
+    ServiceWorkerClientIdentifier clientIdentifier { connection.identifier(), contextIdentifier };
+    registration->removeClientUsingRegistration(clientIdentifier);
+
+    auto result = m_clientToControllingWorker.take(clientIdentifier);
+    ASSERT_UNUSED(result, result == serviceWorkerIdentifier);
 }
 
 void SWServer::updateWorker(Connection&, const ServiceWorkerJobDataIdentifier& jobDataIdentifier, SWServerRegistration& registration, const URL& url, const String& script, WorkerType type)
@@ -582,8 +616,8 @@ const SWServerRegistration* SWServer::doRegistrationMatching(const SecurityOrigi
 void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceWorkerClientIdentifier identifier, ServiceWorkerClientData&& data)
 {
     m_clients.ensure(WTFMove(clientOrigin), [] {
-        return Vector<ClientInformation> { };
-    }).iterator->value.append(ClientInformation { identifier, WTFMove(data) });
+        return Vector<ServiceWorkerClientInformation> { };
+    }).iterator->value.append(ServiceWorkerClientInformation { identifier, WTFMove(data) });
 }
 
 void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientIdentifier identifier)
index 8ba8974..dc6ef73 100644 (file)
@@ -55,6 +55,7 @@ class SWServerToContextConnection;
 enum class ServiceWorkerRegistrationState;
 enum class ServiceWorkerState;
 struct ExceptionData;
+struct ServiceWorkerClientQueryOptions;
 struct ServiceWorkerContextData;
 struct ServiceWorkerFetchResult;
 struct ServiceWorkerRegistrationData;
@@ -139,6 +140,7 @@ public:
     void didFinishActivation(SWServerWorker&);
     void workerContextTerminated(SWServerWorker&);
     std::optional<ServiceWorkerClientData> findClientByIdentifier(const ClientOrigin&, ServiceWorkerClientIdentifier);
+    void matchAll(SWServerWorker&, const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&);
 
     WEBCORE_EXPORT void serverToContextConnectionCreated();
     
@@ -182,11 +184,8 @@ private:
 
     HashMap<ServiceWorkerIdentifier, Ref<SWServerWorker>> m_runningOrTerminatingWorkers;
 
-    struct ClientInformation {
-        ServiceWorkerClientIdentifier identifier;
-        ServiceWorkerClientData data;
-    };
-    HashMap<ClientOrigin, Vector<ClientInformation>> m_clients;
+    HashMap<ClientOrigin, Vector<ServiceWorkerClientInformation>> m_clients;
+    HashMap<ServiceWorkerClientIdentifier, ServiceWorkerIdentifier> m_clientToControllingWorker;
 
     RefPtr<Thread> m_taskThread;
     Lock m_taskThreadLock;
index 737c78b..f61d7d3 100644 (file)
@@ -114,6 +114,15 @@ void SWServerToContextConnection::findClientByIdentifier(uint64_t requestIdentif
         globalServerToContextConnection()->findClientByIdentifierCompleted(requestIdentifier, worker->findClientByIdentifier(clientId), false);
 }
 
+void SWServerToContextConnection::matchAll(uint64_t requestIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, const ServiceWorkerClientQueryOptions& options)
+{
+    if (auto* worker = SWServerWorker::existingWorkerForIdentifier(serviceWorkerIdentifier)) {
+        worker->matchAll(options, [requestIdentifier] (auto&& data) {
+            globalServerToContextConnection()->matchAllCompleted(requestIdentifier, data);
+        });
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 47364c9..7be4131 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "ServiceWorkerClientQueryOptions.h"
 #include "ServiceWorkerIdentifier.h"
 #include "ServiceWorkerTypes.h"
 #include <wtf/RefCounted.h>
@@ -36,6 +37,7 @@ namespace WebCore {
 class SWServer;
 struct ServiceWorkerClientData;
 struct ServiceWorkerClientIdentifier;
+struct ServiceWorkerClientInformation;
 struct ServiceWorkerContextData;
 struct ServiceWorkerJobDataIdentifier;
 
@@ -52,6 +54,7 @@ public:
     virtual void terminateWorker(ServiceWorkerIdentifier) = 0;
     virtual void syncTerminateWorker(ServiceWorkerIdentifier) = 0;
     virtual void findClientByIdentifierCompleted(uint64_t requestIdentifier, const std::optional<ServiceWorkerClientData>&, bool hasSecurityError) = 0;
+    virtual void matchAllCompleted(uint64_t requestIdentifier, const Vector<ServiceWorkerClientInformation>&) = 0;
 
     // Messages back from the SW host process
     WEBCORE_EXPORT void scriptContextFailedToStart(const std::optional<ServiceWorkerJobDataIdentifier>&, ServiceWorkerIdentifier, const String& message);
@@ -61,6 +64,7 @@ public:
     WEBCORE_EXPORT void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool hasPendingEvents);
     WEBCORE_EXPORT void workerTerminated(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void findClientByIdentifier(uint64_t clientIdRequestIdentifier, ServiceWorkerIdentifier, ServiceWorkerClientIdentifier);
+    WEBCORE_EXPORT void matchAll(uint64_t requestIdentifier, ServiceWorkerIdentifier, const ServiceWorkerClientQueryOptions&);
 
     static SWServerToContextConnection* connectionForIdentifier(SWServerToContextConnectionIdentifier);
 
index bcf96dc..5bdc062 100644 (file)
@@ -111,6 +111,11 @@ std::optional<ServiceWorkerClientData> SWServerWorker::findClientByIdentifier(Se
     return m_server.findClientByIdentifier(origin(), clientId);
 }
 
+void SWServerWorker::matchAll(const ServiceWorkerClientQueryOptions& options, ServiceWorkerClientsMatchAllCallback&& callback)
+{
+    return m_server.matchAll(*this, options, WTFMove(callback));
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index df51f8f..e397c11 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(SERVICE_WORKER)
 
+#include "ServiceWorkerClientInformation.h"
 #include "ServiceWorkerData.h"
 #include "ServiceWorkerIdentifier.h"
 #include "ServiceWorkerRegistrationKey.h"
@@ -41,6 +42,7 @@ class SWServer;
 class SWServerRegistration;
 struct ServiceWorkerClientData;
 struct ServiceWorkerClientIdentifier;
+struct ServiceWorkerClientQueryOptions;
 struct ServiceWorkerContextData;
 struct ServiceWorkerJobDataIdentifier;
 enum class WorkerType;
@@ -87,6 +89,7 @@ public:
     void didFinishActivation();
     void contextTerminated();
     std::optional<ServiceWorkerClientData> findClientByIdentifier(ServiceWorkerClientIdentifier);
+    void matchAll(const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&);
 
     WEBCORE_EXPORT static SWServerWorker* existingWorkerForIdentifier(ServiceWorkerIdentifier);
 
index f473906..6437502 100644 (file)
@@ -1,3 +1,22 @@
+2017-12-02  Youenn Fablet  <youenn@apple.com>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-getall
+        https://bugs.webkit.org/show_bug.cgi?id=180276
+
+        Reviewed by Chris Dumez.
+
+        Add IPC plumbery for clients.matchAll between ServiceWorker process and Storage process.
+
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::matchAllCompleted):
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::matchAll):
+        (WebKit::WebSWContextManagerConnection::matchAllCompleted):
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
 2017-12-02  Joseph Pecoraro  <pecoraro@apple.com>
 
         Remote Web Inspector window always shows up at the default size
index 1bb1c88..b6d6eb4 100644 (file)
@@ -86,6 +86,11 @@ void WebSWServerToContextConnection::findClientByIdentifierCompleted(uint64_t re
     send(Messages::WebSWContextManagerConnection::FindClientByIdentifierCompleted { requestIdentifier, data, hasSecurityError });
 }
 
+void WebSWServerToContextConnection::matchAllCompleted(uint64_t requestIdentifier, const Vector<ServiceWorkerClientInformation>& clientsData)
+{
+    send(Messages::WebSWContextManagerConnection::MatchAllCompleted { requestIdentifier, clientsData });
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index 9172e3f..365f197 100644 (file)
@@ -61,6 +61,7 @@ private:
     void terminateWorker(WebCore::ServiceWorkerIdentifier) final;
     void syncTerminateWorker(WebCore::ServiceWorkerIdentifier) final;
     void findClientByIdentifierCompleted(uint64_t requestIdentifier, const std::optional<WebCore::ServiceWorkerClientData>&, bool hasSecurityError) final;
+    void matchAllCompleted(uint64_t requestIdentifier, const Vector<WebCore::ServiceWorkerClientInformation>&) final;
 
     Ref<IPC::Connection> m_ipcConnection;
     
index 0ef0188..0660b6d 100644 (file)
@@ -32,6 +32,7 @@ messages -> WebSWServerToContextConnection {
     SetServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier identifier, bool hasPendingEvents);
     WorkerTerminated(WebCore::ServiceWorkerIdentifier identifier);
     FindClientByIdentifier(uint64_t requestIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, struct WebCore::ServiceWorkerClientIdentifier clientIdentifier);
+    MatchAll(uint64_t matchAllRequestIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, struct WebCore::ServiceWorkerClientQueryOptions options);
 }
 
 #endif // ENABLE(SERVICE_WORKER)
index fd656c5..a5e307e 100644 (file)
@@ -220,6 +220,19 @@ void WebSWContextManagerConnection::findClientByIdentifierCompleted(uint64_t req
     }
 }
 
+void WebSWContextManagerConnection::matchAll(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, const ServiceWorkerClientQueryOptions& options, ServiceWorkerClientsMatchAllCallback&& callback)
+{
+    auto requestIdentifier = ++m_previousRequestIdentifier;
+    m_matchAllRequests.add(requestIdentifier, WTFMove(callback));
+    m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::MatchAll { requestIdentifier, serviceWorkerIdentifier, options }, 0);
+}
+
+void WebSWContextManagerConnection::matchAllCompleted(uint64_t requestIdentifier, Vector<ServiceWorkerClientInformation>&& clientsData)
+{
+    if (auto callback = m_matchAllRequests.take(requestIdentifier))
+        callback(WTFMove(clientsData));
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 597da4e..8e57622 100644 (file)
@@ -31,6 +31,7 @@
 #include "MessageReceiver.h"
 #include "WebSWContextManagerConnectionMessages.h"
 #include <WebCore/SWContextManager.h>
+#include <WebCore/ServiceWorkerClientInformation.h>
 #include <WebCore/ServiceWorkerTypes.h>
 
 namespace IPC {
@@ -64,6 +65,7 @@ private:
     void setServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier, bool) final;
     void workerTerminated(WebCore::ServiceWorkerIdentifier) final;
     void findClientByIdentifier(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerClientIdentifier, FindClientByIdentifierCallback&&) final;
+    void matchAll(WebCore::ServiceWorkerIdentifier, const WebCore::ServiceWorkerClientQueryOptions&, WebCore::ServiceWorkerClientsMatchAllCallback&&) final;
 
     // IPC messages.
     void serviceWorkerStartedWithMessage(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
@@ -75,12 +77,14 @@ private:
     void terminateWorker(WebCore::ServiceWorkerIdentifier);
     void syncTerminateWorker(WebCore::ServiceWorkerIdentifier, Ref<Messages::WebSWContextManagerConnection::SyncTerminateWorker::DelayedReply>&&);
     void findClientByIdentifierCompleted(uint64_t requestIdentifier, std::optional<WebCore::ServiceWorkerClientData>&&, bool hasSecurityError);
+    void matchAllCompleted(uint64_t matchAllRequestIdentifier, Vector<WebCore::ServiceWorkerClientInformation>&&);
 
     Ref<IPC::Connection> m_connectionToStorageProcess;
     uint64_t m_pageID { 0 };
     uint64_t m_previousServiceWorkerID { 0 };
 
     HashMap<uint64_t, FindClientByIdentifierCallback> m_findClientByIdentifierRequests;
+    HashMap<uint64_t, WebCore::ServiceWorkerClientsMatchAllCallback> m_matchAllRequests;
     uint64_t m_previousRequestIdentifier { 0 };
 };
 
index 7a1715e..c21a509 100644 (file)
@@ -31,6 +31,7 @@ messages -> WebSWContextManagerConnection {
     TerminateWorker(WebCore::ServiceWorkerIdentifier identifier)
     SyncTerminateWorker(WebCore::ServiceWorkerIdentifier identifier) -> () Delayed
     FindClientByIdentifierCompleted(uint64_t clientIdRequestIdentifier, std::optional<WebCore::ServiceWorkerClientData> data, bool hasSecurityError)
+    MatchAllCompleted(uint64_t matchAllRequestIdentifier, Vector<WebCore::ServiceWorkerClientInformation> clientsData)
 }
 
 #endif