From 3ebceab01835e4c249c4d948e7a5a61099b1f033 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Wed, 14 Feb 2018 14:23:16 -0500 Subject: [PATCH] Bug 1434701 P6 Make ServiceWorkerRegistrationListener updates take a ServiceWorkerRegistrationDescriptor. r=asuth --- .../base/nsIServiceWorkerManager.idl | 10 -- dom/serviceworkers/ServiceWorkerCommon.h | 25 --- dom/serviceworkers/ServiceWorkerManager.cpp | 138 ++-------------- dom/serviceworkers/ServiceWorkerManager.h | 13 +- .../ServiceWorkerRegistration.cpp | 5 +- .../ServiceWorkerRegistration.h | 1 - .../ServiceWorkerRegistrationImpl.cpp | 154 +++++++----------- .../ServiceWorkerRegistrationImpl.h | 11 +- .../ServiceWorkerRegistrationInfo.cpp | 127 +++++++-------- .../ServiceWorkerRegistrationInfo.h | 12 +- .../ServiceWorkerRegistrationListener.h | 12 +- dom/serviceworkers/moz.build | 1 - .../detached-context.https.html.ini | 3 - 13 files changed, 142 insertions(+), 370 deletions(-) delete mode 100644 dom/serviceworkers/ServiceWorkerCommon.h diff --git a/dom/interfaces/base/nsIServiceWorkerManager.idl b/dom/interfaces/base/nsIServiceWorkerManager.idl index 7b7f142708d6..cf3e7382cc22 100644 --- a/dom/interfaces/base/nsIServiceWorkerManager.idl +++ b/dom/interfaces/base/nsIServiceWorkerManager.idl @@ -156,16 +156,6 @@ interface nsIServiceWorkerManager : nsISupports [notxpcom, nostdcall] bool StartControlling(in const_ClientInfoRef aClientInfo, in const_ServiceWorkerDescriptorRef aServiceWorker); - /* - * Returns a ServiceWorker. - * window is the window of the caller. scope is the registration's scope and must be - * a valid entry that window is allowed to load, otherwise this will return nullptr. - * These are only meant to be called from ServiceWorkerRegistration instances. - */ - [noscript] nsISupports GetInstalling(in nsPIDOMWindowInner aWindow, in DOMString aScope); - [noscript] nsISupports GetWaiting(in nsPIDOMWindowInner aWindow, in DOMString aScope); - [noscript] nsISupports GetActive(in nsPIDOMWindowInner aWindow, in DOMString aScope); - /* * Clears ServiceWorker registrations from memory and disk for the specified * host. diff --git a/dom/serviceworkers/ServiceWorkerCommon.h b/dom/serviceworkers/ServiceWorkerCommon.h deleted file mode 100644 index 1c272c125c9a..000000000000 --- a/dom/serviceworkers/ServiceWorkerCommon.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_ServiceWorkerCommon_h -#define mozilla_dom_ServiceWorkerCommon_h - -namespace mozilla { -namespace dom { - -// Use multiples of 2 since they can be bitwise ORed when calling -// InvalidateServiceWorkerRegistrationWorker. -enum class WhichServiceWorker { - INSTALLING_WORKER = 1, - WAITING_WORKER = 2, - ACTIVE_WORKER = 4, -}; -MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WhichServiceWorker) - -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_ServiceWorkerCommon_h diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp index 66d20323b640..a09b13faf3d1 100644 --- a/dom/serviceworkers/ServiceWorkerManager.cpp +++ b/dom/serviceworkers/ServiceWorkerManager.cpp @@ -467,7 +467,14 @@ class ServiceWorkerResolveWindowPromiseOnRegisterCallback final : public Service RefPtr swr = window->GetServiceWorkerRegistration(reg->Descriptor()); - promise->MaybeResolve(swr); + + nsCOMPtr r = NS_NewRunnableFunction( + "ServiceWorkerResolveWindowPromiseOnRegisterCallback::JobFinished", + [promise = Move(promise), swr = Move(swr)] () { + promise->MaybeResolve(swr); + }); + MOZ_ALWAYS_SUCCEEDS( + window->EventTargetFor(TaskCategory::Other)->Dispatch(r.forget())); } public: @@ -2307,72 +2314,6 @@ ServiceWorkerManager::FireUpdateFoundOnServiceWorkerRegistrations( } } -/* - * This is used for installing, waiting and active. - */ -nsresult -ServiceWorkerManager::GetServiceWorkerForScope(nsPIDOMWindowInner* aWindow, - const nsAString& aScope, - WhichServiceWorker aWhichWorker, - nsISupports** aServiceWorker) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_WARN_IF(!aWindow)) { - return NS_ERROR_DOM_INVALID_STATE_ERR; - } - - nsCOMPtr doc = aWindow->GetExtantDoc(); - MOZ_ASSERT(doc); - - /////////////////////////////////////////// - // Security check - nsAutoCString scope = NS_ConvertUTF16toUTF8(aScope); - nsCOMPtr scopeURI; - // We pass nullptr as the base URI since scopes obtained from - // ServiceWorkerRegistrations MUST be fully qualified URIs. - nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), scope, nullptr, nullptr); - if (NS_WARN_IF(NS_FAILED(rv))) { - return NS_ERROR_DOM_SECURITY_ERR; - } - - nsCOMPtr documentPrincipal = doc->NodePrincipal(); - rv = documentPrincipal->CheckMayLoad(scopeURI, true /* report */, - false /* allowIfInheritsPrinciple */); - if (NS_WARN_IF(NS_FAILED(rv))) { - return NS_ERROR_DOM_SECURITY_ERR; - } - //////////////////////////////////////////// - - RefPtr registration = - GetRegistration(documentPrincipal, scope); - if (NS_WARN_IF(!registration)) { - return NS_ERROR_FAILURE; - } - - RefPtr info; - if (aWhichWorker == WhichServiceWorker::INSTALLING_WORKER) { - info = registration->GetInstalling(); - } else if (aWhichWorker == WhichServiceWorker::WAITING_WORKER) { - info = registration->GetWaiting(); - } else if (aWhichWorker == WhichServiceWorker::ACTIVE_WORKER) { - info = registration->GetActive(); - } else { - MOZ_CRASH("Invalid worker type"); - } - - if (NS_WARN_IF(!info)) { - return NS_ERROR_DOM_NOT_FOUND_ERR; - } - - RefPtr serviceWorker = - aWindow->GetOrCreateServiceWorker(info->Descriptor()); - - serviceWorker->SetState(info->State()); - serviceWorker.forget(aServiceWorker); - return NS_OK; -} - namespace { class ContinueDispatchFetchEventRunnable : public Runnable @@ -2625,72 +2566,15 @@ ServiceWorkerManager::GetClientRegistration(const ClientInfo& aClientInfo, return NS_OK; } -NS_IMETHODIMP -ServiceWorkerManager::GetInstalling(nsPIDOMWindowInner* aWindow, - const nsAString& aScope, - nsISupports** aServiceWorker) -{ - return GetServiceWorkerForScope(aWindow, aScope, - WhichServiceWorker::INSTALLING_WORKER, - aServiceWorker); -} - -NS_IMETHODIMP -ServiceWorkerManager::GetWaiting(nsPIDOMWindowInner* aWindow, - const nsAString& aScope, - nsISupports** aServiceWorker) -{ - return GetServiceWorkerForScope(aWindow, aScope, - WhichServiceWorker::WAITING_WORKER, - aServiceWorker); -} - -NS_IMETHODIMP -ServiceWorkerManager::GetActive(nsPIDOMWindowInner* aWindow, - const nsAString& aScope, - nsISupports** aServiceWorker) -{ - return GetServiceWorkerForScope(aWindow, aScope, - WhichServiceWorker::ACTIVE_WORKER, - aServiceWorker); -} - void -ServiceWorkerManager::TransitionServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration, - WhichServiceWorker aWhichOne) +ServiceWorkerManager::UpdateRegistrationListeners(ServiceWorkerRegistrationInfo* aReg) { MOZ_ASSERT(NS_IsMainThread()); nsTObserverArray::ForwardIterator it(mServiceWorkerRegistrationListeners); while (it.HasMore()) { RefPtr target = it.GetNext(); - nsAutoString regScope; - target->GetScope(regScope); - MOZ_ASSERT(!regScope.IsEmpty()); - - NS_ConvertUTF16toUTF8 utf8Scope(regScope); - - if (utf8Scope.Equals(aRegistration->Scope())) { - target->TransitionWorker(aWhichOne); - } - } -} - -void -ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration, - WhichServiceWorker aWhichOnes) -{ - MOZ_ASSERT(NS_IsMainThread()); - nsTObserverArray::ForwardIterator it(mServiceWorkerRegistrationListeners); - while (it.HasMore()) { - RefPtr target = it.GetNext(); - nsAutoString regScope; - target->GetScope(regScope); - MOZ_ASSERT(!regScope.IsEmpty()); - - NS_ConvertUTF16toUTF8 utf8Scope(regScope); - - if (utf8Scope.Equals(aRegistration->Scope())) { - target->InvalidateWorkers(aWhichOnes); + if (target->MatchesDescriptor(aReg->Descriptor())) { + target->UpdateState(aReg->Descriptor()); } } } diff --git a/dom/serviceworkers/ServiceWorkerManager.h b/dom/serviceworkers/ServiceWorkerManager.h index d0362c69fcdb..185c5d5cdc10 100644 --- a/dom/serviceworkers/ServiceWorkerManager.h +++ b/dom/serviceworkers/ServiceWorkerManager.h @@ -23,7 +23,6 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/ClientHandle.h" #include "mozilla/dom/Promise.h" -#include "mozilla/dom/ServiceWorkerCommon.h" #include "mozilla/dom/ServiceWorkerRegistrar.h" #include "mozilla/dom/ServiceWorkerRegistrarTypes.h" #include "mozilla/dom/ServiceWorkerRegistrationInfo.h" @@ -352,12 +351,6 @@ private: GetClientRegistration(const ClientInfo& aClientInfo, ServiceWorkerRegistrationInfo** aRegistrationInfo); - nsresult - GetServiceWorkerForScope(nsPIDOMWindowInner* aWindow, - const nsAString& aScope, - WhichServiceWorker aWhichWorker, - nsISupports** aServiceWorker); - ServiceWorkerInfo* GetActiveWorkerInfoForScope(const OriginAttributes& aOriginAttributes, const nsACString& aScope); @@ -366,11 +359,7 @@ private: GetActiveWorkerInfoForDocument(nsIDocument* aDocument); void - TransitionServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration, - WhichServiceWorker aWhichOne); - void - InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration, - WhichServiceWorker aWhichOnes); + UpdateRegistrationListeners(ServiceWorkerRegistrationInfo* aReg); void NotifyServiceWorkerRegistrationRemoved(ServiceWorkerRegistrationInfo* aRegistration); diff --git a/dom/serviceworkers/ServiceWorkerRegistration.cpp b/dom/serviceworkers/ServiceWorkerRegistration.cpp index 09234edcbf26..a5e78ab7c331 100644 --- a/dom/serviceworkers/ServiceWorkerRegistration.cpp +++ b/dom/serviceworkers/ServiceWorkerRegistration.cpp @@ -45,8 +45,9 @@ ServiceWorkerRegistration::CreateForMainThread(nsPIDOMWindowInner* aWindow, NS_ConvertUTF8toUTF16 scope(aDescriptor.Scope()); - RefPtr registration = + RefPtr registration = new ServiceWorkerRegistrationMainThread(aWindow, scope); + registration->UpdateState(aDescriptor); return registration.forget(); } @@ -60,7 +61,7 @@ ServiceWorkerRegistration::CreateForWorker(WorkerPrivate* aWorkerPrivate, NS_ConvertUTF8toUTF16 scope(aDescriptor.Scope()); - RefPtr registration = + RefPtr registration = new ServiceWorkerRegistrationWorkerThread(aWorkerPrivate, scope); return registration.forget(); diff --git a/dom/serviceworkers/ServiceWorkerRegistration.h b/dom/serviceworkers/ServiceWorkerRegistration.h index dfbb8c093ce9..f660c482479b 100644 --- a/dom/serviceworkers/ServiceWorkerRegistration.h +++ b/dom/serviceworkers/ServiceWorkerRegistration.h @@ -10,7 +10,6 @@ #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/dom/DOMPrefs.h" #include "mozilla/dom/ServiceWorkerBinding.h" -#include "mozilla/dom/ServiceWorkerCommon.h" #include "mozilla/dom/ServiceWorkerRegistrationBinding.h" // Support for Notification API extension. diff --git a/dom/serviceworkers/ServiceWorkerRegistrationImpl.cpp b/dom/serviceworkers/ServiceWorkerRegistrationImpl.cpp index d04e3c8fb1bf..a7d30242c293 100644 --- a/dom/serviceworkers/ServiceWorkerRegistrationImpl.cpp +++ b/dom/serviceworkers/ServiceWorkerRegistrationImpl.cpp @@ -66,50 +66,6 @@ ServiceWorkerRegistrationMainThread::~ServiceWorkerRegistrationMainThread() MOZ_ASSERT(!mListeningForEvents); } - -already_AddRefed -ServiceWorkerRegistrationMainThread::GetWorkerReference(WhichServiceWorker aWhichOne) -{ - nsCOMPtr window = GetOwner(); - if (!window) { - return nullptr; - } - - nsresult rv; - nsCOMPtr swm = - do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return nullptr; - } - - nsCOMPtr serviceWorker; - switch(aWhichOne) { - case WhichServiceWorker::INSTALLING_WORKER: - rv = swm->GetInstalling(window, mScope, getter_AddRefs(serviceWorker)); - break; - case WhichServiceWorker::WAITING_WORKER: - rv = swm->GetWaiting(window, mScope, getter_AddRefs(serviceWorker)); - break; - case WhichServiceWorker::ACTIVE_WORKER: - rv = swm->GetActive(window, mScope, getter_AddRefs(serviceWorker)); - break; - default: - MOZ_CRASH("Invalid enum value"); - } - - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rv) || rv == NS_ERROR_DOM_NOT_FOUND_ERR, - "Unexpected error getting service worker instance from " - "ServiceWorkerManager"); - if (NS_FAILED(rv)) { - return nullptr; - } - - RefPtr ref = - static_cast(serviceWorker.get()); - return ref.forget(); -} - // XXXnsm, maybe this can be optimized to only add when a event handler is // registered. void @@ -143,10 +99,6 @@ already_AddRefed ServiceWorkerRegistrationMainThread::GetInstalling() { MOZ_ASSERT(NS_IsMainThread()); - if (!mInstallingWorker) { - mInstallingWorker = GetWorkerReference(WhichServiceWorker::INSTALLING_WORKER); - } - RefPtr ret = mInstallingWorker; return ret.forget(); } @@ -155,10 +107,6 @@ already_AddRefed ServiceWorkerRegistrationMainThread::GetWaiting() { MOZ_ASSERT(NS_IsMainThread()); - if (!mWaitingWorker) { - mWaitingWorker = GetWorkerReference(WhichServiceWorker::WAITING_WORKER); - } - RefPtr ret = mWaitingWorker; return ret.forget(); } @@ -167,10 +115,6 @@ already_AddRefed ServiceWorkerRegistrationMainThread::GetActive() { MOZ_ASSERT(NS_IsMainThread()); - if (!mActiveWorker) { - mActiveWorker = GetWorkerReference(WhichServiceWorker::ACTIVE_WORKER); - } - RefPtr ret = mActiveWorker; return ret.forget(); } @@ -182,39 +126,36 @@ ServiceWorkerRegistrationMainThread::UpdateFound() } void -ServiceWorkerRegistrationMainThread::TransitionWorker(WhichServiceWorker aWhichOne) +ServiceWorkerRegistrationMainThread::UpdateState(const ServiceWorkerRegistrationDescriptor& aDescriptor) { - MOZ_ASSERT(NS_IsMainThread()); - - // We assert the worker's previous state because the 'statechange' - // event is dispatched in a queued runnable. - if (aWhichOne == WhichServiceWorker::INSTALLING_WORKER) { - MOZ_ASSERT_IF(mInstallingWorker, mInstallingWorker->State() == ServiceWorkerState::Installing); - mWaitingWorker = mInstallingWorker.forget(); - } else if (aWhichOne == WhichServiceWorker::WAITING_WORKER) { - MOZ_ASSERT_IF(mWaitingWorker, mWaitingWorker->State() == ServiceWorkerState::Installed); - mActiveWorker = mWaitingWorker.forget(); - } else { - MOZ_ASSERT_UNREACHABLE("Invalid transition!"); - } -} - -void -ServiceWorkerRegistrationMainThread::InvalidateWorkers(WhichServiceWorker aWhichOnes) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (aWhichOnes & WhichServiceWorker::INSTALLING_WORKER) { + nsCOMPtr global = GetParentObject(); + if (!global) { mInstallingWorker = nullptr; - } - - if (aWhichOnes & WhichServiceWorker::WAITING_WORKER) { mWaitingWorker = nullptr; + mActiveWorker = nullptr; + return; } - if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) { + Maybe active = aDescriptor.GetActive(); + if (active.isSome()) { + mActiveWorker = global->GetOrCreateServiceWorker(active.ref()); + } else { mActiveWorker = nullptr; } + Maybe waiting = aDescriptor.GetWaiting(); + if (waiting.isSome()) { + mWaitingWorker = global->GetOrCreateServiceWorker(waiting.ref()); + } else { + mWaitingWorker = nullptr; + } + + Maybe installing = aDescriptor.GetInstalling(); + if (installing.isSome()) { + mInstallingWorker = global->GetOrCreateServiceWorker(installing.ref()); + } else { + mInstallingWorker = nullptr; + } } void @@ -228,6 +169,13 @@ ServiceWorkerRegistrationMainThread::RegistrationRemoved() } } +bool +ServiceWorkerRegistrationMainThread::MatchesDescriptor(const ServiceWorkerRegistrationDescriptor& aDescriptor) +{ + NS_ConvertUTF16toUTF8 scope(mScope); + return aDescriptor.Scope() == scope; +} + namespace { void @@ -266,9 +214,19 @@ public: void UpdateSucceeded(ServiceWorkerRegistrationInfo* aRegistration) override { - if (RefPtr promise = mPromise.Get()) { - promise->MaybeResolveWithUndefined(); + RefPtr promise = mPromise.Get(); + nsCOMPtr win = mPromise.GetWindow(); + if (!promise || !win) { + return; } + + nsCOMPtr r = NS_NewRunnableFunction( + "MainThreadUpdateCallback::UpdateSucceeded", + [promise = Move(promise)] () { + promise->MaybeResolveWithUndefined(); + }); + MOZ_ALWAYS_SUCCEEDS( + win->EventTargetFor(TaskCategory::Other)->Dispatch(r.forget())); } void @@ -428,9 +386,19 @@ public: UnregisterSucceeded(bool aState) override { MOZ_ASSERT(NS_IsMainThread()); - if (RefPtr promise = mPromise.Get()) { - promise->MaybeResolve(aState); + RefPtr promise = mPromise.Get(); + nsCOMPtr win = mPromise.GetWindow(); + if (!promise || !win) { + return NS_OK; } + + nsCOMPtr r = NS_NewRunnableFunction( + "UnregisterCallback::UnregisterSucceeded", + [promise = Move(promise), aState] () { + promise->MaybeResolve(aState); + }); + MOZ_ALWAYS_SUCCEEDS( + win->EventTargetFor(TaskCategory::Other)->Dispatch(r.forget())); return NS_OK; } @@ -822,19 +790,12 @@ public: UpdateFound() override; void - TransitionWorker(WhichServiceWorker aWhichOne) override + UpdateState(const ServiceWorkerRegistrationDescriptor& aDescriptor) override { MOZ_ASSERT(NS_IsMainThread()); // TODO: Not implemented } - void - InvalidateWorkers(WhichServiceWorker aWhichOnes) override - { - MOZ_ASSERT(NS_IsMainThread()); - // FIXME(nsm); - } - void RegistrationRemoved() override { @@ -847,6 +808,13 @@ public: aScope = mScope; } + bool + MatchesDescriptor(const ServiceWorkerRegistrationDescriptor& aDescriptor) override + { + // TODO + return false; + } + ServiceWorkerRegistrationWorkerThread* GetRegistration() const { diff --git a/dom/serviceworkers/ServiceWorkerRegistrationImpl.h b/dom/serviceworkers/ServiceWorkerRegistrationImpl.h index f2083e574dfc..2f6e4fa0ab2b 100644 --- a/dom/serviceworkers/ServiceWorkerRegistrationImpl.h +++ b/dom/serviceworkers/ServiceWorkerRegistrationImpl.h @@ -76,10 +76,7 @@ public: UpdateFound() override; void - InvalidateWorkers(WhichServiceWorker aWhichOnes) override; - - void - TransitionWorker(WhichServiceWorker aWhichOne) override; + UpdateState(const ServiceWorkerRegistrationDescriptor& aDescriptor) override; void RegistrationRemoved() override; @@ -128,12 +125,12 @@ public: return static_cast(updateViaCache); } + bool + MatchesDescriptor(const ServiceWorkerRegistrationDescriptor& aDescriptor) override; + private: ~ServiceWorkerRegistrationMainThread(); - already_AddRefed - GetWorkerReference(WhichServiceWorker aWhichOne); - void StartListeningForEvents(); diff --git a/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp b/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp index 3cb5f1df2561..50a301f9958f 100644 --- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp +++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp @@ -52,34 +52,31 @@ ServiceWorkerRegistrationInfo::Clear() mEvaluatingWorker = nullptr; } - UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER | - WhichServiceWorker::WAITING_WORKER | - WhichServiceWorker::ACTIVE_WORKER, Invalidate); + RefPtr installing = mInstallingWorker.forget(); + RefPtr waiting = mWaitingWorker.forget(); + RefPtr active = mActiveWorker.forget(); - if (mInstallingWorker) { - mInstallingWorker->UpdateState(ServiceWorkerState::Redundant); - mInstallingWorker->UpdateRedundantTime(); - mInstallingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo(); - mInstallingWorker = nullptr; + UpdateRegistrationState(); + + if (installing) { + installing->UpdateState(ServiceWorkerState::Redundant); + installing->UpdateRedundantTime(); + installing->WorkerPrivate()->NoteDeadServiceWorkerInfo(); // FIXME(nsm): Abort any inflight requests from installing worker. } - if (mWaitingWorker) { - mWaitingWorker->UpdateState(ServiceWorkerState::Redundant); - mWaitingWorker->UpdateRedundantTime(); - mWaitingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo(); - mWaitingWorker = nullptr; + if (waiting) { + waiting->UpdateState(ServiceWorkerState::Redundant); + waiting->UpdateRedundantTime(); + waiting->WorkerPrivate()->NoteDeadServiceWorkerInfo(); } - if (mActiveWorker) { - mActiveWorker->UpdateState(ServiceWorkerState::Redundant); - mActiveWorker->UpdateRedundantTime(); - mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo(); - mActiveWorker = nullptr; + if (active) { + active->UpdateState(ServiceWorkerState::Redundant); + active->UpdateRedundantTime(); + active->WorkerPrivate()->NoteDeadServiceWorkerInfo(); } - mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker); - NotifyChromeRegistrationListeners(); } @@ -391,43 +388,22 @@ ServiceWorkerRegistrationInfo::IsLastUpdateCheckTimeOverOneDay() const } void -ServiceWorkerRegistrationInfo::AsyncUpdateRegistrationStateProperties(WhichServiceWorker aWorker, - TransitionType aTransition) -{ - MOZ_ASSERT(NS_IsMainThread()); - RefPtr swm = ServiceWorkerManager::GetInstance(); - if (!swm) { - // browser shutdown started during this async step - return; - } - - if (aTransition == Invalidate) { - swm->InvalidateServiceWorkerRegistrationWorker(this, aWorker); - } else { - MOZ_ASSERT(aTransition == TransitionToNextState); - swm->TransitionServiceWorkerRegistrationWorker(this, aWorker); - - if (aWorker == WhichServiceWorker::WAITING_WORKER) { - swm->CheckPendingReadyPromises(); - } - } -} - -void -ServiceWorkerRegistrationInfo::UpdateRegistrationStateProperties(WhichServiceWorker aWorker, - TransitionType aTransition) +ServiceWorkerRegistrationInfo::UpdateRegistrationState() { MOZ_ASSERT(NS_IsMainThread()); - nsCOMPtr runnable = - NewRunnableMethod( - "dom::ServiceWorkerRegistrationInfo::" - "AsyncUpdateRegistrationStateProperties", - this, - &ServiceWorkerRegistrationInfo::AsyncUpdateRegistrationStateProperties, - aWorker, - aTransition); - MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable.forget())); + mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker); + + RefPtr self(this); + nsCOMPtr r = NS_NewRunnableFunction( + "ServiceWorkerRegistrationInfo::UpdateRegistrationState", + [self = Move(self)] { + RefPtr swm = ServiceWorkerManager::GetInstance(); + if (swm) { + swm->UpdateRegistrationListeners(self); + } + }); + MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget())); } void @@ -570,13 +546,12 @@ ServiceWorkerRegistrationInfo::ClearInstalling() return; } - UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER, - Invalidate); - mInstallingWorker->UpdateState(ServiceWorkerState::Redundant); - mInstallingWorker->UpdateRedundantTime(); - mInstallingWorker = nullptr; + RefPtr installing = mInstallingWorker.forget(); - mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker); + UpdateRegistrationState(); + + installing->UpdateState(ServiceWorkerState::Redundant); + installing->UpdateRedundantTime(); NotifyChromeRegistrationListeners(); } @@ -589,9 +564,10 @@ ServiceWorkerRegistrationInfo::TransitionEvaluatingToInstalling() MOZ_ASSERT(!mInstallingWorker); mInstallingWorker = mEvaluatingWorker.forget(); - mInstallingWorker->UpdateState(ServiceWorkerState::Installing); - mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker); + UpdateRegistrationState(); + + mInstallingWorker->UpdateState(ServiceWorkerState::Installing); NotifyChromeRegistrationListeners(); } @@ -609,13 +585,12 @@ ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting() } mWaitingWorker = mInstallingWorker.forget(); - UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER, - TransitionToNextState); + + UpdateRegistrationState(); + mWaitingWorker->UpdateState(ServiceWorkerState::Installed); mWaitingWorker->UpdateInstalledTime(); - mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker); - NotifyChromeRegistrationListeners(); RefPtr swm = ServiceWorkerManager::GetInstance(); @@ -651,11 +626,10 @@ ServiceWorkerRegistrationInfo::SetActive(ServiceWorkerInfo* aServiceWorker) // Activated state. mActiveWorker = aServiceWorker; mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated); + // We don't need to update activated time when we load registration from // registrar. - UpdateRegistrationStateProperties(WhichServiceWorker::ACTIVE_WORKER, Invalidate); - - mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker); + UpdateRegistrationState(); NotifyChromeRegistrationListeners(); } @@ -675,11 +649,20 @@ ServiceWorkerRegistrationInfo::TransitionWaitingToActive() // We are transitioning from waiting to active normally, so go to // the activating state. mActiveWorker = mWaitingWorker.forget(); - UpdateRegistrationStateProperties(WhichServiceWorker::WAITING_WORKER, - TransitionToNextState); + + UpdateRegistrationState(); + mActiveWorker->UpdateState(ServiceWorkerState::Activating); - mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker); + nsCOMPtr r = + NS_NewRunnableFunction("ServiceWorkerRegistrationInfo::TransitionWaitingToActive", + [] { + RefPtr swm = ServiceWorkerManager::GetInstance(); + if (swm) { + swm->CheckPendingReadyPromises(); + } + }); + MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget())); NotifyChromeRegistrationListeners(); } diff --git a/dom/serviceworkers/ServiceWorkerRegistrationInfo.h b/dom/serviceworkers/ServiceWorkerRegistrationInfo.h index 02657a1daac1..705c176732d4 100644 --- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.h +++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.h @@ -8,7 +8,6 @@ #define mozilla_dom_serviceworkerregistrationinfo_h #include "mozilla/dom/ServiceWorkerInfo.h" -#include "mozilla/dom/ServiceWorkerCommon.h" #include "mozilla/dom/ServiceWorkerRegistrationBinding.h" #include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h" #include "nsProxyRelease.h" @@ -213,20 +212,11 @@ public: Descriptor() const; private: - enum TransitionType { - TransitionToNextState = 0, - Invalidate - }; - - // Queued as a runnable from UpdateRegistrationStateProperties. - void - AsyncUpdateRegistrationStateProperties(WhichServiceWorker aWorker, TransitionType aType); - // Roughly equivalent to [[Update Registration State algorithm]]. Make sure // this is called *before* updating SW instances' state, otherwise they // may get CC-ed. void - UpdateRegistrationStateProperties(WhichServiceWorker aWorker, TransitionType aType); + UpdateRegistrationState(); // Used by devtools to track changes to the properties of *nsIServiceWorkerRegistrationInfo*. // Note, this doesn't necessarily need to be in sync with the DOM registration objects, but diff --git a/dom/serviceworkers/ServiceWorkerRegistrationListener.h b/dom/serviceworkers/ServiceWorkerRegistrationListener.h index 360cad355806..b1ea8c0a8ad7 100644 --- a/dom/serviceworkers/ServiceWorkerRegistrationListener.h +++ b/dom/serviceworkers/ServiceWorkerRegistrationListener.h @@ -7,11 +7,11 @@ #ifndef mozilla_dom_ServiceWorkerRegistrationListener_h #define mozilla_dom_ServiceWorkerRegistrationListener_h -#include "mozilla/dom/ServiceWorkerCommon.h" - namespace mozilla { namespace dom { +class ServiceWorkerRegistrationDescriptor; + // Used by ServiceWorkerManager to notify ServiceWorkerRegistrations of // updatefound event and invalidating ServiceWorker instances. class ServiceWorkerRegistrationListener @@ -23,16 +23,16 @@ public: UpdateFound() = 0; virtual void - InvalidateWorkers(WhichServiceWorker aWhichOnes) = 0; - - virtual void - TransitionWorker(WhichServiceWorker aWhichOne) = 0; + UpdateState(const ServiceWorkerRegistrationDescriptor& aDescriptor) = 0; virtual void RegistrationRemoved() = 0; virtual void GetScope(nsAString& aScope) const = 0; + + virtual bool + MatchesDescriptor(const ServiceWorkerRegistrationDescriptor& aDescriptor) = 0; }; diff --git a/dom/serviceworkers/moz.build b/dom/serviceworkers/moz.build index 79a16913fcaa..33ee9e502673 100644 --- a/dom/serviceworkers/moz.build +++ b/dom/serviceworkers/moz.build @@ -10,7 +10,6 @@ with Files("**"): # Public stuff. EXPORTS.mozilla.dom += [ 'ServiceWorker.h', - 'ServiceWorkerCommon.h', 'ServiceWorkerContainer.h', 'ServiceWorkerDescriptor.h', 'ServiceWorkerEvents.h', diff --git a/testing/web-platform/meta/service-workers/service-worker/detached-context.https.html.ini b/testing/web-platform/meta/service-workers/service-worker/detached-context.https.html.ini index 0adb78c55d2a..fb1be61ccb04 100644 --- a/testing/web-platform/meta/service-workers/service-worker/detached-context.https.html.ini +++ b/testing/web-platform/meta/service-workers/service-worker/detached-context.https.html.ini @@ -1,7 +1,4 @@ [detached-context.https.html] - [accessing a ServiceWorkerRegistration from a removed iframe] - expected: FAIL - [accessing navigator on a removed frame] expected: FAIL