SW: Implement "Update Registration State" algorithm (unused for now)
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Nov 2017 04:36:20 +0000 (04:36 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Nov 2017 04:36:20 +0000 (04:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179186

Reviewed by Chris Dumez.

Source/WebCore:

No new tests (No behavior change yet).

This algorithm is very simple, and this patch plumbs it through.
But it's not useful to start using this algorithm without "Update Worker State" also.
So to keep this patch small, it's unused for now. Will be used in the next patch.

* WebCore.xcodeproj/project.pbxproj:

* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):

* workers/service/ServiceWorkerRegistration.cpp:
(WebCore::ServiceWorkerRegistration::ServiceWorkerRegistration):
(WebCore::ServiceWorkerRegistration::~ServiceWorkerRegistration):
(WebCore::ServiceWorkerRegistration::updateStateFromServer):
* workers/service/ServiceWorkerRegistration.h:

* workers/service/ServiceWorkerTypes.h: Copied from Source/WebCore/workers/service/server/SWServerRegistration.cpp.

* workers/service/server/SWClientConnection.cpp:
(WebCore::SWClientConnection::addServiceWorkerRegistration):
(WebCore::SWClientConnection::removeServiceWorkerRegistration):
(WebCore::SWClientConnection::updateRegistrationState):
* workers/service/server/SWClientConnection.h:

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::addServiceWorkerRegistrationInServer):
(WebCore::SWServer::Connection::removeServiceWorkerRegistrationInServer):
(WebCore::SWServer::addClientServiceWorkerRegistration):
(WebCore::SWServer::removeClientServiceWorkerRegistration):
* workers/service/server/SWServer.h:
(WebCore::SWServer::getConnection):

* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::runRegisterJob):

* workers/service/server/SWServerRegistration.cpp:
(WebCore::SWServerRegistration::SWServerRegistration):
(WebCore::SWServerRegistration::updateRegistrationState):
(WebCore::SWServerRegistration::addClientServiceWorkerRegistration):
(WebCore::SWServerRegistration::removeClientServiceWorkerRegistration):
* workers/service/server/SWServerRegistration.h:

Source/WebKit:

* Scripts/webkit/messages.py:
(headers_for_type):

* Shared/WebCoreArgumentCoders.h:

* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::updateRegistrationStateInClient):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:

* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::addServiceWorkerRegistrationInServer):
(WebKit::WebSWClientConnection::removeServiceWorkerRegistrationInServer):
* WebProcess/Storage/WebSWClientConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

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

22 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerRegistration.cpp
Source/WebCore/workers/service/ServiceWorkerRegistration.h
Source/WebCore/workers/service/ServiceWorkerTypes.h [new file with mode: 0644]
Source/WebCore/workers/service/server/SWClientConnection.cpp
Source/WebCore/workers/service/server/SWClientConnection.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerJobQueue.cpp
Source/WebCore/workers/service/server/SWServerRegistration.cpp
Source/WebCore/workers/service/server/SWServerRegistration.h
Source/WebKit/ChangeLog
Source/WebKit/Scripts/webkit/messages.py
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in
Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h
Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in

index fb872b6..a323822 100644 (file)
@@ -1,3 +1,53 @@
+2017-11-02  Brady Eidson  <beidson@apple.com>
+
+        SW: Implement "Update Registration State" algorithm (unused for now)
+        https://bugs.webkit.org/show_bug.cgi?id=179186
+
+        Reviewed by Chris Dumez.
+
+        No new tests (No behavior change yet).
+
+        This algorithm is very simple, and this patch plumbs it through.
+        But it's not useful to start using this algorithm without "Update Worker State" also.
+        So to keep this patch small, it's unused for now. Will be used in the next patch.
+
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
+
+        * workers/service/ServiceWorkerRegistration.cpp:
+        (WebCore::ServiceWorkerRegistration::ServiceWorkerRegistration):
+        (WebCore::ServiceWorkerRegistration::~ServiceWorkerRegistration):
+        (WebCore::ServiceWorkerRegistration::updateStateFromServer):
+        * workers/service/ServiceWorkerRegistration.h:
+
+        * workers/service/ServiceWorkerTypes.h: Copied from Source/WebCore/workers/service/server/SWServerRegistration.cpp.
+
+        * workers/service/server/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::addServiceWorkerRegistration):
+        (WebCore::SWClientConnection::removeServiceWorkerRegistration):
+        (WebCore::SWClientConnection::updateRegistrationState):
+        * workers/service/server/SWClientConnection.h:
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::addServiceWorkerRegistrationInServer):
+        (WebCore::SWServer::Connection::removeServiceWorkerRegistrationInServer):
+        (WebCore::SWServer::addClientServiceWorkerRegistration):
+        (WebCore::SWServer::removeClientServiceWorkerRegistration):
+        * workers/service/server/SWServer.h:
+        (WebCore::SWServer::getConnection):
+
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::runRegisterJob):
+
+        * workers/service/server/SWServerRegistration.cpp:
+        (WebCore::SWServerRegistration::SWServerRegistration):
+        (WebCore::SWServerRegistration::updateRegistrationState):
+        (WebCore::SWServerRegistration::addClientServiceWorkerRegistration):
+        (WebCore::SWServerRegistration::removeClientServiceWorkerRegistration):
+        * workers/service/server/SWServerRegistration.h:
+
 2017-11-01  Ryosuke Niwa  <rniwa@webkit.org>
 
         Assert that updateStyle and updateLayout are only called when it's safe to dispatch events
index 91777b5..b85632e 100644 (file)
                515BE1951D54F5FB00DD7C68 /* PlatformGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE18E1D54F5F600DD7C68 /* PlatformGamepad.h */; settings = {ATTRIBUTES = (Private, ); }; };
                515BE19C1D54F6C100DD7C68 /* HIDGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE1981D54F6BD00DD7C68 /* HIDGamepad.h */; settings = {ATTRIBUTES = (Private, ); }; };
                515BE19E1D54F6C100DD7C68 /* HIDGamepadProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE19A1D54F6BD00DD7C68 /* HIDGamepadProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               515E37F61FAA940200D7F22A /* ServiceWorkerTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 515E37F41FAA938800D7F22A /* ServiceWorkerTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                515F79541CFCA3D500CCED93 /* WebCoreCrossThreadCopier.h in Headers */ = {isa = PBXBuildFile; fileRef = 515F79521CFCA3C700CCED93 /* WebCoreCrossThreadCopier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5160712F1BD8307800DBC4F2 /* IDBObjectStoreInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160712D1BD8307200DBC4F2 /* IDBObjectStoreInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                516071321BD8308B00DBC4F2 /* TransactionOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5160712B1BD8305300DBC4F2 /* TransactionOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                515BE1981D54F6BD00DD7C68 /* HIDGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDGamepad.h; sourceTree = "<group>"; };
                515BE1991D54F6BD00DD7C68 /* HIDGamepadProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HIDGamepadProvider.cpp; sourceTree = "<group>"; };
                515BE19A1D54F6BD00DD7C68 /* HIDGamepadProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDGamepadProvider.h; sourceTree = "<group>"; };
+               515E37F41FAA938800D7F22A /* ServiceWorkerTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerTypes.h; sourceTree = "<group>"; };
                515F79511CFCA3C700CCED93 /* WebCoreCrossThreadCopier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreCrossThreadCopier.cpp; sourceTree = "<group>"; };
                515F79521CFCA3C700CCED93 /* WebCoreCrossThreadCopier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreCrossThreadCopier.h; sourceTree = "<group>"; };
                5160300A0CC4251200C8AC25 /* FileSystemPOSIX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystemPOSIX.cpp; sourceTree = "<group>"; };
                                517A53261F4B90B200DCDC0A /* ServiceWorkerRegistrationKey.h */,
                                51F645A01F4BF51600B54DED /* ServiceWorkerRegistrationOptions.cpp */,
                                51F1754A1F3EBC0C00C74950 /* ServiceWorkerRegistrationOptions.h */,
+                               515E37F41FAA938800D7F22A /* ServiceWorkerTypes.h */,
                                51F175471F3EBC0C00C74950 /* ServiceWorkerUpdateViaCache.h */,
                                51F175461F3EBC0C00C74950 /* ServiceWorkerUpdateViaCache.idl */,
                                46EF14251F97B7BA00C2A524 /* ServiceWorkerWindowClient.cpp */,
                                51F175691F3EBC8300C74950 /* ServiceWorkerRegistrationOptions.h in Headers */,
                                51BCCE301F8F179E006BA0ED /* ServiceWorkerThread.h in Headers */,
                                4112B5431F9F9CA000E67875 /* ServiceWorkerThreadProxy.h in Headers */,
+                               515E37F61FAA940200D7F22A /* ServiceWorkerTypes.h in Headers */,
                                51F1756C1F3EBC8300C74950 /* ServiceWorkerUpdateViaCache.h in Headers */,
                                46EF142A1F97B7D800C2A524 /* ServiceWorkerWindowClient.h in Headers */,
                                93309E10099E64920056E581 /* SetNodeAttributeCommand.h in Headers */,
index 4762918..646b345 100644 (file)
@@ -250,7 +250,10 @@ void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job,
     }
 
     activeServiceWorker->setState(ServiceWorker::State::Installing);
-    auto registration = ServiceWorkerRegistration::create(*context, WTFMove(data), *activeServiceWorker);
+    
+    ASSERT(m_swConnection);
+    auto registration = ServiceWorkerRegistration::create(*context, *m_swConnection, WTFMove(data), *activeServiceWorker);
+
     job.promise().resolve<IDLInterface<ServiceWorkerRegistration>>(registration.get());
 
     // Use a microtask because we need to make sure this is executed after the promise above is resolved.
index 281db8f..ab1a9c2 100644 (file)
 #include "Document.h"
 #include "ServiceWorker.h"
 #include "ServiceWorkerContainer.h"
+#include "ServiceWorkerTypes.h"
 #include "WorkerGlobalScope.h"
 
 namespace WebCore {
 
-ServiceWorkerRegistration::ServiceWorkerRegistration(ScriptExecutionContext& context, ServiceWorkerRegistrationData&& registrationData, Ref<ServiceWorker>&& serviceWorker)
+ServiceWorkerRegistration::ServiceWorkerRegistration(ScriptExecutionContext& context, SWClientConnection& connection, ServiceWorkerRegistrationData&& registrationData, Ref<ServiceWorker>&& serviceWorker)
     : ActiveDOMObject(&context)
     , m_registrationData(WTFMove(registrationData))
     , m_serviceWorker(WTFMove(serviceWorker))
+    , m_connection(connection)
 {
     suspendIfNeeded();
+
+    m_connection->addServiceWorkerRegistration(*this);
 }
 
 ServiceWorkerRegistration::~ServiceWorkerRegistration()
 {
+    m_connection->removeServiceWorkerRegistration(*this);
 }
 
 ServiceWorker* ServiceWorkerRegistration::installing()
@@ -101,6 +106,13 @@ void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise)
     container->removeRegistration(m_registrationData.scopeURL, WTFMove(promise));
 }
 
+void ServiceWorkerRegistration::updateStateFromServer(ServiceWorkerRegistrationState state, const String& workerID)
+{
+    // FIXME: Implement here along with "Update Worker State" algorithm
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(workerID);
+}
+
 EventTargetInterface ServiceWorkerRegistration::eventTargetInterface() const
 {
     return ServiceWorkerRegistrationEventTargetInterfaceType;
index 68ab02d..0e5ba7d 100644 (file)
 #include "ActiveDOMObject.h"
 #include "EventTarget.h"
 #include "JSDOMPromiseDeferred.h"
+#include "SWClientConnection.h"
 #include "ServiceWorkerRegistrationData.h"
+#include <wtf/Identified.h>
 
 namespace WebCore {
 
 class ScriptExecutionContext;
 class ServiceWorker;
 
-class ServiceWorkerRegistration final : public RefCounted<ServiceWorkerRegistration>, public EventTargetWithInlineData, public ActiveDOMObject {
+class ServiceWorkerRegistration final : public RefCounted<ServiceWorkerRegistration>, public EventTargetWithInlineData, public ActiveDOMObject, public ThreadSafeIdentified<ServiceWorkerRegistration> {
 public:
-    static Ref<ServiceWorkerRegistration> create(ScriptExecutionContext& context, ServiceWorkerRegistrationData&& data, Ref<ServiceWorker>&& serviceWorker)
+    template <typename... Args> static Ref<ServiceWorkerRegistration> create(Args&&... args)
     {
-        return adoptRef(*new ServiceWorkerRegistration(context, WTFMove(data), WTFMove(serviceWorker)));
+        return adoptRef(*new ServiceWorkerRegistration(std::forward<Args>(args)...));
     }
 
     ~ServiceWorkerRegistration();
@@ -58,9 +60,13 @@ public:
 
     using RefCounted::ref;
     using RefCounted::deref;
+    
+    const ServiceWorkerRegistrationData& data() const { return m_registrationData; }
+
+    void updateStateFromServer(ServiceWorkerRegistrationState, const String& workerID);
 
 private:
-    ServiceWorkerRegistration(ScriptExecutionContext&, ServiceWorkerRegistrationData&&, Ref<ServiceWorker>&&);
+    ServiceWorkerRegistration(ScriptExecutionContext&, SWClientConnection&, ServiceWorkerRegistrationData&&, Ref<ServiceWorker>&&);
 
     EventTargetInterface eventTargetInterface() const final;
     ScriptExecutionContext* scriptExecutionContext() const final;
@@ -72,6 +78,7 @@ private:
 
     ServiceWorkerRegistrationData m_registrationData;
     Ref<ServiceWorker> m_serviceWorker;
+    Ref<SWClientConnection> m_connection;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/workers/service/ServiceWorkerTypes.h b/Source/WebCore/workers/service/ServiceWorkerTypes.h
new file mode 100644 (file)
index 0000000..44d5f42
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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)
+
+namespace WebCore {
+
+enum class ServiceWorkerRegistrationState {
+    Installing = 0,
+    Waiting = 1,
+    Active = 2,
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SERVICE_WORKER)
index 1e8380c..97f051c 100644 (file)
@@ -34,6 +34,7 @@
 #include "ServiceWorkerContainer.h"
 #include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerJobData.h"
+#include "ServiceWorkerRegistration.h"
 
 namespace WebCore {
 
@@ -63,6 +64,32 @@ void SWClientConnection::failedFetchingScript(ServiceWorkerJob& job, const Resou
     finishFetchingScriptInServer({ job.data().identifier(), job.data().connectionIdentifier(), job.data().registrationKey(), { }, error });
 }
 
+void SWClientConnection::addServiceWorkerRegistration(ServiceWorkerRegistration& registration)
+{
+    auto result = m_registrations.ensure(registration.data().key, [] {
+        return std::make_unique<HashSet<ServiceWorkerRegistration*>>();
+    });
+
+    ASSERT(!result.iterator->value->contains(&registration));
+    result.iterator->value->add(&registration);
+    
+    addServiceWorkerRegistrationInServer(registration.data().key, registration.identifier());
+}
+
+void SWClientConnection::removeServiceWorkerRegistration(ServiceWorkerRegistration& registration)
+{
+    auto iterator = m_registrations.find(registration.data().key);
+
+    ASSERT(iterator != m_registrations.end());
+    ASSERT(iterator->value && iterator->value->contains(&registration));
+    iterator->value->remove(&registration);
+
+    if (iterator->value->isEmpty())
+        m_registrations.remove(iterator);
+
+    removeServiceWorkerRegistrationInServer(registration.data().key, registration.identifier());
+}
+    
 void SWClientConnection::jobRejectedInServer(uint64_t jobIdentifier, const ExceptionData& exceptionData)
 {
     auto job = m_scheduledJobs.take(jobIdentifier);
@@ -137,6 +164,16 @@ void SWClientConnection::postMessageToServiceWorkerClient(uint64_t destinationSc
     container->dispatchEvent(messageEvent);
 }
 
+void SWClientConnection::updateRegistrationState(const ServiceWorkerRegistrationKey& key, ServiceWorkerRegistrationState state, const String& workerID)
+{
+    auto* registrations = m_registrations.get(key);
+    if (!registrations)
+        return;
+    
+    for (auto& registration : *registrations)
+        registration->updateStateFromServer(state, workerID);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index c61a61e..987c6b7 100644 (file)
@@ -36,36 +36,45 @@ namespace WebCore {
 class ResourceError;
 class SecurityOrigin;
 class SerializedScriptValue;
+class ServiceWorkerRegistration;
 class SharedBuffer;
+enum class ServiceWorkerRegistrationState;
 struct ExceptionData;
 struct ServiceWorkerFetchResult;
 struct ServiceWorkerRegistrationData;
 
 class SWClientConnection : public ThreadSafeRefCounted<SWClientConnection> {
 public:
-    WEBCORE_EXPORT SWClientConnection();
     WEBCORE_EXPORT virtual ~SWClientConnection();
 
     void scheduleJob(ServiceWorkerJob&);
     void finishedFetchingScript(ServiceWorkerJob&, const String&);
     void failedFetchingScript(ServiceWorkerJob&, const ResourceError&);
-    virtual void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<SerializedScriptValue>&&, ScriptExecutionContext& source) = 0;
+    void addServiceWorkerRegistration(ServiceWorkerRegistration&);
+    void removeServiceWorkerRegistration(ServiceWorkerRegistration&);
 
+    virtual void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<SerializedScriptValue>&&, ScriptExecutionContext& source) = 0;
     virtual uint64_t identifier() const = 0;
     virtual bool hasServiceWorkerRegisteredForOrigin(const SecurityOrigin&) const = 0;
 
 protected:
+    WEBCORE_EXPORT SWClientConnection();
+
     WEBCORE_EXPORT void jobRejectedInServer(uint64_t jobIdentifier, const ExceptionData&);
     WEBCORE_EXPORT void registrationJobResolvedInServer(uint64_t jobIdentifier, ServiceWorkerRegistrationData&&);
     WEBCORE_EXPORT void unregistrationJobResolvedInServer(uint64_t jobIdentifier, bool unregistrationResult);
     WEBCORE_EXPORT void startScriptFetchForServer(uint64_t jobIdentifier);
     WEBCORE_EXPORT void postMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, Ref<SerializedScriptValue>&& message, uint64_t sourceServiceWorkerIdentifier, const String& sourceOrigin);
+    WEBCORE_EXPORT void updateRegistrationState(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, const String& workerID);
 
 private:
     virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
     virtual void finishFetchingScriptInServer(const ServiceWorkerFetchResult&) = 0;
+    virtual void addServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) = 0;
+    virtual void removeServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) = 0;
 
     HashMap<uint64_t, RefPtr<ServiceWorkerJob>> m_scheduledJobs;
+    HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<HashSet<ServiceWorkerRegistration*>>> m_registrations;
 };
 
 } // namespace WebCore
index 9ac0f7f..1c0c35d 100644 (file)
@@ -99,6 +99,16 @@ void SWServer::Connection::finishFetchingScriptInServer(const ServiceWorkerFetch
     m_server.scriptFetchFinished(*this, result);
 }
 
+void SWServer::Connection::addServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey& key, uint64_t clientRegistrationIdentifier)
+{
+    m_server.addClientServiceWorkerRegistration(*this, key, clientRegistrationIdentifier);
+}
+
+void SWServer::Connection::removeServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey& key, uint64_t clientRegistrationIdentifier)
+{
+    m_server.removeClientServiceWorkerRegistration(*this, key, clientRegistrationIdentifier);
+}
+
 void SWServer::Connection::scriptContextFailedToStart(const ServiceWorkerRegistrationKey& registrationKey, const String& workerID, const String& message)
 {
     m_server.scriptContextFailedToStart(*this, registrationKey, workerID, message);
@@ -201,6 +211,28 @@ void SWServer::scriptContextStarted(Connection& connection, const ServiceWorkerR
         jobQueue->scriptContextStarted(connection, serviceWorkerIdentifier, workerID);
 }
 
+void SWServer::addClientServiceWorkerRegistration(Connection& connection, const ServiceWorkerRegistrationKey& key, uint64_t registrationIdentifier)
+{
+    auto* registration = m_registrations.get(key);
+    if (!registration) {
+        LOG_ERROR("Request to add client-side ServiceWorkerRegistration to non-existent server-side registration");
+        return;
+    }
+    
+    registration->addClientServiceWorkerRegistration(connection.identifier(), registrationIdentifier);
+}
+
+void SWServer::removeClientServiceWorkerRegistration(Connection& connection, const ServiceWorkerRegistrationKey& key, uint64_t registrationIdentifier)
+{
+    auto* registration = m_registrations.get(key);
+    if (!registration) {
+        LOG_ERROR("Request to remove client-side ServiceWorkerRegistration from non-existent server-side registration");
+        return;
+    }
+    
+    registration->removeClientServiceWorkerRegistration(connection.identifier(), registrationIdentifier);
+}
+
 Ref<SWServerWorker> SWServer::updateWorker(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, const URL& url, const String& script, WorkerType type)
 {
     String workerID = createCanonicalUUIDString();
index 3bd57d4..e8023c3 100644 (file)
@@ -43,6 +43,7 @@ namespace WebCore {
 class SWServerJobQueue;
 class SWServerRegistration;
 class SWServerWorker;
+enum class ServiceWorkerRegistrationState;
 struct ExceptionData;
 struct ServiceWorkerContextData;
 struct ServiceWorkerFetchResult;
@@ -57,6 +58,9 @@ public:
 
         WEBCORE_EXPORT void scriptContextFailedToStart(const ServiceWorkerRegistrationKey&, const String& workerID, const String& message);
         WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, uint64_t serviceWorkerIdentifier, const String& workerID);
+        
+        // Messages to the client WebProcess
+        virtual void updateRegistrationStateInClient(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, const String& serviceWorkerID) = 0;
 
     protected:
         WEBCORE_EXPORT Connection(SWServer&, uint64_t identifier);
@@ -64,6 +68,8 @@ public:
 
         WEBCORE_EXPORT void scheduleJobInServer(const ServiceWorkerJobData&);
         WEBCORE_EXPORT void finishFetchingScriptInServer(const ServiceWorkerFetchResult&);
+        WEBCORE_EXPORT void addServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t clientRegistrationIdentifier);
+        WEBCORE_EXPORT void removeServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t clientRegistrationIdentifier);
 
     private:
         // Messages to the client WebProcess
@@ -96,6 +102,8 @@ public:
 
     Ref<SWServerWorker> updateWorker(Connection&, const ServiceWorkerRegistrationKey&, const URL&, const String& script, WorkerType);
     
+    Connection* getConnection(uint64_t identifier) { return m_connections.get(identifier); }
+
 private:
     void registerConnection(Connection&);
     void unregisterConnection(Connection&);
@@ -107,6 +115,9 @@ private:
     void scriptContextFailedToStart(Connection&, const ServiceWorkerRegistrationKey&, const String& workerID, const String& message);
     void scriptContextStarted(Connection&, const ServiceWorkerRegistrationKey&, uint64_t serviceWorkerIdentifier, const String& workerID);
 
+    void addClientServiceWorkerRegistration(Connection&, const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier);
+    void removeClientServiceWorkerRegistration(Connection&, const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier);
+
     HashMap<uint64_t, Connection*> m_connections;
     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
     HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerJobQueue>> m_jobQueues;
index 690b042..17f081f 100644 (file)
@@ -148,7 +148,7 @@ void SWServerJobQueue::runRegisterJob(const ServiceWorkerJobData& job)
             return;
         }
     } else {
-        auto newRegistration = std::make_unique<SWServerRegistration>(m_registrationKey, job.registrationOptions.updateViaCache, job.scopeURL, job.scriptURL);
+        auto newRegistration = std::make_unique<SWServerRegistration>(m_server, m_registrationKey, job.registrationOptions.updateViaCache, job.scopeURL, job.scriptURL);
         m_server.addRegistration(WTFMove(newRegistration));
     }
 
index 5fdf85e..5e53b5e 100644 (file)
 
 #include "SWServer.h"
 #include "SWServerWorker.h"
+#include "ServiceWorkerTypes.h"
 #include "ServiceWorkerUpdateViaCache.h"
 
 namespace WebCore {
 
-SWServerRegistration::SWServerRegistration(const ServiceWorkerRegistrationKey& key, ServiceWorkerUpdateViaCache updateViaCache, const URL& scopeURL, const URL& scriptURL)
+SWServerRegistration::SWServerRegistration(SWServer& server, const ServiceWorkerRegistrationKey& key, ServiceWorkerUpdateViaCache updateViaCache, const URL& scopeURL, const URL& scriptURL)
     : m_registrationKey(key)
     , m_updateViaCache(updateViaCache)
     , m_scopeURL(scopeURL)
     , m_scriptURL(scriptURL)
+    , m_server(server)
 {
     m_scopeURL.removeFragmentIdentifier();
 }
@@ -57,11 +59,57 @@ SWServerWorker* SWServerRegistration::getNewestWorker()
     return m_activeWorker.get();
 }
 
+void SWServerRegistration::updateRegistrationState(ServiceWorkerRegistrationState state, SWServerWorker* worker)
+{
+    switch (state) {
+    case ServiceWorkerRegistrationState::Installing:
+        m_installingWorker = worker;
+        break;
+    case ServiceWorkerRegistrationState::Waiting:
+        m_waitingWorker = worker;
+        break;
+    case ServiceWorkerRegistrationState::Active:
+        m_activeWorker = worker;
+        break;
+    };
+
+    String workerID;
+    if (worker)
+        workerID = worker->workerID();
+
+    for (auto& connectionIdentifierWithClients : m_clientRegistrationsByConnection.keys()) {
+        if (auto* connection = m_server.getConnection(connectionIdentifierWithClients))
+            connection->updateRegistrationStateInClient(m_registrationKey, state, workerID);
+    }
+}
+
 ServiceWorkerRegistrationData SWServerRegistration::data() const
 {
     return { m_registrationKey, identifier(), m_activeServiceWorkerIdentifier, m_scopeURL, m_scriptURL, m_updateViaCache };
 }
 
+void SWServerRegistration::addClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier)
+{
+    auto result = m_clientRegistrationsByConnection.ensure(connectionIdentifier, [] {
+        return std::make_unique<HashSet<uint64_t>>();
+    });
+    
+    ASSERT(!result.iterator->value->contains(clientRegistrationIdentifier));
+    result.iterator->value->add(clientRegistrationIdentifier);
+}
+
+void SWServerRegistration::removeClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier)
+{
+    auto iterator = m_clientRegistrationsByConnection.find(connectionIdentifier);
+    if (iterator == m_clientRegistrationsByConnection.end() || !iterator->value)
+        return;
+    
+    ASSERT(iterator->value->contains(clientRegistrationIdentifier));
+    iterator->value->remove(clientRegistrationIdentifier);
+    if (iterator->value->isEmpty())
+        m_clientRegistrationsByConnection.remove(iterator);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 8e070b5..5b35df8 100644 (file)
 
 namespace WebCore {
 
+class SWServer;
 class SWServerWorker;
+enum class ServiceWorkerRegistrationState;
 struct ExceptionData;
 struct ServiceWorkerFetchResult;
 
 class SWServerRegistration : public ThreadSafeIdentified<SWServerRegistration> {
 public:
-    SWServerRegistration(const ServiceWorkerRegistrationKey&, ServiceWorkerUpdateViaCache, const URL& scopeURL, const URL& scriptURL);
+    SWServerRegistration(SWServer&, const ServiceWorkerRegistrationKey&, ServiceWorkerUpdateViaCache, const URL& scopeURL, const URL& scriptURL);
     ~SWServerRegistration();
 
     const ServiceWorkerRegistrationKey& key() const { return m_registrationKey; }
@@ -55,6 +57,11 @@ public:
 
     void setActiveServiceWorkerIdentifier(uint64_t identifier) { m_activeServiceWorkerIdentifier = identifier; }
 
+    void updateRegistrationState(ServiceWorkerRegistrationState, SWServerWorker*);
+
+    void addClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier);
+    void removeClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier);
+
 private:
     ServiceWorkerRegistrationKey m_registrationKey;
     ServiceWorkerUpdateViaCache m_updateViaCache;
@@ -62,13 +69,16 @@ private:
     URL m_scriptURL;
 
     bool m_uninstalling { false };
-    std::unique_ptr<SWServerWorker> m_installingWorker;
-    std::unique_ptr<SWServerWorker> m_waitingWorker;
-    std::unique_ptr<SWServerWorker> m_activeWorker;
+    RefPtr<SWServerWorker> m_installingWorker;
+    RefPtr<SWServerWorker> m_waitingWorker;
+    RefPtr<SWServerWorker> m_activeWorker;
 
     uint64_t m_activeServiceWorkerIdentifier { 0 };
 
     double m_lastUpdateTime { 0 };
+    
+    HashMap<uint64_t, std::unique_ptr<HashSet<uint64_t>>> m_clientRegistrationsByConnection;
+    SWServer& m_server;
 };
 
 } // namespace WebCore
index bf60944..12896b4 100644 (file)
@@ -1,3 +1,26 @@
+2017-11-02  Brady Eidson  <beidson@apple.com>
+
+        SW: Implement "Update Registration State" algorithm (unused for now)
+        https://bugs.webkit.org/show_bug.cgi?id=179186
+
+        Reviewed by Chris Dumez.
+
+        * Scripts/webkit/messages.py:
+        (headers_for_type):
+
+        * Shared/WebCoreArgumentCoders.h:
+
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::updateRegistrationStateInClient):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
+
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        (WebKit::WebSWClientConnection::addServiceWorkerRegistrationInServer):
+        (WebKit::WebSWClientConnection::removeServiceWorkerRegistrationInServer):
+        * WebProcess/Storage/WebSWClientConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+
 2017-11-02  Alex Christensen  <achristensen@webkit.org>
 
         Use CompletionHandlers for redirects
index ce64d6e..2804995 100644 (file)
@@ -370,7 +370,9 @@ def headers_for_type(type):
         'WebCore::PaymentAuthorizationResult': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
         'WebCore::PaymentMethodUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
         'WebCore::PluginInfo': ['<WebCore/PluginData.h>'],
+        'WebCore::PolicyAction': ['<WebCore/FrameLoaderTypes.h>'],
         'WebCore::RecentSearch': ['<WebCore/SearchPopupMenu.h>'],
+        'WebCore::ServiceWorkerRegistrationState': ['<WebCore/ServiceWorkerTypes.h>'],
         'WebCore::ShippingContactUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
         'WebCore::ShippingMethodUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
         'WebCore::ShouldSample': ['<WebCore/DiagnosticLoggingClient.h>'],
@@ -388,7 +390,6 @@ def headers_for_type(type):
         'WebKit::WebMouseEvent': ['"WebEvent.h"'],
         'WebKit::WebTouchEvent': ['"WebEvent.h"'],
         'WebKit::WebWheelEvent': ['"WebEvent.h"'],
-        'WebCore::PolicyAction': ['<WebCore/FrameLoaderTypes.h>'],
         'struct WebKit::WebUserScriptData': ['"WebUserContentControllerDataTypes.h"'],
         'struct WebKit::WebUserStyleSheetData': ['"WebUserContentControllerDataTypes.h"'],
         'struct WebKit::WebScriptMessageHandlerData': ['"WebUserContentControllerDataTypes.h"'],
index 308e92e..76d76e3 100644 (file)
@@ -39,6 +39,7 @@
 #include <WebCore/PaymentHeaders.h>
 #include <WebCore/RealtimeMediaSource.h>
 #include <WebCore/ScrollSnapOffsetsInfo.h>
+#include <WebCore/ServiceWorkerTypes.h>
 #include <WebCore/ServiceWorkerUpdateViaCache.h>
 #include <WebCore/StoredCredentialsPolicy.h>
 
@@ -805,6 +806,15 @@ template <> struct EnumTraits<WebCore::ServiceWorkerUpdateViaCache> {
         WebCore::ServiceWorkerUpdateViaCache::None
     >;
 };
+
+template <> struct EnumTraits<WebCore::ServiceWorkerRegistrationState> {
+    using values = EnumValues<
+        WebCore::ServiceWorkerRegistrationState,
+        WebCore::ServiceWorkerRegistrationState::Installing,
+        WebCore::ServiceWorkerRegistrationState::Waiting,
+        WebCore::ServiceWorkerRegistrationState::Active
+    >;
+};
 #endif
 
 } // namespace WTF
index f7bca3d..5184116 100644 (file)
@@ -96,6 +96,11 @@ void WebSWServerConnection::startScriptFetchInClient(uint64_t jobIdentifier)
     send(Messages::WebSWClientConnection::StartScriptFetchForServer(jobIdentifier));
 }
 
+void WebSWServerConnection::updateRegistrationStateInClient(const ServiceWorkerRegistrationKey& key, ServiceWorkerRegistrationState state, const String& workerID)
+{
+    send(Messages::WebSWClientConnection::UpdateRegistrationState(key, state, workerID));
+}
+
 void WebSWServerConnection::updateServiceWorkerContext(const ServiceWorkerContextData& data)
 {
     if (sendToContextProcess(Messages::WebSWContextManagerConnection::UpdateServiceWorker(identifier(), data)))
index 3102e16..5f393dc 100644 (file)
@@ -65,6 +65,7 @@ private:
     void resolveRegistrationJobInClient(uint64_t jobIdentifier, const WebCore::ServiceWorkerRegistrationData&) final;
     void resolveUnregistrationJobInClient(uint64_t jobIdentifier, const WebCore::ServiceWorkerRegistrationKey&, bool unregistrationResult) final;
     void startScriptFetchInClient(uint64_t jobIdentifier) final;
+    void updateRegistrationStateInClient(const WebCore::ServiceWorkerRegistrationKey&, WebCore::ServiceWorkerRegistrationState, const String& serviceWorkerID) final;
 
     void startFetch(uint64_t fetchIdentifier, uint64_t serviceWorkerIdentifier, const WebCore::ResourceRequest&, const WebCore::FetchOptions&);
 
index de515d9..e658bcf 100644 (file)
@@ -26,6 +26,8 @@ messages -> WebSWServerConnection {
     # When possible, these messages can be implemented directly by WebCore::SWClientConnection
     ScheduleJobInServer(struct WebCore::ServiceWorkerJobData jobData)
     FinishFetchingScriptInServer(struct WebCore::ServiceWorkerFetchResult result)
+    AddServiceWorkerRegistrationInServer(struct WebCore::ServiceWorkerRegistrationKey key, uint64_t registrationIdentifier)
+    RemoveServiceWorkerRegistrationInServer(struct WebCore::ServiceWorkerRegistrationKey key, uint64_t registrationIdentifier)
 
     StartFetch(uint64_t identifier, uint64_t serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options)
     PostMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, IPC::DataReference message, uint64_t sourceScriptExecutionContextIdentifier, String sourceOrigin)
index 7b8778a..4785060 100644 (file)
@@ -69,6 +69,16 @@ void WebSWClientConnection::finishFetchingScriptInServer(const ServiceWorkerFetc
     send(Messages::WebSWServerConnection::FinishFetchingScriptInServer(result));
 }
 
+void WebSWClientConnection::addServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey& key, uint64_t registrationIdentifier)
+{
+    send(Messages::WebSWServerConnection::AddServiceWorkerRegistrationInServer(key, registrationIdentifier));
+}
+
+void WebSWClientConnection::removeServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey& key, uint64_t registrationIdentifier)
+{
+    send(Messages::WebSWServerConnection::RemoveServiceWorkerRegistrationInServer(key, registrationIdentifier));
+}
+
 void WebSWClientConnection::postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<SerializedScriptValue>&& scriptValue, ScriptExecutionContext& source)
 {
     // FIXME: Add support for posting messages from workers.
index 27cdba2..57a7121 100644 (file)
@@ -56,6 +56,8 @@ public:
 
     void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;
     void finishFetchingScriptInServer(const WebCore::ServiceWorkerFetchResult&) final;
+    void addServiceWorkerRegistrationInServer(const WebCore::ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) final;
+    void removeServiceWorkerRegistrationInServer(const WebCore::ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) final;
     void postMessageToServiceWorkerGlobalScope(uint64_t destinationServiceWorkerIdentifier, Ref<WebCore::SerializedScriptValue>&&, WebCore::ScriptExecutionContext& source) final;
 
     void disconnectedFromWebProcess();
index 911cf10..d76c3ae 100644 (file)
@@ -28,6 +28,7 @@ messages -> WebSWClientConnection {
     RegistrationJobResolvedInServer(uint64_t identifier, struct WebCore::ServiceWorkerRegistrationData registration)
     UnregistrationJobResolvedInServer(uint64_t identifier, bool unregistrationResult)
     StartScriptFetchForServer(uint64_t jobIdentifier)
+    UpdateRegistrationState(struct WebCore::ServiceWorkerRegistrationKey key, enum WebCore::ServiceWorkerRegistrationState state, String workerID)
 
     SetSWOriginTableSharedMemory(WebKit::SharedMemory::Handle handle)
     PostMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, IPC::DataReference message, uint64_t sourceServiceWorkerIdentifier, String sourceOrigin)