Bug 1434701 P6 Make ServiceWorkerRegistrationListener updates take a ServiceWorkerRegistrationDescriptor. r=asuth

This commit is contained in:
Ben Kelly 2018-02-14 14:23:16 -05:00
Родитель 010b72ac08
Коммит 3ebceab018
13 изменённых файлов: 142 добавлений и 370 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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

Просмотреть файл

@ -467,7 +467,14 @@ class ServiceWorkerResolveWindowPromiseOnRegisterCallback final : public Service
RefPtr<ServiceWorkerRegistration> swr =
window->GetServiceWorkerRegistration(reg->Descriptor());
nsCOMPtr<nsIRunnable> 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<nsIDocument> doc = aWindow->GetExtantDoc();
MOZ_ASSERT(doc);
///////////////////////////////////////////
// Security check
nsAutoCString scope = NS_ConvertUTF16toUTF8(aScope);
nsCOMPtr<nsIURI> 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<nsIPrincipal> 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<ServiceWorkerRegistrationInfo> registration =
GetRegistration(documentPrincipal, scope);
if (NS_WARN_IF(!registration)) {
return NS_ERROR_FAILURE;
}
RefPtr<ServiceWorkerInfo> 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> 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<ServiceWorkerRegistrationListener*>::ForwardIterator it(mServiceWorkerRegistrationListeners);
while (it.HasMore()) {
RefPtr<ServiceWorkerRegistrationListener> 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<ServiceWorkerRegistrationListener*>::ForwardIterator it(mServiceWorkerRegistrationListeners);
while (it.HasMore()) {
RefPtr<ServiceWorkerRegistrationListener> 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());
}
}
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -45,8 +45,9 @@ ServiceWorkerRegistration::CreateForMainThread(nsPIDOMWindowInner* aWindow,
NS_ConvertUTF8toUTF16 scope(aDescriptor.Scope());
RefPtr<ServiceWorkerRegistration> registration =
RefPtr<ServiceWorkerRegistrationMainThread> 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<ServiceWorkerRegistration> registration =
RefPtr<ServiceWorkerRegistrationWorkerThread> registration =
new ServiceWorkerRegistrationWorkerThread(aWorkerPrivate, scope);
return registration.forget();

Просмотреть файл

@ -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.

Просмотреть файл

@ -66,50 +66,6 @@ ServiceWorkerRegistrationMainThread::~ServiceWorkerRegistrationMainThread()
MOZ_ASSERT(!mListeningForEvents);
}
already_AddRefed<ServiceWorker>
ServiceWorkerRegistrationMainThread::GetWorkerReference(WhichServiceWorker aWhichOne)
{
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
if (!window) {
return nullptr;
}
nsresult rv;
nsCOMPtr<nsIServiceWorkerManager> swm =
do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
nsCOMPtr<nsISupports> 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<ServiceWorker> ref =
static_cast<ServiceWorker*>(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<ServiceWorker>
ServiceWorkerRegistrationMainThread::GetInstalling()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mInstallingWorker) {
mInstallingWorker = GetWorkerReference(WhichServiceWorker::INSTALLING_WORKER);
}
RefPtr<ServiceWorker> ret = mInstallingWorker;
return ret.forget();
}
@ -155,10 +107,6 @@ already_AddRefed<ServiceWorker>
ServiceWorkerRegistrationMainThread::GetWaiting()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mWaitingWorker) {
mWaitingWorker = GetWorkerReference(WhichServiceWorker::WAITING_WORKER);
}
RefPtr<ServiceWorker> ret = mWaitingWorker;
return ret.forget();
}
@ -167,10 +115,6 @@ already_AddRefed<ServiceWorker>
ServiceWorkerRegistrationMainThread::GetActive()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mActiveWorker) {
mActiveWorker = GetWorkerReference(WhichServiceWorker::ACTIVE_WORKER);
}
RefPtr<ServiceWorker> 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<nsIGlobalObject> global = GetParentObject();
if (!global) {
mInstallingWorker = nullptr;
}
if (aWhichOnes & WhichServiceWorker::WAITING_WORKER) {
mWaitingWorker = nullptr;
mActiveWorker = nullptr;
return;
}
if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) {
Maybe<ServiceWorkerDescriptor> active = aDescriptor.GetActive();
if (active.isSome()) {
mActiveWorker = global->GetOrCreateServiceWorker(active.ref());
} else {
mActiveWorker = nullptr;
}
Maybe<ServiceWorkerDescriptor> waiting = aDescriptor.GetWaiting();
if (waiting.isSome()) {
mWaitingWorker = global->GetOrCreateServiceWorker(waiting.ref());
} else {
mWaitingWorker = nullptr;
}
Maybe<ServiceWorkerDescriptor> 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> promise = mPromise.Get()) {
promise->MaybeResolveWithUndefined();
RefPtr<Promise> promise = mPromise.Get();
nsCOMPtr<nsPIDOMWindowInner> win = mPromise.GetWindow();
if (!promise || !win) {
return;
}
nsCOMPtr<nsIRunnable> 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> promise = mPromise.Get()) {
promise->MaybeResolve(aState);
RefPtr<Promise> promise = mPromise.Get();
nsCOMPtr<nsPIDOMWindowInner> win = mPromise.GetWindow();
if (!promise || !win) {
return NS_OK;
}
nsCOMPtr<nsIRunnable> 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
{

Просмотреть файл

@ -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<ServiceWorkerUpdateViaCache>(updateViaCache);
}
bool
MatchesDescriptor(const ServiceWorkerRegistrationDescriptor& aDescriptor) override;
private:
~ServiceWorkerRegistrationMainThread();
already_AddRefed<ServiceWorker>
GetWorkerReference(WhichServiceWorker aWhichOne);
void
StartListeningForEvents();

Просмотреть файл

@ -52,34 +52,31 @@ ServiceWorkerRegistrationInfo::Clear()
mEvaluatingWorker = nullptr;
}
UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER |
WhichServiceWorker::WAITING_WORKER |
WhichServiceWorker::ACTIVE_WORKER, Invalidate);
RefPtr<ServiceWorkerInfo> installing = mInstallingWorker.forget();
RefPtr<ServiceWorkerInfo> waiting = mWaitingWorker.forget();
RefPtr<ServiceWorkerInfo> 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)
ServiceWorkerRegistrationInfo::UpdateRegistrationState()
{
MOZ_ASSERT(NS_IsMainThread());
mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
RefPtr<ServiceWorkerRegistrationInfo> self(this);
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
"ServiceWorkerRegistrationInfo::UpdateRegistrationState",
[self = Move(self)] {
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (!swm) {
// browser shutdown started during this async step
return;
if (swm) {
swm->UpdateRegistrationListeners(self);
}
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)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> runnable =
NewRunnableMethod<WhichServiceWorker, TransitionType>(
"dom::ServiceWorkerRegistrationInfo::"
"AsyncUpdateRegistrationStateProperties",
this,
&ServiceWorkerRegistrationInfo::AsyncUpdateRegistrationStateProperties,
aWorker,
aTransition);
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable.forget()));
});
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<ServiceWorkerInfo> 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<ServiceWorkerManager> 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<nsIRunnable> r =
NS_NewRunnableFunction("ServiceWorkerRegistrationInfo::TransitionWaitingToActive",
[] {
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (swm) {
swm->CheckPendingReadyPromises();
}
});
MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
NotifyChromeRegistrationListeners();
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -10,7 +10,6 @@ with Files("**"):
# Public stuff.
EXPORTS.mozilla.dom += [
'ServiceWorker.h',
'ServiceWorkerCommon.h',
'ServiceWorkerContainer.h',
'ServiceWorkerDescriptor.h',
'ServiceWorkerEvents.h',

Просмотреть файл

@ -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