Title: [225427] trunk
Revision
225427
Author
[email protected]
Date
2017-12-01 16:00:40 -0800 (Fri, 01 Dec 2017)

Log Message

Implement https://w3c.github.io/ServiceWorker/#clients-get
https://bugs.webkit.org/show_bug.cgi?id=180167

Patch by Youenn Fablet <[email protected]> on 2017-12-01
Reviewed by Chris Dumez.

Source/WebCore:

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

Implement clients get by having service worker clients do the following:
- Go to main thread to query the SWClientConnection for getting the client.
- SWClientConnection requests it through IPC to StorageProcess SWServer.
- SWServer looks at its client map and returns client data based on the given identifier.
- SWClientConnection sends it back to the right clients for resolving the promise.

Identifier is parsed at service worker process level.

Made ServiceWorkerClients no longer an ActiveDOMObject since it is owned by ServiceWorkerGlobalScope
and is only exposed in service workers.

* workers/service/ServiceWorkerClientIdentifier.h:
(WebCore::ServiceWorkerClientIdentifier::fromString):
* workers/service/ServiceWorkerClients.cpp:
(WebCore::ServiceWorkerClients::ServiceWorkerClients):
(WebCore::ServiceWorkerClients::get):
* workers/service/ServiceWorkerClients.h:
(WebCore::ServiceWorkerClients::create):
* workers/service/context/SWContextManager.cpp:
(WebCore::SWContextManager::postTaskToServiceWorker):
* workers/service/context/SWContextManager.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::getClientFromId):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerToContextConnection.cpp:
(WebCore::SWServerToContextConnection::findClientByIdentifier):
* workers/service/server/SWServerToContextConnection.h:
* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::origin const):
(WebCore::SWServerWorker::findClientByIdentifier):
* workers/service/server/SWServerWorker.h:

Source/WebKit:

Add IPC plumbery for clientFromId between ServiceWorker process and Storage process.

* StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::clientFromIdCompleted):
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::findClientByIdentifier):
(WebKit::WebSWContextManagerConnection::findClientByIdentifierCompleted):
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:

Source/WTF:

* wtf/text/StringView.h:
(WTF::StringView::toUInt64Strict const):
* wtf/text/WTFString.h:

LayoutTests:

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

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (225426 => 225427)


--- trunk/LayoutTests/ChangeLog	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/LayoutTests/ChangeLog	2017-12-02 00:00:40 UTC (rev 225427)
@@ -1,3 +1,14 @@
+2017-12-01  Youenn Fablet  <[email protected]>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-get
+        https://bugs.webkit.org/show_bug.cgi?id=180167
+
+        Reviewed by Chris Dumez.
+
+        * http/tests/workers/service/resources/serviceworkerclients-get-worker.js: Added.
+        * http/tests/workers/service/serviceworkerclients-get.https-expected.txt: Added.
+        * http/tests/workers/service/serviceworkerclients-get.https.html: Added.
+
 2017-12-01  Ryan Haddad  <[email protected]>
 
         Update TestExpectations for editing/input tests on iOS.

Added: trunk/LayoutTests/http/tests/workers/service/resources/serviceworkerclients-get-worker.js (0 => 225427)


--- trunk/LayoutTests/http/tests/workers/service/resources/serviceworkerclients-get-worker.js	                        (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/serviceworkerclients-get-worker.js	2017-12-02 00:00:40 UTC (rev 225427)
@@ -0,0 +1,41 @@
+var client = null;
+self.addEventListener("message", async (event) => {
+    try {
+        var client = event.source;
+
+        if (!(client instanceof WindowClient)) {
+            event.source.postMessage("FAIL: client source is not a WindowClient");
+            return;
+        }
+
+        var retrievedClient = await self.clients.get(client.id);
+        if (!retrievedClient) {
+            event.source.postMessage("FAIL: did not retrieve any client through self.clients.get");
+            return;
+        }
+
+        if (retrievedClient.id !== client.id) {
+            event.source.postMessage("FAIL: client id is different from retrieved client id through self.clients.get: " + client.id + " / " + retrievedClient.id);
+            return;
+        }
+
+        if (retrievedClient !== client) {
+            event.source.postMessage("FAIL: client is different from the one retrieved through self.clients.get");
+            return;
+        }
+
+        var badIds = [client.id + "0", "0-0", "0-1", "1-0", "0-", "-", "-0"];
+        for (id in badIds) {
+            retrievedClient = await self.clients.get(id);
+            if (!!retrievedClient) {
+                event.source.postMessage("FAIL: retrieved client with bad id " + id + " should be null");
+                return;
+            }
+        }
+
+        event.source.postMessage("PASS");
+    } catch (e) {
+        event.source.postMessage("FAIL: received exception " + e);
+    }
+});
+

Added: trunk/LayoutTests/http/tests/workers/service/serviceworkerclients-get.https-expected.txt (0 => 225427)


--- trunk/LayoutTests/http/tests/workers/service/serviceworkerclients-get.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/serviceworkerclients-get.https-expected.txt	2017-12-02 00:00:40 UTC (rev 225427)
@@ -0,0 +1,3 @@
+
+PASS Testing clients.get 
+

Added: trunk/LayoutTests/http/tests/workers/service/serviceworkerclients-get.https.html (0 => 225427)


--- trunk/LayoutTests/http/tests/workers/service/serviceworkerclients-get.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/serviceworkerclients-get.https.html	2017-12-02 00:00:40 UTC (rev 225427)
@@ -0,0 +1,27 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+
+promise_test(async (test) => {
+    var promise = new Promise((resolve) => {
+        navigator.serviceWorker.addEventListener("message", test.step_func((event) => {
+            assert_equals(event.data, "PASS");
+            resolve();
+        }));
+    });
+
+    var registration = await navigator.serviceWorker.register("resources/serviceworkerclients-get-worker.js", { scope : "/noone" });
+    var worker = registration.installing;
+    if (!worker)
+        worker = registration.active;
+    worker.postMessage("start");
+
+    await promise;
+}, "Testing clients.get");
+</script>
+</body>
+</html>

Modified: trunk/Source/WTF/ChangeLog (225426 => 225427)


--- trunk/Source/WTF/ChangeLog	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WTF/ChangeLog	2017-12-02 00:00:40 UTC (rev 225427)
@@ -1,3 +1,14 @@
+2017-12-01  Youenn Fablet  <[email protected]>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-get
+        https://bugs.webkit.org/show_bug.cgi?id=180167
+
+        Reviewed by Chris Dumez.
+
+        * wtf/text/StringView.h:
+        (WTF::StringView::toUInt64Strict const):
+        * wtf/text/WTFString.h:
+
 2017-12-01  Brian Burg  <[email protected]>
 
         Web Inspector: move Inspector::Protocol::Array<T> to JSON namespace

Modified: trunk/Source/WTF/wtf/text/StringView.h (225426 => 225427)


--- trunk/Source/WTF/wtf/text/StringView.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WTF/wtf/text/StringView.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -29,6 +29,7 @@
 #include <limits.h>
 #include <unicode/utypes.h>
 #include <wtf/Forward.h>
+#include <wtf/Optional.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/Vector.h>
 #include <wtf/text/CString.h>
@@ -146,6 +147,7 @@
     int toInt() const;
     int toInt(bool& isValid) const;
     int toIntStrict(bool& isValid) const;
+    std::optional<uint64_t> toUInt64Strict() const;
     float toFloat(bool& isValid) const;
 
     static void invalidate(const StringImpl&);
@@ -523,6 +525,13 @@
     return charactersToIntStrict(characters16(), m_length, &isValid);
 }
 
+inline std::optional<uint64_t> StringView::toUInt64Strict() const
+{
+    bool isValid;
+    uint64_t result = is8Bit() ? charactersToUInt64Strict(characters8(), m_length, &isValid) : charactersToUInt64Strict(characters16(), m_length, &isValid);
+    return isValid ? std::make_optional(result) : std::nullopt;
+}
+
 inline String StringView::toStringWithoutCopying() const
 {
     if (is8Bit())

Modified: trunk/Source/WTF/wtf/text/WTFString.h (225426 => 225427)


--- trunk/Source/WTF/wtf/text/WTFString.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WTF/wtf/text/WTFString.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -46,8 +46,8 @@
 WTF_EXPORT_STRING_API unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = nullptr, int base = 10);
 int64_t charactersToInt64Strict(const LChar*, size_t, bool* ok = nullptr, int base = 10);
 int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = nullptr, int base = 10);
-uint64_t charactersToUInt64Strict(const LChar*, size_t, bool* ok = nullptr, int base = 10);
-uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = nullptr, int base = 10);
+WTF_EXPORT_STRING_API uint64_t charactersToUInt64Strict(const LChar*, size_t, bool* ok = nullptr, int base = 10);
+WTF_EXPORT_STRING_API uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = nullptr, int base = 10);
 intptr_t charactersToIntPtrStrict(const LChar*, size_t, bool* ok = nullptr, int base = 10);
 intptr_t charactersToIntPtrStrict(const UChar*, size_t, bool* ok = nullptr, int base = 10);
 

Modified: trunk/Source/WebCore/ChangeLog (225426 => 225427)


--- trunk/Source/WebCore/ChangeLog	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/ChangeLog	2017-12-02 00:00:40 UTC (rev 225427)
@@ -1,3 +1,44 @@
+2017-12-01  Youenn Fablet  <[email protected]>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-get
+        https://bugs.webkit.org/show_bug.cgi?id=180167
+
+        Reviewed by Chris Dumez.
+
+        Test: http/tests/workers/service/serviceworkerclients-get.https.html
+
+        Implement clients get by having service worker clients do the following:
+        - Go to main thread to query the SWClientConnection for getting the client.
+        - SWClientConnection requests it through IPC to StorageProcess SWServer.
+        - SWServer looks at its client map and returns client data based on the given identifier.
+        - SWClientConnection sends it back to the right clients for resolving the promise.
+
+        Identifier is parsed at service worker process level.
+
+        Made ServiceWorkerClients no longer an ActiveDOMObject since it is owned by ServiceWorkerGlobalScope
+        and is only exposed in service workers.
+
+        * workers/service/ServiceWorkerClientIdentifier.h:
+        (WebCore::ServiceWorkerClientIdentifier::fromString):
+        * workers/service/ServiceWorkerClients.cpp:
+        (WebCore::ServiceWorkerClients::ServiceWorkerClients):
+        (WebCore::ServiceWorkerClients::get):
+        * workers/service/ServiceWorkerClients.h:
+        (WebCore::ServiceWorkerClients::create):
+        * workers/service/context/SWContextManager.cpp:
+        (WebCore::SWContextManager::postTaskToServiceWorker):
+        * workers/service/context/SWContextManager.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::getClientFromId):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerToContextConnection.cpp:
+        (WebCore::SWServerToContextConnection::findClientByIdentifier):
+        * workers/service/server/SWServerToContextConnection.h:
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::origin const):
+        (WebCore::SWServerWorker::findClientByIdentifier):
+        * workers/service/server/SWServerWorker.h:
+
 2017-12-01  Brian Burg  <[email protected]>
 
         Web Inspector: move Inspector::Protocol::Array<T> to JSON namespace

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClientIdentifier.h (225426 => 225427)


--- trunk/Source/WebCore/workers/service/ServiceWorkerClientIdentifier.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClientIdentifier.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -40,6 +40,7 @@
     unsigned hash() const;
 
     String toString() const { return String::number(serverConnectionIdentifier.toUInt64()) + "-" +  String::number(contextIdentifier.toUInt64()); }
+    static std::optional<ServiceWorkerClientIdentifier> fromString(StringView);
 
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static std::optional<ServiceWorkerClientIdentifier> decode(Decoder&);
@@ -50,6 +51,23 @@
     return a.serverConnectionIdentifier == b.serverConnectionIdentifier &&  a.contextIdentifier == b.contextIdentifier;
 }
 
+inline std::optional<ServiceWorkerClientIdentifier> ServiceWorkerClientIdentifier::fromString(StringView string)
+{
+    ServiceWorkerClientIdentifier clientIdentifier;
+
+    unsigned counter = 0;
+    for (auto item : string.split('-')) {
+        auto identifier = item.toUInt64Strict();
+        if (!identifier || !*identifier)
+            return std::nullopt;
+        if (!counter++)
+            clientIdentifier.serverConnectionIdentifier = makeObjectIdentifier<SWServerConnectionIdentifierType>(identifier.value());
+        else if (counter == 2)
+            clientIdentifier.contextIdentifier = makeObjectIdentifier<DocumentIdentifierType>(identifier.value());
+    }
+    return (counter == 2) ? std::make_optional(WTFMove(clientIdentifier)) : std::nullopt;
+}
+
 template<class Encoder>
 void ServiceWorkerClientIdentifier::encode(Encoder& encoder) const
 {

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClients.cpp (225426 => 225427)


--- trunk/Source/WebCore/workers/service/ServiceWorkerClients.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClients.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -29,29 +29,49 @@
 #include "ServiceWorkerClients.h"
 
 #include "JSDOMPromiseDeferred.h"
+#include "JSServiceWorkerWindowClient.h"
+#include "ServiceWorkerGlobalScope.h"
 
 namespace WebCore {
 
-ServiceWorkerClients::ServiceWorkerClients(ScriptExecutionContext& context)
-    : ActiveDOMObject(&context)
+static inline void didFinishGetRequest(ServiceWorkerGlobalScope& scope, DeferredPromise& promise, ServiceWorkerClientIdentifier identifier, ExceptionOr<std::optional<ServiceWorkerClientData>>&& clientData)
 {
-    suspendIfNeeded();
-}
+    if (clientData.hasException()) {
+        promise.reject(clientData.releaseException());
+        return;
+    }
+    auto data = ""
+    if (!data) {
+        promise.resolve();
+        return;
+    }
 
-const char* ServiceWorkerClients::activeDOMObjectName() const
-{
-    return "ServiceWorkerClients";
+    promise.resolve<IDLInterface<ServiceWorkerClient>>(ServiceWorkerClient::getOrCreate(scope, identifier, WTFMove(data.value())));
 }
 
-bool ServiceWorkerClients::canSuspendForDocumentSuspension() const
+void ServiceWorkerClients::get(ScriptExecutionContext& context, const String& id, Ref<DeferredPromise>&& promise)
 {
-    return !hasPendingActivity();
-}
+    auto identifier = ServiceWorkerClientIdentifier::fromString(id);
+    if (!identifier) {
+        promise->resolve();
+        return;
+    }
+    auto clientIdentifier = identifier.value();
 
-void ServiceWorkerClients::get(const String& id, Ref<DeferredPromise>&& promise)
-{
-    UNUSED_PARAM(id);
-    promise->reject(Exception { NotSupportedError, ASCIILiteral("clients.get() is not yet supported") });
+    auto serviceWorkerIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
+
+    auto promisePointer = promise.ptr();
+    m_pendingPromises.add(promisePointer, WTFMove(promise));
+
+    callOnMainThread([promisePointer, serviceWorkerIdentifier, clientIdentifier] () {
+        auto connection = SWContextManager::singleton().connection();
+        connection->findClientByIdentifier(serviceWorkerIdentifier, clientIdentifier, [promisePointer, serviceWorkerIdentifier, clientIdentifier] (auto&& clientData) {
+            SWContextManager::singleton().postTaskToServiceWorker(serviceWorkerIdentifier, [promisePointer, clientIdentifier, data = "" (auto& context) mutable {
+                if (auto promise = context.clients().m_pendingPromises.take(promisePointer))
+                    didFinishGetRequest(context, *promise, clientIdentifier, WTFMove(data));
+            });
+        });
+    });
 }
 
 void ServiceWorkerClients::matchAll(const ClientQueryOptions&, Ref<DeferredPromise>&& promise)

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClients.h (225426 => 225427)


--- trunk/Source/WebCore/workers/service/ServiceWorkerClients.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClients.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -27,8 +27,8 @@
 
 #if ENABLE(SERVICE_WORKER)
 
-#include "ActiveDOMObject.h"
 #include "ServiceWorkerClientType.h"
+#include "ServiceWorkerIdentifier.h"
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
 
@@ -35,12 +35,15 @@
 namespace WebCore {
 
 class DeferredPromise;
+class ScriptExecutionContext;
+struct ServiceWorkerClientData;
+struct ServiceWorkerClientIdentifier;
 
-class ServiceWorkerClients : public RefCounted<ServiceWorkerClients>, public ActiveDOMObject {
+class ServiceWorkerClients : public RefCounted<ServiceWorkerClients> {
 public:
-    static Ref<ServiceWorkerClients> create(ScriptExecutionContext& context)
+    static Ref<ServiceWorkerClients> create()
     {
-        return adoptRef(*new ServiceWorkerClients(context));
+        return adoptRef(*new ServiceWorkerClients);
     }
 
     struct ClientQueryOptions {
@@ -48,17 +51,15 @@
         ServiceWorkerClientType type { ServiceWorkerClientType::Window };
     };
 
-    void get(const String& id, Ref<DeferredPromise>&&);
+    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>&&);
 
 private:
-    explicit ServiceWorkerClients(ScriptExecutionContext&);
+    ServiceWorkerClients() = default;
 
-    // ActiveDOMObject.
-    const char* activeDOMObjectName() const final;
-    bool canSuspendForDocumentSuspension() const final;
+    HashMap<DeferredPromise*, Ref<DeferredPromise>> m_pendingPromises;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClients.idl (225426 => 225427)


--- trunk/Source/WebCore/workers/service/ServiceWorkerClients.idl	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClients.idl	2017-12-02 00:00:40 UTC (rev 225427)
@@ -28,10 +28,11 @@
     EnabledAtRuntime=ServiceWorker,
     Exposed=ServiceWorker,
     GenerateIsReachable=Impl,
+    ImplementationLacksVTable,
     InterfaceName=Clients,
 ] interface ServiceWorkerClients {
     // The objects returned will be new instances every time
-    [NewObject] Promise<any> get(DOMString id);
+    [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();

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp (225426 => 225427)


--- trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -42,7 +42,7 @@
     : WorkerGlobalScope(url, identifier, userAgent, isOnline, thread, shouldBypassMainWorldContentSecurityPolicy, WTFMove(topOrigin), timeOrigin, connectionProxy, socketProvider, sessionID)
     , m_contextData(crossThreadCopy(data))
     , m_registration(ServiceWorkerRegistration::getOrCreate(*this, navigator().serviceWorker(), WTFMove(m_contextData.registration)))
-    , m_clients(ServiceWorkerClients::create(*this))
+    , m_clients(ServiceWorkerClients::create())
 {
 }
 

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


--- trunk/Source/WebCore/workers/service/context/SWContextManager.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 #include "SWContextManager.h"
 #include "ServiceWorkerClientIdentifier.h"
+#include "ServiceWorkerGlobalScope.h"
 
 namespace WebCore {
 
@@ -124,6 +125,15 @@
         apply(*workerThread);
 }
 
+void SWContextManager::postTaskToServiceWorker(ServiceWorkerIdentifier identifier, WTF::Function<void(ServiceWorkerGlobalScope&)>&& task)
+{
+    if (auto* serviceWorker = m_workerMap.get(identifier)) {
+        serviceWorker->thread().runLoop().postTask([task = WTFMove(task)] (auto& context) {
+            task(downcast<ServiceWorkerGlobalScope>(context));
+        });
+    }
+}
+
 } // namespace WebCore
 
 #endif

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


--- trunk/Source/WebCore/workers/service/context/SWContextManager.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -30,6 +30,7 @@
 #include "ExceptionOr.h"
 #include "ServiceWorkerIdentifier.h"
 #include "ServiceWorkerThreadProxy.h"
+#include <wtf/CompletionHandler.h>
 #include <wtf/HashMap.h>
 
 namespace WebCore {
@@ -36,6 +37,7 @@
 
 class SerializedScriptValue;
 struct ServiceWorkerClientIdentifier;
+class ServiceWorkerGlobalScope;
 
 class SWContextManager {
 public:
@@ -51,6 +53,9 @@
         virtual void didFinishActivation(ServiceWorkerIdentifier) = 0;
         virtual void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool) = 0;
         virtual void workerTerminated(ServiceWorkerIdentifier) = 0;
+
+        using FindClientByIdentifierCallback = WTF::CompletionHandler<void(ExceptionOr<std::optional<ServiceWorkerClientData>>&&)>;
+        virtual void findClientByIdentifier(ServiceWorkerIdentifier, ServiceWorkerClientIdentifier, FindClientByIdentifierCallback&&) = 0;
     };
 
     WEBCORE_EXPORT void setConnection(std::unique_ptr<Connection>&&);
@@ -65,6 +70,8 @@
 
     void forEachServiceWorkerThread(const WTF::Function<void(ServiceWorkerThreadProxy&)>&);
 
+    WEBCORE_EXPORT void postTaskToServiceWorker(ServiceWorkerIdentifier, WTF::Function<void(ServiceWorkerGlobalScope&)>&&);
+
 private:
     SWContextManager() = default;
 

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (225426 => 225427)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -312,6 +312,20 @@
         SWServerJobQueue::didFinishActivation(*registration, worker.identifier());
 }
 
+std::optional<ServiceWorkerClientData> SWServer::findClientByIdentifier(const ClientOrigin& origin, ServiceWorkerClientIdentifier clientIdentifier)
+{
+    auto iterator = m_clients.find(origin);
+    if (iterator == m_clients.end())
+        return std::nullopt;
+
+    auto& clients = iterator->value;
+    auto position = clients.findMatching([&] (const auto& client) {
+        return clientIdentifier == client.identifier;
+    });
+
+    return (position != notFound) ? std::make_optional(clients[position].data) : std::nullopt;
+}
+
 void SWServer::didResolveRegistrationPromise(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey)
 {
     ASSERT_UNUSED(connection, m_connections.contains(connection.identifier()));

Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (225426 => 225427)


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -138,6 +138,7 @@
     void didFinishInstall(const std::optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&, bool wasSuccessful);
     void didFinishActivation(SWServerWorker&);
     void workerContextTerminated(SWServerWorker&);
+    std::optional<ServiceWorkerClientData> findClientByIdentifier(const ClientOrigin&, ServiceWorkerClientIdentifier);
 
     WEBCORE_EXPORT void serverToContextConnectionCreated();
     

Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp (225426 => 225427)


--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -108,6 +108,12 @@
         worker->contextTerminated();
 }
 
+void SWServerToContextConnection::findClientByIdentifier(uint64_t requestIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ServiceWorkerClientIdentifier clientId)
+{
+    if (auto* worker = SWServerWorker::existingWorkerForIdentifier(serviceWorkerIdentifier))
+        globalServerToContextConnection()->findClientByIdentifierCompleted(requestIdentifier, worker->findClientByIdentifier(clientId), false);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h (225426 => 225427)


--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -34,6 +34,8 @@
 namespace WebCore {
 
 class SWServer;
+struct ServiceWorkerClientData;
+struct ServiceWorkerClientIdentifier;
 struct ServiceWorkerContextData;
 struct ServiceWorkerJobDataIdentifier;
 
@@ -49,6 +51,7 @@
     virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0;
     virtual void terminateWorker(ServiceWorkerIdentifier) = 0;
     virtual void syncTerminateWorker(ServiceWorkerIdentifier) = 0;
+    virtual void findClientByIdentifierCompleted(uint64_t requestIdentifier, const std::optional<ServiceWorkerClientData>&, bool hasSecurityError) = 0;
 
     // Messages back from the SW host process
     WEBCORE_EXPORT void scriptContextFailedToStart(const std::optional<ServiceWorkerJobDataIdentifier>&, ServiceWorkerIdentifier, const String& message);
@@ -57,6 +60,7 @@
     WEBCORE_EXPORT void didFinishActivation(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool hasPendingEvents);
     WEBCORE_EXPORT void workerTerminated(ServiceWorkerIdentifier);
+    WEBCORE_EXPORT void findClientByIdentifier(uint64_t clientIdRequestIdentifier, ServiceWorkerIdentifier, ServiceWorkerClientIdentifier);
 
     static SWServerToContextConnection* connectionForIdentifier(SWServerToContextConnectionIdentifier);
 

Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp (225426 => 225427)


--- trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -73,6 +73,14 @@
     m_server.terminateWorker(*this);
 }
 
+const ClientOrigin& SWServerWorker::origin() const
+{
+    if (!m_origin)
+        m_origin = ClientOrigin { m_registrationKey.topOrigin(), SecurityOriginData::fromSecurityOrigin(SecurityOrigin::create(m_data.scriptURL)) };
+
+    return *m_origin;
+}
+
 void SWServerWorker::scriptContextFailedToStart(const std::optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier, const String& message)
 {
     m_server.scriptContextFailedToStart(jobDataIdentifier, *this, message);
@@ -98,6 +106,11 @@
     m_server.workerContextTerminated(*this);
 }
 
+std::optional<ServiceWorkerClientData> SWServerWorker::findClientByIdentifier(ServiceWorkerClientIdentifier clientId)
+{
+    return m_server.findClientByIdentifier(origin(), clientId);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.h (225426 => 225427)


--- trunk/Source/WebCore/workers/service/server/SWServerWorker.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -36,11 +36,14 @@
 
 namespace WebCore {
 
+struct ClientOrigin;
 class SWServer;
 class SWServerRegistration;
-enum class WorkerType;
+struct ServiceWorkerClientData;
+struct ServiceWorkerClientIdentifier;
 struct ServiceWorkerContextData;
 struct ServiceWorkerJobDataIdentifier;
+enum class WorkerType;
 
 class SWServerWorker : public RefCounted<SWServerWorker> {
 public:
@@ -83,11 +86,13 @@
     void didFinishInstall(const std::optional<ServiceWorkerJobDataIdentifier>&, bool wasSuccessful);
     void didFinishActivation();
     void contextTerminated();
+    std::optional<ServiceWorkerClientData> findClientByIdentifier(ServiceWorkerClientIdentifier);
 
     WEBCORE_EXPORT static SWServerWorker* existingWorkerForIdentifier(ServiceWorkerIdentifier);
 
     const ServiceWorkerData& data() const { return m_data; }
     ServiceWorkerContextData contextData() const;
+    const ClientOrigin& origin() const;
 
 private:
     SWServerWorker(SWServer&, SWServerRegistration&, SWServerToContextConnectionIdentifier, const URL&, const String& script, WorkerType, ServiceWorkerIdentifier);
@@ -99,6 +104,7 @@
     String m_script;
     bool m_hasPendingEvents { false };
     State m_state { State::NotRunning };
+    mutable std::optional<ClientOrigin> m_origin;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (225426 => 225427)


--- trunk/Source/WebKit/ChangeLog	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebKit/ChangeLog	2017-12-02 00:00:40 UTC (rev 225427)
@@ -1,3 +1,22 @@
+2017-12-01  Youenn Fablet  <[email protected]>
+
+        Implement https://w3c.github.io/ServiceWorker/#clients-get
+        https://bugs.webkit.org/show_bug.cgi?id=180167
+
+        Reviewed by Chris Dumez.
+
+        Add IPC plumbery for clientFromId between ServiceWorker process and Storage process.
+
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::clientFromIdCompleted):
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::findClientByIdentifier):
+        (WebKit::WebSWContextManagerConnection::findClientByIdentifierCompleted):
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
 2017-12-01  Brian Burg  <[email protected]>
 
         Web Inspector: move Inspector::Protocol::Array<T> to JSON namespace

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp (225426 => 225427)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -81,6 +81,11 @@
     sendSync(Messages::WebSWContextManagerConnection::SyncTerminateWorker(serviceWorkerIdentifier), Messages::WebSWContextManagerConnection::SyncTerminateWorker::Reply());
 }
 
+void WebSWServerToContextConnection::findClientByIdentifierCompleted(uint64_t requestIdentifier, const std::optional<ServiceWorkerClientData>& data, bool hasSecurityError)
+{
+    send(Messages::WebSWContextManagerConnection::FindClientByIdentifierCompleted { requestIdentifier, data, hasSecurityError });
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h (225426 => 225427)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -60,6 +60,7 @@
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier) final;
     void terminateWorker(WebCore::ServiceWorkerIdentifier) final;
     void syncTerminateWorker(WebCore::ServiceWorkerIdentifier) final;
+    void findClientByIdentifierCompleted(uint64_t requestIdentifier, const std::optional<WebCore::ServiceWorkerClientData>&, bool hasSecurityError) final;
 
     Ref<IPC::Connection> m_ipcConnection;
     

Modified: trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in (225426 => 225427)


--- trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in	2017-12-02 00:00:40 UTC (rev 225427)
@@ -31,6 +31,7 @@
     DidFinishActivation(WebCore::ServiceWorkerIdentifier identifier);
     SetServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier identifier, bool hasPendingEvents);
     WorkerTerminated(WebCore::ServiceWorkerIdentifier identifier);
+    FindClientByIdentifier(uint64_t requestIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, struct WebCore::ServiceWorkerClientIdentifier clientIdentifier);
 }
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (225426 => 225427)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2017-12-02 00:00:40 UTC (rev 225427)
@@ -48,6 +48,7 @@
 #include <WebCore/PageConfiguration.h>
 #include <WebCore/RuntimeEnabledFeatures.h>
 #include <WebCore/SerializedScriptValue.h>
+#include <WebCore/ServiceWorkerClientData.h>
 #include <WebCore/ServiceWorkerClientIdentifier.h>
 #include <pal/SessionID.h>
 
@@ -201,6 +202,24 @@
     m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::WorkerTerminated(serviceWorkerIdentifier), 0);
 }
 
+void WebSWContextManagerConnection::findClientByIdentifier(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, ServiceWorkerClientIdentifier clientIdentifier, FindClientByIdentifierCallback&& callback)
+{
+    auto requestIdentifier = ++m_previousRequestIdentifier;
+    m_findClientByIdentifierRequests.add(requestIdentifier, WTFMove(callback));
+    m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::FindClientByIdentifier { requestIdentifier, serviceWorkerIdentifier, clientIdentifier }, 0);
+}
+
+void WebSWContextManagerConnection::findClientByIdentifierCompleted(uint64_t requestIdentifier, std::optional<ServiceWorkerClientData>&& clientData, bool hasSecurityError)
+{
+    if (auto callback = m_findClientByIdentifierRequests.take(requestIdentifier)) {
+        if (hasSecurityError) {
+            callback(Exception { SecurityError });
+            return;
+        }
+        callback(WTFMove(clientData));
+    }
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (225426 => 225427)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2017-12-02 00:00:40 UTC (rev 225427)
@@ -63,6 +63,7 @@
     void didFinishActivation(WebCore::ServiceWorkerIdentifier) final;
     void setServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier, bool) final;
     void workerTerminated(WebCore::ServiceWorkerIdentifier) final;
+    void findClientByIdentifier(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerClientIdentifier, FindClientByIdentifierCallback&&) final;
 
     // IPC messages.
     void serviceWorkerStartedWithMessage(std::optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
@@ -73,10 +74,14 @@
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier);
     void terminateWorker(WebCore::ServiceWorkerIdentifier);
     void syncTerminateWorker(WebCore::ServiceWorkerIdentifier, Ref<Messages::WebSWContextManagerConnection::SyncTerminateWorker::DelayedReply>&&);
+    void findClientByIdentifierCompleted(uint64_t requestIdentifier, std::optional<WebCore::ServiceWorkerClientData>&&, bool hasSecurityError);
 
     Ref<IPC::Connection> m_connectionToStorageProcess;
     uint64_t m_pageID { 0 };
     uint64_t m_previousServiceWorkerID { 0 };
+
+    HashMap<uint64_t, FindClientByIdentifierCallback> m_findClientByIdentifierRequests;
+    uint64_t m_previousRequestIdentifier { 0 };
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (225426 => 225427)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2017-12-01 23:52:01 UTC (rev 225426)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2017-12-02 00:00:40 UTC (rev 225427)
@@ -30,6 +30,7 @@
     FireActivateEvent(WebCore::ServiceWorkerIdentifier identifier)
     TerminateWorker(WebCore::ServiceWorkerIdentifier identifier)
     SyncTerminateWorker(WebCore::ServiceWorkerIdentifier identifier) -> () Delayed
+    FindClientByIdentifierCompleted(uint64_t clientIdRequestIdentifier, std::optional<WebCore::ServiceWorkerClientData> data, bool hasSecurityError)
 }
 
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to