Implement real post 'install' event steps of the Install algorithm (steps 14+)
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Nov 2017 23:45:29 +0000 (23:45 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Nov 2017 23:45:29 +0000 (23:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179401

Reviewed by Brady Eidson.

LayoutTests/imported/w3c:

Rebaseline a test that is now failing later (progression).

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

Source/WebCore:

Implement step 14+ of Install algorithm, as per:
- https://w3c.github.io/ServiceWorker/#installation-algorithm

* dom/Microtasks.h:
* workers/service/ServiceWorker.cpp:
(WebCore::ServiceWorker::ServiceWorker):
(WebCore::ServiceWorker::scheduleTaskToUpdateState):
* workers/service/ServiceWorker.h:
* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::scheduleTaskToUpdateRegistrationState):
(WebCore::ServiceWorkerContainer::jobFailedWithException):
(WebCore::ServiceWorkerContainer::scheduleTaskToFireUpdateFoundEvent):
(WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
(WebCore::ServiceWorkerContainer::jobResolvedWithUnregistrationResult):
* workers/service/ServiceWorkerContainer.h:
* workers/service/ServiceWorkerJob.cpp:
(WebCore::ServiceWorkerJob::resolvedWithRegistration):
* workers/service/ServiceWorkerJob.h:
* workers/service/ServiceWorkerJobClient.h:
* workers/service/ServiceWorkerRegistration.cpp:
(WebCore::ServiceWorkerRegistration::ServiceWorkerRegistration):
* workers/service/ServiceWorkerTypes.h:
* workers/service/server/SWClientConnection.cpp:
(WebCore::SWClientConnection::registrationJobResolvedInServer):
(WebCore::SWClientConnection::forEachContainer):
(WebCore::SWClientConnection::updateRegistrationState):
(WebCore::SWClientConnection::updateWorkerState):
(WebCore::SWClientConnection::fireUpdateFoundEvent):
* workers/service/server/SWClientConnection.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::didResolveRegistrationPromise):
(WebCore::SWServer::resolveRegistrationJob):
(WebCore::SWServer::didResolveRegistrationPromise):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::install):
(WebCore::SWServerJobQueue::didResolveRegistrationPromise):
(WebCore::SWServerJobQueue::didFinishInstall):
(WebCore::SWServerJobQueue::runRegisterJob):
* workers/service/server/SWServerJobQueue.h:
* workers/service/server/SWServerRegistration.cpp:
* workers/service/server/SWServerRegistration.h:
(WebCore::SWServerRegistration::installingWorker const):
(WebCore::SWServerRegistration::waitingWorker const):
(WebCore::SWServerRegistration::activeWorker const):
* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::terminate):
* workers/service/server/SWServerWorker.h:

Source/WebKit:

Implement step 14+ of Install algorithm, as per:
- https://w3c.github.io/ServiceWorker/#installation-algorithm

* Scripts/webkit/messages.py:
(headers_for_type):
* Shared/WebCoreArgumentCoders.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::resolveRegistrationJobInClient):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::didResolveRegistrationPromise):
* WebProcess/Storage/WebSWClientConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

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

32 files changed:
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/navigate-window.https-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/dom/Microtasks.h
Source/WebCore/workers/service/ServiceWorker.cpp
Source/WebCore/workers/service/ServiceWorker.h
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerContainer.h
Source/WebCore/workers/service/ServiceWorkerJob.cpp
Source/WebCore/workers/service/ServiceWorkerJob.h
Source/WebCore/workers/service/ServiceWorkerJobClient.h
Source/WebCore/workers/service/ServiceWorkerRegistration.cpp
Source/WebCore/workers/service/ServiceWorkerTypes.h
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/SWServerJobQueue.h
Source/WebCore/workers/service/server/SWServerRegistration.cpp
Source/WebCore/workers/service/server/SWServerRegistration.h
Source/WebCore/workers/service/server/SWServerWorker.cpp
Source/WebCore/workers/service/server/SWServerWorker.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 c802000..f201085 100644 (file)
@@ -1,3 +1,14 @@
+2017-11-09  Chris Dumez  <cdumez@apple.com>
+
+        Implement real post 'install' event steps of the Install algorithm (steps 14+)
+        https://bugs.webkit.org/show_bug.cgi?id=179401
+
+        Reviewed by Brady Eidson.
+
+        Rebaseline a test that is now failing later (progression).
+
+        * web-platform-tests/service-workers/service-worker/navigate-window.https-expected.txt:
+
 2017-11-08  Brady Eidson  <beidson@apple.com>
 
         Some SW Container and Registration tweaks.
index 391446a..a8165a7 100644 (file)
@@ -1,4 +1,4 @@
 
-FAIL Clients.matchAll() should not show an old window as controlled after it navigates. assert_unreached: unexpected rejection: null is not an object (evaluating 'sw.postMessage') Reached unreachable code
-FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: null is not an object (evaluating 'sw.postMessage') Reached unreachable code
+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
 
index abba85d..dcc7369 100644 (file)
@@ -1,3 +1,59 @@
+2017-11-09  Chris Dumez  <cdumez@apple.com>
+
+        Implement real post 'install' event steps of the Install algorithm (steps 14+)
+        https://bugs.webkit.org/show_bug.cgi?id=179401
+
+        Reviewed by Brady Eidson.
+
+        Implement step 14+ of Install algorithm, as per:
+        - https://w3c.github.io/ServiceWorker/#installation-algorithm
+
+        * dom/Microtasks.h:
+        * workers/service/ServiceWorker.cpp:
+        (WebCore::ServiceWorker::ServiceWorker):
+        (WebCore::ServiceWorker::scheduleTaskToUpdateState):
+        * workers/service/ServiceWorker.h:
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::scheduleTaskToUpdateRegistrationState):
+        (WebCore::ServiceWorkerContainer::jobFailedWithException):
+        (WebCore::ServiceWorkerContainer::scheduleTaskToFireUpdateFoundEvent):
+        (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
+        (WebCore::ServiceWorkerContainer::jobResolvedWithUnregistrationResult):
+        * workers/service/ServiceWorkerContainer.h:
+        * workers/service/ServiceWorkerJob.cpp:
+        (WebCore::ServiceWorkerJob::resolvedWithRegistration):
+        * workers/service/ServiceWorkerJob.h:
+        * workers/service/ServiceWorkerJobClient.h:
+        * workers/service/ServiceWorkerRegistration.cpp:
+        (WebCore::ServiceWorkerRegistration::ServiceWorkerRegistration):
+        * workers/service/ServiceWorkerTypes.h:
+        * workers/service/server/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::registrationJobResolvedInServer):
+        (WebCore::SWClientConnection::forEachContainer):
+        (WebCore::SWClientConnection::updateRegistrationState):
+        (WebCore::SWClientConnection::updateWorkerState):
+        (WebCore::SWClientConnection::fireUpdateFoundEvent):
+        * workers/service/server/SWClientConnection.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::didResolveRegistrationPromise):
+        (WebCore::SWServer::resolveRegistrationJob):
+        (WebCore::SWServer::didResolveRegistrationPromise):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::install):
+        (WebCore::SWServerJobQueue::didResolveRegistrationPromise):
+        (WebCore::SWServerJobQueue::didFinishInstall):
+        (WebCore::SWServerJobQueue::runRegisterJob):
+        * workers/service/server/SWServerJobQueue.h:
+        * workers/service/server/SWServerRegistration.cpp:
+        * workers/service/server/SWServerRegistration.h:
+        (WebCore::SWServerRegistration::installingWorker const):
+        (WebCore::SWServerRegistration::waitingWorker const):
+        (WebCore::SWServerRegistration::activeWorker const):
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::terminate):
+        * workers/service/server/SWServerWorker.h:
+
 2017-11-09  Doug Russell  <d_russell@apple.com>
 
         Bug 179068 - AX: search predicate returns containing group for plain text instead of text element
index 51ed51f..25ec8f8 100644 (file)
@@ -46,6 +46,24 @@ protected:
     void removeSelfFromQueue(MicrotaskQueue&);
 };
 
+class VoidMicrotask final : public Microtask {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit VoidMicrotask(Function<void()>&& function)
+        : m_function(WTFMove(function))
+    {
+    }
+
+private:
+    Result run() final
+    {
+        m_function();
+        return Result::Done;
+    }
+
+    Function<void()> m_function;
+};
+
 class MicrotaskQueue {
     friend NeverDestroyed<MicrotaskQueue>;
     friend class Microtask;
index 9f34151..96e5171 100644 (file)
@@ -53,10 +53,11 @@ HashMap<ServiceWorkerIdentifier, HashSet<ServiceWorker*>>& ServiceWorker::mutabl
     return allWorkersMap;
 }
 
-ServiceWorker::ServiceWorker(ScriptExecutionContext& context, ServiceWorkerIdentifier identifier, const URL& scriptURL)
+ServiceWorker::ServiceWorker(ScriptExecutionContext& context, ServiceWorkerIdentifier identifier, const URL& scriptURL, State state)
     : ContextDestructionObserver(&context)
     , m_identifier(identifier)
     , m_scriptURL(scriptURL)
+    , m_state(state)
 {
     auto result = mutableAllWorkers().ensure(identifier, [] {
         return HashSet<ServiceWorker*>();
@@ -75,15 +76,19 @@ ServiceWorker::~ServiceWorker()
         mutableAllWorkers().remove(iterator);
 }
 
-void ServiceWorker::updateWorkerState(State state, ShouldFireStateChangeEvent shouldFire)
+void ServiceWorker::scheduleTaskToUpdateState(State state)
 {
     // FIXME: Once we support service workers from workers, this might need to change.
     RELEASE_ASSERT(isMainThread());
 
-    m_state = state;
-    
-    if (shouldFire == FireStateChangeEvent)
+    auto* context = scriptExecutionContext();
+    if (!context)
+        return;
+
+    context->postTask([this, protectedThis = makeRef(*this), state](ScriptExecutionContext&) {
+        m_state = state;
         dispatchEvent(Event::create(eventNames().statechangeEvent, false, false));
+    });
 }
 
 ExceptionOr<void> ServiceWorker::postMessage(ScriptExecutionContext& context, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
index 06852af..6484145 100644 (file)
@@ -45,23 +45,19 @@ class Frame;
 
 class ServiceWorker final : public RefCounted<ServiceWorker>, public EventTargetWithInlineData, public ContextDestructionObserver {
 public:
-    static Ref<ServiceWorker> create(ScriptExecutionContext& context, ServiceWorkerIdentifier identifier, const URL& scriptURL)
+    using State = ServiceWorkerState;
+    static Ref<ServiceWorker> create(ScriptExecutionContext& context, ServiceWorkerIdentifier identifier, const URL& scriptURL, State state = State::Installing)
     {
-        return adoptRef(*new ServiceWorker(context, identifier, scriptURL));
+        return adoptRef(*new ServiceWorker(context, identifier, scriptURL, state));
     }
 
     virtual ~ServiceWorker();
 
     const URL& scriptURL() const { return m_scriptURL; }
 
-    using State = ServiceWorkerState;
     State state() const { return m_state; }
     
-    enum ShouldFireStateChangeEvent {
-        FireStateChangeEvent,
-        DoNotFireStateChangeEvent,
-    };
-    void updateWorkerState(State, ShouldFireStateChangeEvent = FireStateChangeEvent);
+    void scheduleTaskToUpdateState(State);
 
     ExceptionOr<void> postMessage(ScriptExecutionContext&, JSC::JSValue message, Vector<JSC::Strong<JSC::JSObject>>&&);
 
@@ -73,17 +69,17 @@ public:
     static const HashMap<ServiceWorkerIdentifier, HashSet<ServiceWorker*>>& allWorkers();
 
 private:
-    ServiceWorker(ScriptExecutionContext&, ServiceWorkerIdentifier, const URL& scriptURL);
+    ServiceWorker(ScriptExecutionContext&, ServiceWorkerIdentifier, const URL& scriptURL, State);
     static HashMap<ServiceWorkerIdentifier, HashSet<ServiceWorker*>>& mutableAllWorkers();
 
-    virtual EventTargetInterface eventTargetInterface() const;
-    virtual ScriptExecutionContext* scriptExecutionContext() const;
+    EventTargetInterface eventTargetInterface() const final;
+    ScriptExecutionContext* scriptExecutionContext() const final;
     void refEventTarget() final { ref(); }
     void derefEventTarget() final { deref(); }
 
     ServiceWorkerIdentifier m_identifier;
     URL m_scriptURL;
-    State m_state { State::Installing };
+    State m_state;
 };
 
 } // namespace WebCore
index 1c7d14f..08449b2 100644 (file)
@@ -241,10 +241,16 @@ void ServiceWorkerContainer::getRegistration(const String& clientURL, Ref<Deferr
     });
 }
 
-void ServiceWorkerContainer::updateRegistrationState(const ServiceWorkerRegistrationKey& key, ServiceWorkerRegistrationState state, const std::optional<ServiceWorkerIdentifier>& serviceWorkerIdentifier)
+void ServiceWorkerContainer::scheduleTaskToUpdateRegistrationState(const ServiceWorkerRegistrationKey& key, ServiceWorkerRegistrationState state, const std::optional<ServiceWorkerIdentifier>& serviceWorkerIdentifier)
 {
-    if (auto* registration = m_registrations.get(key))
-        registration->updateStateFromServer(state, serviceWorkerIdentifier);
+    auto* context = scriptExecutionContext();
+    if (!context)
+        return;
+
+    context->postTask([this, protectedThis = makeRef(*this), key, state, serviceWorkerIdentifier](ScriptExecutionContext&) {
+        if (auto* registration = m_registrations.get(key))
+            registration->updateStateFromServer(state, serviceWorkerIdentifier);
+    });
 }
 
 void ServiceWorkerContainer::getRegistrations(RegistrationsPromise&& promise)
@@ -259,81 +265,29 @@ void ServiceWorkerContainer::startMessages()
 
 void ServiceWorkerContainer::jobFailedWithException(ServiceWorkerJob& job, const Exception& exception)
 {
-    job.promise().reject(exception);
+    if (auto* context = scriptExecutionContext()) {
+        context->postTask([job = makeRef(job), exception](ScriptExecutionContext&) {
+            job->promise().reject(exception);
+        });
+    }
     jobDidFinish(job);
 }
 
-void ServiceWorkerContainer::fireUpdateFoundEvent(const ServiceWorkerRegistrationKey& key)
+void ServiceWorkerContainer::scheduleTaskToFireUpdateFoundEvent(const ServiceWorkerRegistrationKey& key)
 {
     if (isStopped())
         return;
 
-    auto* registration = m_registrations.get(key);
-    if (!registration)
-        return;
-
-    scriptExecutionContext()->postTask([container = makeRef(*this), registration = makeRef(*registration)] (ScriptExecutionContext&) {
-        if (container->isStopped())
+    scriptExecutionContext()->postTask([this, protectedThis = makeRef(*this), key](ScriptExecutionContext&) {
+        if (isStopped())
             return;
-        registration->dispatchEvent(Event::create(eventNames().updatefoundEvent, false, false));
-    });
-}
 
-class FirePostInstallEventsMicrotask final : public Microtask {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    explicit FirePostInstallEventsMicrotask(Ref<ServiceWorkerContainer>&& container, Ref<ServiceWorkerRegistration>&& registration)
-        : m_container(WTFMove(container))
-        , m_registration(WTFMove(registration))
-    {
-    }
-private:
-    Result run() final
-    {
-        auto* serviceWorker = m_registration->installing();
-        if (!serviceWorker)
-            return Result::Done;
-
-        callOnMainThread([container = WTFMove(m_container), registration = WTFMove(m_registration), serviceWorker = makeRef(*serviceWorker)] () mutable {
-            if (container->isStopped())
-                return;
-            registration->setInstallingWorker(nullptr);
-            registration->setWaitingWorker(serviceWorker.copyRef());
-            serviceWorker->updateWorkerState(ServiceWorker::State::Installed);
-            callOnMainThread([container = WTFMove(container), registration = WTFMove(registration), serviceWorker = WTFMove(serviceWorker)] () mutable {
-                if (container->isStopped())
-                    return;
-                registration->setWaitingWorker(nullptr);
-                registration->setActiveWorker(serviceWorker.copyRef());
-                serviceWorker->updateWorkerState(ServiceWorker::State::Activating);
-                callOnMainThread([container = WTFMove(container), serviceWorker = WTFMove(serviceWorker)] () mutable {
-                    if (container->isStopped())
-                        return;
-                    serviceWorker->updateWorkerState(ServiceWorker::State::Activated);
-                });
-            });
-        });
-        return Result::Done;
-    }
-
-    Ref<ServiceWorkerContainer> m_container;
-    Ref<ServiceWorkerRegistration> m_registration;
-};
-
-// FIXME: This method is only use to mimick service worker activation and will do away once we implement it.
-void ServiceWorkerContainer::firePostInstallEvents(const ServiceWorkerRegistrationKey& key)
-{
-    if (isStopped())
-        return;
-
-    auto* registration = m_registrations.get(key);
-    if (!registration)
-        return;
-
-    MicrotaskQueue::mainThreadQueue().append(std::make_unique<FirePostInstallEventsMicrotask>(*this, *registration));
+        if (auto* registration = m_registrations.get(key))
+            registration->dispatchEvent(Event::create(eventNames().updatefoundEvent, false, false));
+    });
 }
 
-void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job, ServiceWorkerRegistrationData&& data)
+void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job, ServiceWorkerRegistrationData&& data, WTF::Function<void()>&& promiseResolvedHandler)
 {
     auto guard = WTF::makeScopeExit([this, &job] {
         jobDidFinish(job);
@@ -342,19 +296,23 @@ void ServiceWorkerContainer::jobResolvedWithRegistration(ServiceWorkerJob& job,
     auto* context = scriptExecutionContext();
     if (!context) {
         LOG_ERROR("ServiceWorkerContainer::jobResolvedWithRegistration called but the containers ScriptExecutionContext is gone");
+        promiseResolvedHandler();
         return;
     }
 
-    RefPtr<ServiceWorkerRegistration> registration = m_registrations.get(data.key);
-    if (!registration)
-        registration = ServiceWorkerRegistration::create(*context, *this, WTFMove(data));
+    context->postTask([this, protectedThis = makeRef(*this), job = makeRef(job), data = WTFMove(data), promiseResolvedHandler = WTFMove(promiseResolvedHandler)](ScriptExecutionContext& context) mutable {
+        RefPtr<ServiceWorkerRegistration> registration = m_registrations.get(data.key);
+        if (!registration)
+            registration = ServiceWorkerRegistration::create(context, *this, WTFMove(data));
 
-    // FIXME: Implement proper selection of service workers.
-    context->setActiveServiceWorker(registration->getNewestWorker());
+        LOG(ServiceWorker, "Container %p resolved job with registration %p", this, registration.get());
 
-    LOG(ServiceWorker, "Container %p resolved job with registration %p", this, registration.get());
+        job->promise().resolve<IDLInterface<ServiceWorkerRegistration>>(*registration);
 
-    job.promise().resolve<IDLInterface<ServiceWorkerRegistration>>(*registration);
+        MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrotask>([promiseResolvedHandler = WTFMove(promiseResolvedHandler)] {
+            promiseResolvedHandler();
+        }));
+    });
 }
 
 void ServiceWorkerContainer::jobResolvedWithUnregistrationResult(ServiceWorkerJob& job, bool unregistrationResult)
@@ -373,7 +331,9 @@ void ServiceWorkerContainer::jobResolvedWithUnregistrationResult(ServiceWorkerJo
     if (unregistrationResult)
         context->setActiveServiceWorker(nullptr);
 
-    job.promise().resolve<IDLBoolean>(unregistrationResult);
+    context->postTask([job = makeRef(job), unregistrationResult](ScriptExecutionContext&) mutable {
+        job->promise().resolve<IDLBoolean>(unregistrationResult);
+    });
 }
 
 void ServiceWorkerContainer::startScriptFetchForJob(ServiceWorkerJob& job)
index 7581906..7f26337 100644 (file)
@@ -65,9 +65,8 @@ public:
     void updateRegistration(const URL& scopeURL, const URL& scriptURL, WorkerType, Ref<DeferredPromise>&&);
 
     void getRegistration(const String& clientURL, Ref<DeferredPromise>&&);
-    void updateRegistrationState(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerIdentifier>&);
-    void fireUpdateFoundEvent(const ServiceWorkerRegistrationKey&);
-    void firePostInstallEvents(const ServiceWorkerRegistrationKey&);
+    void scheduleTaskToUpdateRegistrationState(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerIdentifier>&);
+    void scheduleTaskToFireUpdateFoundEvent(const ServiceWorkerRegistrationKey&);
 
     using RegistrationsPromise = DOMPromiseDeferred<IDLSequence<IDLInterface<ServiceWorkerRegistration>>>;
     void getRegistrations(RegistrationsPromise&&);
@@ -86,7 +85,7 @@ private:
     void scheduleJob(Ref<ServiceWorkerJob>&&);
 
     void jobFailedWithException(ServiceWorkerJob&, const Exception&) final;
-    void jobResolvedWithRegistration(ServiceWorkerJob&, ServiceWorkerRegistrationData&&) final;
+    void jobResolvedWithRegistration(ServiceWorkerJob&, ServiceWorkerRegistrationData&&, WTF::Function<void()>&& promiseResolvedHandler) final;
     void jobResolvedWithUnregistrationResult(ServiceWorkerJob&, bool unregistrationResult) final;
     void startScriptFetchForJob(ServiceWorkerJob&) final;
     void jobFinishedLoadingScript(ServiceWorkerJob&, const String&) final;
index 1b91b87..7c52695 100644 (file)
@@ -58,13 +58,13 @@ void ServiceWorkerJob::failedWithException(const Exception& exception)
     m_client->jobFailedWithException(*this, exception);
 }
 
-void ServiceWorkerJob::resolvedWithRegistration(ServiceWorkerRegistrationData&& data)
+void ServiceWorkerJob::resolvedWithRegistration(ServiceWorkerRegistrationData&& data, WTF::Function<void()>&& promiseResolvedHandler)
 {
     ASSERT(currentThread() == m_creationThread);
     ASSERT(!m_completed);
 
     m_completed = true;
-    m_client->jobResolvedWithRegistration(*this, WTFMove(data));
+    m_client->jobResolvedWithRegistration(*this, WTFMove(data), WTFMove(promiseResolvedHandler));
 }
 
 void ServiceWorkerJob::resolvedWithUnregistrationResult(bool unregistrationResult)
index ae618da..6a58d46 100644 (file)
@@ -55,7 +55,7 @@ public:
     WEBCORE_EXPORT ~ServiceWorkerJob();
 
     void failedWithException(const Exception&);
-    void resolvedWithRegistration(ServiceWorkerRegistrationData&&);
+    void resolvedWithRegistration(ServiceWorkerRegistrationData&&, WTF::Function<void()>&& promiseResolvedHandler);
     void resolvedWithUnregistrationResult(bool);
     void startScriptFetch();
 
index 698adff..715a9c3 100644 (file)
@@ -40,7 +40,7 @@ public:
     virtual ~ServiceWorkerJobClient() = default;
 
     virtual void jobFailedWithException(ServiceWorkerJob&, const Exception&) = 0;
-    virtual void jobResolvedWithRegistration(ServiceWorkerJob&, ServiceWorkerRegistrationData&&) = 0;
+    virtual void jobResolvedWithRegistration(ServiceWorkerJob&, ServiceWorkerRegistrationData&&, WTF::Function<void()>&& promiseResolvedHandler) = 0;
     virtual void jobResolvedWithUnregistrationResult(ServiceWorkerJob&, bool unregistrationResult) = 0;
     virtual void startScriptFetchForJob(ServiceWorkerJob&) = 0;
     virtual void jobFinishedLoadingScript(ServiceWorkerJob&, const String&) = 0;
index a797568..674457d 100644 (file)
@@ -46,20 +46,18 @@ ServiceWorkerRegistration::ServiceWorkerRegistration(ScriptExecutionContext& con
     suspendIfNeeded();
 
     // FIXME: Reconcile worker state properly (see below)
-    if (m_registrationData.installingServiceWorkerIdentifier) {
-        m_installingWorker = ServiceWorker::create(context, *m_registrationData.installingServiceWorkerIdentifier, m_registrationData.scriptURL);
-        m_installingWorker->updateWorkerState(ServiceWorker::State::Installing);
-    }
-    if (m_registrationData.waitingServiceWorkerIdentifier) {
-        m_waitingWorker = ServiceWorker::create(context, *m_registrationData.waitingServiceWorkerIdentifier, m_registrationData.scriptURL);
-        // FIXME: Installed or Activating? This is why we have to have more data here...
-        m_waitingWorker->updateWorkerState(ServiceWorker::State::Installed);
-    }
+    if (m_registrationData.installingServiceWorkerIdentifier)
+        m_installingWorker = ServiceWorker::create(context, *m_registrationData.installingServiceWorkerIdentifier, m_registrationData.scriptURL, ServiceWorker::State::Installing);
+    if (m_registrationData.waitingServiceWorkerIdentifier)
+        m_waitingWorker = ServiceWorker::create(context, *m_registrationData.waitingServiceWorkerIdentifier, m_registrationData.scriptURL, ServiceWorker::State::Installed);
     if (m_registrationData.activeServiceWorkerIdentifier) {
-        m_activeWorker = ServiceWorker::create(context, *m_registrationData.activeServiceWorkerIdentifier, m_registrationData.scriptURL);
-        m_activeWorker->updateWorkerState(ServiceWorker::State::Activated);
+        // FIXME: Activating or Activated? This is why we have to have more data here...
+        m_activeWorker = ServiceWorker::create(context, *m_registrationData.activeServiceWorkerIdentifier, m_registrationData.scriptURL, ServiceWorker::State::Activated);
     }
 
+    // FIXME: Implement proper selection of service workers.
+    context.setActiveServiceWorker(getNewestWorker());
+
     m_container->addRegistration(*this);
 }
 
index d640299..ff35eea 100644 (file)
@@ -43,6 +43,8 @@ enum class ServiceWorkerState {
     Redundant,
 };
 
+enum class ShouldNotifyWhenResolved { No, Yes };
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index d9341b8..fa48b25 100644 (file)
@@ -31,6 +31,7 @@
 #include "Document.h"
 #include "ExceptionData.h"
 #include "MessageEvent.h"
+#include "Microtasks.h"
 #include "ServiceWorkerContainer.h"
 #include "ServiceWorkerFetchResult.h"
 #include "ServiceWorkerJobData.h"
@@ -75,7 +76,7 @@ void SWClientConnection::jobRejectedInServer(uint64_t jobIdentifier, const Excep
     job->failedWithException(exceptionData.toException());
 }
 
-void SWClientConnection::registrationJobResolvedInServer(uint64_t jobIdentifier, ServiceWorkerRegistrationData&& registrationData)
+void SWClientConnection::registrationJobResolvedInServer(uint64_t jobIdentifier, ServiceWorkerRegistrationData&& registrationData, ShouldNotifyWhenResolved shouldNotifyWhenResolved)
 {
     auto job = m_scheduledJobs.take(jobIdentifier);
     if (!job) {
@@ -83,7 +84,11 @@ void SWClientConnection::registrationJobResolvedInServer(uint64_t jobIdentifier,
         return;
     }
 
-    job->resolvedWithRegistration(WTFMove(registrationData));
+    auto key = registrationData.key;
+    job->resolvedWithRegistration(WTFMove(registrationData), [this, protectedThis = makeRef(*this), key, shouldNotifyWhenResolved] {
+        if (shouldNotifyWhenResolved == ShouldNotifyWhenResolved::Yes)
+            didResolveRegistrationPromise(key);
+    });
 }
 
 void SWClientConnection::unregistrationJobResolvedInServer(uint64_t jobIdentifier, bool unregistrationResult)
@@ -141,7 +146,7 @@ void SWClientConnection::postMessageToServiceWorkerClient(uint64_t destinationSc
 void SWClientConnection::forEachContainer(const WTF::Function<void(ServiceWorkerContainer&)>& apply)
 {
     // FIXME: We should iterate over all service worker clients, not only documents.
-    for (auto& document : Document::allDocuments()) {
+    for (auto* document : Document::allDocuments()) {
         if (auto* container = document->serviceWorkerContainer())
             apply(*container);
     }
@@ -150,29 +155,20 @@ void SWClientConnection::forEachContainer(const WTF::Function<void(ServiceWorker
 void SWClientConnection::updateRegistrationState(const ServiceWorkerRegistrationKey& key, ServiceWorkerRegistrationState state, std::optional<ServiceWorkerIdentifier> serviceWorkerIdentifier)
 {
     forEachContainer([&](ServiceWorkerContainer& container) {
-        container.updateRegistrationState(key, state, serviceWorkerIdentifier);
+        container.scheduleTaskToUpdateRegistrationState(key, state, serviceWorkerIdentifier);
     });
 }
 
-void SWClientConnection::updateWorkerState(ServiceWorkerIdentifier worker, ServiceWorkerState state)
+void SWClientConnection::updateWorkerState(ServiceWorkerIdentifier identifier, ServiceWorkerState state)
 {
-    const auto& matchingWorkers = ServiceWorker::allWorkers().get(worker);
-    
-    for (auto* worker : matchingWorkers)
-        worker->updateWorkerState(state);
+    for (auto* worker : ServiceWorker::allWorkers().get(identifier))
+        worker->scheduleTaskToUpdateState(state);
 }
 
 void SWClientConnection::fireUpdateFoundEvent(const ServiceWorkerRegistrationKey& key)
 {
     forEachContainer([&](ServiceWorkerContainer& container) {
-        container.fireUpdateFoundEvent(key);
-    });
-}
-
-void SWClientConnection::firePostInstallEvents(const ServiceWorkerRegistrationKey& key)
-{
-    forEachContainer([&](ServiceWorkerContainer& container) {
-        container.firePostInstallEvents(key);
+        container.scheduleTaskToFireUpdateFoundEvent(key);
     });
 }
 
index 6fc6438..77b1c33 100644 (file)
@@ -41,6 +41,7 @@ class ServiceWorkerRegistration;
 class SharedBuffer;
 enum class ServiceWorkerRegistrationState;
 enum class ServiceWorkerState;
+enum class ShouldNotifyWhenResolved;
 struct ExceptionData;
 struct ServiceWorkerFetchResult;
 struct ServiceWorkerRegistrationData;
@@ -59,6 +60,8 @@ public:
     void finishedFetchingScript(ServiceWorkerJob&, const String&);
     void failedFetchingScript(ServiceWorkerJob&, const ResourceError&);
 
+    virtual void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&) = 0;
+
     virtual void postMessageToServiceWorkerGlobalScope(ServiceWorkerIdentifier destinationIdentifier, Ref<SerializedScriptValue>&&, ScriptExecutionContext& source) = 0;
     virtual uint64_t identifier() const = 0;
     virtual bool hasServiceWorkerRegisteredForOrigin(const SecurityOrigin&) const = 0;
@@ -67,14 +70,13 @@ protected:
     WEBCORE_EXPORT SWClientConnection();
 
     WEBCORE_EXPORT void jobRejectedInServer(uint64_t jobIdentifier, const ExceptionData&);
-    WEBCORE_EXPORT void registrationJobResolvedInServer(uint64_t jobIdentifier, ServiceWorkerRegistrationData&&);
+    WEBCORE_EXPORT void registrationJobResolvedInServer(uint64_t jobIdentifier, ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved);
     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, ServiceWorkerIdentifier source, const String& sourceOrigin);
     WEBCORE_EXPORT void updateRegistrationState(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, std::optional<ServiceWorkerIdentifier>);
     WEBCORE_EXPORT void updateWorkerState(ServiceWorkerIdentifier, ServiceWorkerState);
     WEBCORE_EXPORT void fireUpdateFoundEvent(const ServiceWorkerRegistrationKey&);
-    WEBCORE_EXPORT void firePostInstallEvents(const ServiceWorkerRegistrationKey&);
 
 private:
     virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
index 1f69207..72c903d 100644 (file)
@@ -117,6 +117,11 @@ void SWServer::Connection::didFinishInstall(const ServiceWorkerRegistrationKey&
     m_server.didFinishInstall(*this, key, serviceWorkerIdentifier, wasSuccessful);
 }
 
+void SWServer::Connection::didResolveRegistrationPromise(const ServiceWorkerRegistrationKey& key)
+{
+    m_server.didResolveRegistrationPromise(*this, key);
+}
+
 void SWServer::Connection::addServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey& key, uint64_t clientRegistrationIdentifier)
 {
     m_server.addClientServiceWorkerRegistration(*this, key, clientRegistrationIdentifier);
@@ -171,14 +176,14 @@ void SWServer::rejectJob(const ServiceWorkerJobData& jobData, const ExceptionDat
     connection->rejectJobInClient(jobData.identifier(), exceptionData);
 }
 
-void SWServer::resolveRegistrationJob(const ServiceWorkerJobData& jobData, const ServiceWorkerRegistrationData& registrationData)
+void SWServer::resolveRegistrationJob(const ServiceWorkerJobData& jobData, const ServiceWorkerRegistrationData& registrationData, ShouldNotifyWhenResolved shouldNotifyWhenResolved)
 {
     LOG(ServiceWorker, "Resolved ServiceWorker job %" PRIu64 "-%" PRIu64 " in server with registration %" PRIu64, jobData.connectionIdentifier(), jobData.identifier(), registrationData.identifier);
     auto* connection = m_connections.get(jobData.connectionIdentifier());
     if (!connection)
         return;
 
-    connection->resolveRegistrationJobInClient(jobData.identifier(), registrationData);
+    connection->resolveRegistrationJobInClient(jobData.identifier(), registrationData, shouldNotifyWhenResolved);
 }
 
 void SWServer::resolveUnregistrationJob(const ServiceWorkerJobData& jobData, const ServiceWorkerRegistrationKey& registrationKey, bool unregistrationResult)
@@ -237,6 +242,14 @@ void SWServer::didFinishInstall(Connection& connection, const ServiceWorkerRegis
         jobQueue->didFinishInstall(connection, serviceWorkerIdentifier, wasSuccessful);
 }
 
+void SWServer::didResolveRegistrationPromise(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey)
+{
+    ASSERT(m_connections.contains(connection.identifier()));
+
+    if (auto* jobQueue = m_jobQueues.get(registrationKey))
+        jobQueue->didResolveRegistrationPromise(connection);
+}
+
 void SWServer::addClientServiceWorkerRegistration(Connection& connection, const ServiceWorkerRegistrationKey& key, uint64_t registrationIdentifier)
 {
     auto* registration = m_registrations.get(key);
index ef6a02c..580cc26 100644 (file)
@@ -62,13 +62,13 @@ public:
         WEBCORE_EXPORT void scriptContextFailedToStart(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier, const String& message);
         WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier);
         WEBCORE_EXPORT void didFinishInstall(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier, bool wasSuccessful);
+        WEBCORE_EXPORT void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&);
         const SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const { return m_server.doRegistrationMatching(topOrigin, clientURL); }
 
         // Messages to the client WebProcess
         virtual void updateRegistrationStateInClient(const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationState, std::optional<ServiceWorkerIdentifier>) = 0;
         virtual void updateWorkerStateInClient(ServiceWorkerIdentifier, ServiceWorkerState) = 0;
         virtual void fireUpdateFoundEvent(const ServiceWorkerRegistrationKey&) = 0;
-        virtual void firePostInstallEvents(const ServiceWorkerRegistrationKey&) = 0;
 
     protected:
         WEBCORE_EXPORT Connection(SWServer&, uint64_t identifier);
@@ -82,7 +82,7 @@ public:
     private:
         // Messages to the client WebProcess
         virtual void rejectJobInClient(uint64_t jobIdentifier, const ExceptionData&) = 0;
-        virtual void resolveRegistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData&) = 0;
+        virtual void resolveRegistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved) = 0;
         virtual void resolveUnregistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationKey&, bool registrationResult) = 0;
         virtual void startScriptFetchInClient(uint64_t jobIdentifier) = 0;
 
@@ -104,7 +104,7 @@ public:
 
     void scheduleJob(const ServiceWorkerJobData&);
     void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
-    void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&);
+    void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved);
     void resolveUnregistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationKey&, bool unregistrationResult);
     void startScriptFetch(const ServiceWorkerJobData&);
 
@@ -128,6 +128,7 @@ private:
     void scriptContextFailedToStart(Connection&, const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier, const String& message);
     void scriptContextStarted(Connection&, const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier);
     void didFinishInstall(Connection&, const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier, bool wasSuccessful);
+    void didResolveRegistrationPromise(Connection&, const ServiceWorkerRegistrationKey&);
 
     void addClientServiceWorkerRegistration(Connection&, const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier);
     void removeClientServiceWorkerRegistration(Connection&, const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier);
index a2f9556..b38baca 100644 (file)
@@ -109,7 +109,7 @@ void SWServerJobQueue::scriptContextStarted(SWServer::Connection& connection, Se
 }
 
 // https://w3c.github.io/ServiceWorker/#install
-void SWServerJobQueue::install(SWServerRegistration& registration, SWServer::Connection& connection, ServiceWorkerIdentifier installingWorker)
+void SWServerJobQueue::install(SWServerRegistration& registration, SWServer::Connection&, ServiceWorkerIdentifier installingWorker)
 {
     // The Install algorithm should never be invoked with a null worker.
     auto* worker = m_server.workerByID(installingWorker);
@@ -121,15 +121,24 @@ void SWServerJobQueue::install(SWServerRegistration& registration, SWServer::Con
     registration.updateWorkerState(job, *worker, ServiceWorkerState::Installing);
 
     // Invoke Resolve Job Promise with job and registration.
-    m_server.resolveRegistrationJob(job, registration.data());
+    m_server.resolveRegistrationJob(job, registration.data(), ShouldNotifyWhenResolved::Yes);
+}
+
+// https://w3c.github.io/ServiceWorker/#install (after resolving promise).
+void SWServerJobQueue::didResolveRegistrationPromise(SWServer::Connection& connection)
+{
+    auto* registration = m_server.getRegistration(m_registrationKey);
+    ASSERT(registration);
+
+    auto& job = firstJob();
 
     // Queue a task to fire an event named updatefound at all the ServiceWorkerRegistration objects
     // for all the service worker clients whose creation URL matches registration's scope url and
     // all the service workers whose containing service worker registration is registration.
-    registration.fireUpdateFoundEvent(job);
+    registration->fireUpdateFoundEvent(job);
 
     // Queue a task to fire the InstallEvent.
-    m_server.fireInstallEvent(connection, installingWorker);
+    m_server.fireInstallEvent(connection, registration->installingWorker()->identifier());
 }
 
 // https://w3c.github.io/ServiceWorker/#install
@@ -138,7 +147,7 @@ void SWServerJobQueue::didFinishInstall(SWServer::Connection&, ServiceWorkerIden
     auto* registration = m_server.getRegistration(m_registrationKey);
     ASSERT(registration);
 
-    auto& job = firstJob();
+    auto job = firstJob();
 
     if (!wasSuccessful) {
         auto* worker = m_server.workerByID(identifier);
@@ -157,10 +166,29 @@ void SWServerJobQueue::didFinishInstall(SWServer::Connection&, ServiceWorkerIden
         return;
     }
 
-    // FIXME: Implement real post 'install' event steps of the Install algorithm (steps 14+).
-    registration->firePostInstallEvents(job);
+    if (auto* waitingWorker = registration->waitingWorker()) {
+        waitingWorker->terminate();
+        registration->updateWorkerState(job, *waitingWorker, ServiceWorkerState::Redundant);
+    }
+
+    auto* installing = registration->installingWorker();
+    ASSERT(installing);
+
+    registration->updateRegistrationState(job, ServiceWorkerRegistrationState::Waiting, installing);
+    registration->updateRegistrationState(job, ServiceWorkerRegistrationState::Installing, nullptr);
+    registration->updateWorkerState(job, *installing, ServiceWorkerState::Installed);
 
     finishCurrentJob();
+
+    // FIXME: Invoke Try Activate with registration
+    // FIXME: Do we need "Wait for all the tasks queued by Update Worker State invoked in this algorithm have executed" first?
+    auto* waiting = registration->waitingWorker();
+    ASSERT(waiting);
+
+    registration->updateRegistrationState(job, ServiceWorkerRegistrationState::Active, waiting);
+    registration->updateRegistrationState(job, ServiceWorkerRegistrationState::Waiting, nullptr);
+    registration->updateWorkerState(job, *waiting, ServiceWorkerState::Activating);
+    registration->updateWorkerState(job, *waiting, ServiceWorkerState::Activated);
 }
 
 // https://w3c.github.io/ServiceWorker/#run-job
@@ -210,7 +238,7 @@ void SWServerJobQueue::runRegisterJob(const ServiceWorkerJobData& job)
         registration->setIsUninstalling(false);
         auto* newestWorker = registration->getNewestWorker();
         if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == registration->updateViaCache()) {
-            m_server.resolveRegistrationJob(firstJob(), registration->data());
+            m_server.resolveRegistrationJob(firstJob(), registration->data(), ShouldNotifyWhenResolved::No);
             finishCurrentJob();
             return;
         }
index 52155b8..5843789 100644 (file)
@@ -51,6 +51,7 @@ public:
     void scriptContextFailedToStart(SWServer::Connection&, ServiceWorkerIdentifier, const String& message);
     void scriptContextStarted(SWServer::Connection&, ServiceWorkerIdentifier);
     void didFinishInstall(SWServer::Connection&, ServiceWorkerIdentifier, bool wasSuccessful);
+    void didResolveRegistrationPromise(SWServer::Connection&);
 
 private:
     void jobTimerFired();
index 100b215..8d84dcb 100644 (file)
@@ -102,14 +102,6 @@ void SWServerRegistration::fireUpdateFoundEvent(const ServiceWorkerJobData& job)
     });
 }
 
-// FIXME: This will do away once we correctly update the registration state after install.
-void SWServerRegistration::firePostInstallEvents(const ServiceWorkerJobData& job)
-{
-    forEachConnection(job, [&](auto& connection) {
-        connection.firePostInstallEvents(m_registrationKey);
-    });
-}
-
 void SWServerRegistration::forEachConnection(const ServiceWorkerJobData& job, const WTF::Function<void(SWServer::Connection&)>& apply)
 {
     // No matter what, we send the event to the connection that scheduled the job. The client registration
index 2b37ba4..3786944 100644 (file)
@@ -59,11 +59,14 @@ public:
     void updateRegistrationState(const ServiceWorkerJobData&, ServiceWorkerRegistrationState, SWServerWorker*);
     void updateWorkerState(const ServiceWorkerJobData&, SWServerWorker&, ServiceWorkerState);
     void fireUpdateFoundEvent(const ServiceWorkerJobData&);
-    void firePostInstallEvents(const ServiceWorkerJobData&);
 
     void addClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier);
     void removeClientServiceWorkerRegistration(uint64_t connectionIdentifier, uint64_t clientRegistrationIdentifier);
 
+    SWServerWorker* installingWorker() const { return m_installingWorker.get(); }
+    SWServerWorker* waitingWorker() const { return m_waitingWorker.get(); }
+    SWServerWorker* activeWorker() const { return m_activeWorker.get(); }
+
 private:
     void forEachConnection(const ServiceWorkerJobData&, const WTF::Function<void(SWServer::Connection&)>&);
 
index 01b087d..125a264 100644 (file)
@@ -41,6 +41,11 @@ SWServerWorker::SWServerWorker(const ServiceWorkerRegistrationKey& registrationK
 
 SWServerWorker::~SWServerWorker() = default;
 
+void SWServerWorker::terminate()
+{
+    // FIXME: Implement
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index a3c8145..abcd59c 100644 (file)
@@ -47,6 +47,8 @@ public:
     SWServerWorker(const SWServerWorker&) = delete;
     ~SWServerWorker();
 
+    void terminate();
+
     const URL& scriptURL() const { return m_scriptURL; }
     const String& script() const { return m_script; }
     WorkerType type() const { return m_type; }
index e85e0e5..0096905 100644 (file)
@@ -1,3 +1,25 @@
+2017-11-09  Chris Dumez  <cdumez@apple.com>
+
+        Implement real post 'install' event steps of the Install algorithm (steps 14+)
+        https://bugs.webkit.org/show_bug.cgi?id=179401
+
+        Reviewed by Brady Eidson.
+
+        Implement step 14+ of Install algorithm, as per:
+        - https://w3c.github.io/ServiceWorker/#installation-algorithm
+
+        * Scripts/webkit/messages.py:
+        (headers_for_type):
+        * Shared/WebCoreArgumentCoders.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::resolveRegistrationJobInClient):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        (WebKit::WebSWClientConnection::didResolveRegistrationPromise):
+        * WebProcess/Storage/WebSWClientConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+
 2017-11-09  Megan Gardner  <megan_gardner@apple.com>
 
         Clean out unused selection items from UIKitSPI
index 2db00f0..3961e6e 100644 (file)
@@ -376,6 +376,7 @@ def headers_for_type(type):
         'WebCore::ServiceWorkerState': ['<WebCore/ServiceWorkerTypes.h>'],
         'WebCore::ShippingContactUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
         'WebCore::ShippingMethodUpdate': ['<WebCore/ApplePaySessionPaymentRequest.h>'],
+        'WebCore::ShouldNotifyWhenResolved': ['<WebCore/ServiceWorkerTypes.h>'],
         'WebCore::ShouldSample': ['<WebCore/DiagnosticLoggingClient.h>'],
         'WebCore::TextCheckingRequestData': ['<WebCore/TextChecking.h>'],
         'WebCore::TextCheckingResult': ['<WebCore/TextCheckerClient.h>'],
index 33596be..98d97ad 100644 (file)
@@ -826,6 +826,14 @@ template <> struct EnumTraits<WebCore::ServiceWorkerState> {
         WebCore::ServiceWorkerState::Redundant
     >;
 };
+
+template <> struct EnumTraits<WebCore::ShouldNotifyWhenResolved> {
+    using values = EnumValues<
+        WebCore::ShouldNotifyWhenResolved,
+        WebCore::ShouldNotifyWhenResolved::No,
+        WebCore::ShouldNotifyWhenResolved::Yes
+    >;
+};
 #endif
 
 } // namespace WTF
index 856df0e..db7a0af 100644 (file)
@@ -76,11 +76,11 @@ void WebSWServerConnection::rejectJobInClient(uint64_t jobIdentifier, const Exce
     send(Messages::WebSWClientConnection::JobRejectedInServer(jobIdentifier, exceptionData));
 }
 
-void WebSWServerConnection::resolveRegistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData& registrationData)
+void WebSWServerConnection::resolveRegistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationData& registrationData, ShouldNotifyWhenResolved shouldNotifyWhenResolved)
 {
     auto origin = registrationData.key.topOrigin().securityOrigin();
     StorageProcess::singleton().ensureSWOriginStoreForSession(m_sessionID).add(origin);
-    send(Messages::WebSWClientConnection::RegistrationJobResolvedInServer(jobIdentifier, registrationData));
+    send(Messages::WebSWClientConnection::RegistrationJobResolvedInServer(jobIdentifier, registrationData, shouldNotifyWhenResolved));
 }
 
 void WebSWServerConnection::resolveUnregistrationJobInClient(uint64_t jobIdentifier, const ServiceWorkerRegistrationKey& registrationKey, bool unregistrationResult)
@@ -106,11 +106,6 @@ void WebSWServerConnection::fireUpdateFoundEvent(const ServiceWorkerRegistration
     send(Messages::WebSWClientConnection::FireUpdateFoundEvent(key));
 }
 
-void WebSWServerConnection::firePostInstallEvents(const ServiceWorkerRegistrationKey& key)
-{
-    send(Messages::WebSWClientConnection::FirePostInstallEvents(key));
-}
-
 void WebSWServerConnection::updateWorkerStateInClient(ServiceWorkerIdentifier worker, ServiceWorkerState state)
 {
     send(Messages::WebSWClientConnection::UpdateWorkerState(worker, state));
index 9779728..38edb4c 100644 (file)
@@ -62,13 +62,12 @@ public:
 private:
     // Implement SWServer::Connection (Messages to the client WebProcess)
     void rejectJobInClient(uint64_t jobIdentifier, const WebCore::ExceptionData&) final;
-    void resolveRegistrationJobInClient(uint64_t jobIdentifier, const WebCore::ServiceWorkerRegistrationData&) final;
+    void resolveRegistrationJobInClient(uint64_t jobIdentifier, const WebCore::ServiceWorkerRegistrationData&, WebCore::ShouldNotifyWhenResolved) 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, std::optional<WebCore::ServiceWorkerIdentifier>) final;
     void updateWorkerStateInClient(WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerState) final;
     void fireUpdateFoundEvent(const WebCore::ServiceWorkerRegistrationKey&) final;
-    void firePostInstallEvents(const WebCore::ServiceWorkerRegistrationKey&) final;
 
     void startFetch(uint64_t fetchIdentifier, std::optional<WebCore::ServiceWorkerIdentifier>, const WebCore::ResourceRequest&, const WebCore::FetchOptions&);
 
index 7257dfe..5f5d681 100644 (file)
@@ -32,6 +32,8 @@ messages -> WebSWServerConnection {
     StartFetch(uint64_t identifier, std::optional<WebCore::ServiceWorkerIdentifier> serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options)
     PostMessageToServiceWorkerGlobalScope(WebCore::ServiceWorkerIdentifier destinationServiceWorkerIdentifier, IPC::DataReference message, uint64_t sourceScriptExecutionContextIdentifier, String sourceOrigin)
 
+    DidResolveRegistrationPromise(WebCore::ServiceWorkerRegistrationKey key)
+
     MatchRegistration(uint64_t serviceRegistrationMatchRequestIdentifier, struct WebCore::SecurityOriginData topOrigin, WebCore::URL clientURL)
 }
 
index 2e3823d..ec95175 100644 (file)
@@ -89,6 +89,11 @@ void WebSWClientConnection::postMessageToServiceWorkerGlobalScope(ServiceWorkerI
     send(Messages::WebSWServerConnection::PostMessageToServiceWorkerGlobalScope(destinationIdentifier, IPC::DataReference { scriptValue->data() }, downcast<Document>(source).identifier(), source.origin()));
 }
 
+void WebSWClientConnection::didResolveRegistrationPromise(const ServiceWorkerRegistrationKey& key)
+{
+    send(Messages::WebSWServerConnection::DidResolveRegistrationPromise(key));
+}
+
 bool WebSWClientConnection::hasServiceWorkerRegisteredForOrigin(const SecurityOrigin& origin) const
 {
     return m_swOriginTable->contains(origin);
index d4c644a..45bf2e9 100644 (file)
@@ -73,6 +73,8 @@ private:
     void matchRegistration(const WebCore::SecurityOrigin& topOrigin, const WebCore::URL& clientURL, RegistrationCallback&&) final;
     void didMatchRegistration(uint64_t matchRequestIdentifier, std::optional<WebCore::ServiceWorkerRegistrationData>&&);
 
+    void didResolveRegistrationPromise(const WebCore::ServiceWorkerRegistrationKey&) final;
+
     void scheduleStorageJob(const WebCore::ServiceWorkerJobData&);
 
     IPC::Connection* messageSenderConnection() final { return m_connection.ptr(); }
index c0330e3..6a347c4 100644 (file)
 messages -> WebSWClientConnection {
     # When possible, these messages can be implemented directly by WebCore::SWServer::Connection
     JobRejectedInServer(uint64_t identifier, struct WebCore::ExceptionData exception)
-    RegistrationJobResolvedInServer(uint64_t identifier, struct WebCore::ServiceWorkerRegistrationData registration)
+    RegistrationJobResolvedInServer(uint64_t identifier, struct WebCore::ServiceWorkerRegistrationData registration, enum WebCore::ShouldNotifyWhenResolved shouldNotifyWhenResolved)
     UnregistrationJobResolvedInServer(uint64_t identifier, bool unregistrationResult)
     StartScriptFetchForServer(uint64_t jobIdentifier)
     UpdateRegistrationState(WebCore::ServiceWorkerRegistrationKey key, enum WebCore::ServiceWorkerRegistrationState state, std::optional<WebCore::ServiceWorkerIdentifier> serviceWorkerIdentifier)
     UpdateWorkerState(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum WebCore::ServiceWorkerState state)
     FireUpdateFoundEvent(WebCore::ServiceWorkerRegistrationKey key)
-    FirePostInstallEvents(WebCore::ServiceWorkerRegistrationKey key)
 
     SetSWOriginTableSharedMemory(WebKit::SharedMemory::Handle handle)
     PostMessageToServiceWorkerClient(uint64_t destinationScriptExecutionContextIdentifier, IPC::DataReference message, WebCore::ServiceWorkerIdentifier sourceServiceWorkerIdentifier, String sourceOrigin)