Bug 1715547 - Remove ServiceWorkerRegistration::Inner r=asuth

Differential Revision: https://phabricator.services.mozilla.com/D117344
This commit is contained in:
Eden Chuang 2022-09-29 18:25:59 +00:00
Родитель 166ef2beaa
Коммит eb9c853d1f
10 изменённых файлов: 228 добавлений и 404 удалений

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

@ -23,7 +23,8 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(NavigationPreloadManager)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(NavigationPreloadManager, mGlobal)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(NavigationPreloadManager,
mServiceWorkerRegistration)
/* static */
bool NavigationPreloadManager::IsValidHeader(const nsACString& aHeader) {
@ -36,9 +37,8 @@ bool NavigationPreloadManager::IsEnabled(JSContext* aCx, JSObject* aGlobal) {
}
NavigationPreloadManager::NavigationPreloadManager(
nsCOMPtr<nsIGlobalObject>&& aGlobal,
RefPtr<ServiceWorkerRegistration::Inner>& aInner)
: mGlobal(aGlobal), mInner(aInner) {}
RefPtr<ServiceWorkerRegistration>& aServiceWorkerRegistration)
: mServiceWorkerRegistration(aServiceWorkerRegistration) {}
JSObject* NavigationPreloadManager::WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
@ -53,12 +53,12 @@ already_AddRefed<Promise> NavigationPreloadManager::SetEnabled(
return nullptr;
}
if (!mInner) {
if (!mServiceWorkerRegistration) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
mInner->SetNavigationPreloadEnabled(
mServiceWorkerRegistration->SetNavigationPreloadEnabled(
aEnabled,
[promise](bool aSuccess) {
if (aSuccess) {
@ -95,12 +95,12 @@ already_AddRefed<Promise> NavigationPreloadManager::SetHeaderValue(
return promise.forget();
}
if (!mInner) {
if (!mServiceWorkerRegistration) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
mInner->SetNavigationPreloadHeader(
mServiceWorkerRegistration->SetNavigationPreloadHeader(
nsAutoCString(aHeader),
[promise](bool aSuccess) {
if (aSuccess) {
@ -122,12 +122,12 @@ already_AddRefed<Promise> NavigationPreloadManager::GetState(
return nullptr;
}
if (!mInner) {
if (!mServiceWorkerRegistration) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
mInner->GetNavigationPreloadState(
mServiceWorkerRegistration->GetNavigationPreloadState(
[promise](NavigationPreloadState&& aState) {
promise->MaybeResolve(std::move(aState));
},

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

@ -30,11 +30,13 @@ class NavigationPreloadManager final : public nsISupports,
static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
NavigationPreloadManager(nsCOMPtr<nsIGlobalObject>&& aGlobal,
RefPtr<ServiceWorkerRegistration::Inner>& aInner);
explicit NavigationPreloadManager(
RefPtr<ServiceWorkerRegistration>& aServiceWorkerRegistration);
// Webidl binding
nsIGlobalObject* GetParentObject() const { return mGlobal; }
nsIGlobalObject* GetParentObject() const {
return mServiceWorkerRegistration->GetParentObject();
}
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
@ -55,8 +57,7 @@ class NavigationPreloadManager final : public nsISupports,
// General method for Enable()/Disable()
already_AddRefed<Promise> SetEnabled(bool aEnabled, ErrorResult& aError);
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ServiceWorkerRegistration::Inner> mInner;
RefPtr<ServiceWorkerRegistration> mServiceWorkerRegistration;
};
} // namespace mozilla::dom

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

@ -1,240 +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/. */
#include "RemoteServiceWorkerRegistrationImpl.h"
#include "ServiceWorkerRegistrationChild.h"
#include "mozilla/dom/NavigationPreloadManagerBinding.h"
#include "mozilla/ipc/MessageChannel.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/ipc/BackgroundChild.h"
namespace mozilla::dom {
using mozilla::ipc::IPCResult;
using mozilla::ipc::ResponseRejectReason;
RemoteServiceWorkerRegistrationImpl::~RemoteServiceWorkerRegistrationImpl() {
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
Shutdown();
}
void RemoteServiceWorkerRegistrationImpl::Shutdown() {
if (mShutdown) {
return;
}
mShutdown = true;
if (mActor) {
mActor->RevokeOwner(this);
mActor->MaybeStartTeardown();
mActor = nullptr;
}
}
void RemoteServiceWorkerRegistrationImpl::SetServiceWorkerRegistration(
ServiceWorkerRegistration* aReg) {
NS_ASSERT_OWNINGTHREAD(RemoteServiceWorkerRegistrationImpl);
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
MOZ_DIAGNOSTIC_ASSERT(aReg);
mOuter = aReg;
}
void RemoteServiceWorkerRegistrationImpl::ClearServiceWorkerRegistration(
ServiceWorkerRegistration* aReg) {
NS_ASSERT_OWNINGTHREAD(RemoteServiceWorkerRegistrationImpl);
MOZ_DIAGNOSTIC_ASSERT(mOuter);
MOZ_DIAGNOSTIC_ASSERT(aReg == mOuter);
mOuter = nullptr;
}
void RemoteServiceWorkerRegistrationImpl::Update(
const nsCString& aNewestWorkerScriptUrl,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendUpdate(
aNewestWorkerScriptUrl,
[successCB = std::move(aSuccessCB), aFailureCB](
const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
auto& rv = aResult.get_CopyableErrorResult();
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
aFailureCB(CopyableErrorResult(rv));
return;
}
// success
auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
},
[aFailureCB](ResponseRejectReason&& aReason) {
// IPC layer error
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void RemoteServiceWorkerRegistrationImpl::Unregister(
ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendUnregister(
[successCB = std::move(aSuccessCB),
aFailureCB](Tuple<bool, CopyableErrorResult>&& aResult) {
if (Get<1>(aResult).Failed()) {
// application layer error
aFailureCB(std::move(Get<1>(aResult)));
return;
}
// success
successCB(Get<0>(aResult));
},
[aFailureCB](ResponseRejectReason&& aReason) {
// IPC layer error
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void RemoteServiceWorkerRegistrationImpl::SetNavigationPreloadEnabled(
bool aEnabled, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendSetNavigationPreloadEnabled(
aEnabled,
[successCB = std::move(aSuccessCB), aFailureCB](bool aResult) {
if (!aResult) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
successCB(aResult);
},
[aFailureCB](ResponseRejectReason&& aReason) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void RemoteServiceWorkerRegistrationImpl::SetNavigationPreloadHeader(
const nsCString& aHeader, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendSetNavigationPreloadHeader(
aHeader,
[successCB = std::move(aSuccessCB), aFailureCB](bool aResult) {
if (!aResult) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
successCB(aResult);
},
[aFailureCB](ResponseRejectReason&& aReason) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void RemoteServiceWorkerRegistrationImpl::GetNavigationPreloadState(
NavigationPreloadGetStateCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendGetNavigationPreloadState(
[successCB = std::move(aSuccessCB),
aFailureCB](Maybe<IPCNavigationPreloadState>&& aState) {
if (NS_WARN_IF(!aState)) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
NavigationPreloadState state;
state.mEnabled = aState.ref().enabled();
state.mHeaderValue.Construct(std::move(aState.ref().headerValue()));
successCB(std::move(state));
},
[aFailureCB](ResponseRejectReason&& aReason) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
RemoteServiceWorkerRegistrationImpl::RemoteServiceWorkerRegistrationImpl(
const ServiceWorkerRegistrationDescriptor& aDescriptor)
: mOuter(nullptr), mShutdown(false) {
::mozilla::ipc::PBackgroundChild* parentActor =
::mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!parentActor)) {
Shutdown();
return;
}
auto actor = ServiceWorkerRegistrationChild::Create();
if (NS_WARN_IF(!actor)) {
Shutdown();
return;
}
PServiceWorkerRegistrationChild* sentActor =
parentActor->SendPServiceWorkerRegistrationConstructor(
actor, aDescriptor.ToIPC());
if (NS_WARN_IF(!sentActor)) {
Shutdown();
return;
}
MOZ_DIAGNOSTIC_ASSERT(sentActor == actor);
mActor = std::move(actor);
mActor->SetOwner(this);
}
void RemoteServiceWorkerRegistrationImpl::RevokeActor(
ServiceWorkerRegistrationChild* aActor) {
MOZ_DIAGNOSTIC_ASSERT(mActor);
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
mActor->RevokeOwner(this);
mActor = nullptr;
mShutdown = true;
if (mOuter) {
RefPtr<ServiceWorkerRegistration> outer = mOuter;
outer->RegistrationCleared();
}
}
void RemoteServiceWorkerRegistrationImpl::UpdateState(
const ServiceWorkerRegistrationDescriptor& aDescriptor) {
if (mOuter) {
RefPtr<ServiceWorkerRegistration> outer = mOuter;
outer->UpdateState(aDescriptor);
}
}
void RemoteServiceWorkerRegistrationImpl::FireUpdateFound() {
if (mOuter) {
mOuter->MaybeDispatchUpdateFoundRunnable();
}
}
} // namespace mozilla::dom

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

@ -1,65 +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_remoteserviceworkerregistrationimpl_h__
#define mozilla_dom_remoteserviceworkerregistrationimpl_h__
#include "ServiceWorkerRegistration.h"
namespace mozilla::dom {
class ServiceWorkerRegistrationChild;
class RemoteServiceWorkerRegistrationImpl final
: public ServiceWorkerRegistration::Inner {
RefPtr<ServiceWorkerRegistrationChild> mActor;
ServiceWorkerRegistration* mOuter;
bool mShutdown;
~RemoteServiceWorkerRegistrationImpl();
void Shutdown();
// ServiceWorkerRegistration::Inner implementation
void SetServiceWorkerRegistration(ServiceWorkerRegistration* aReg) override;
void ClearServiceWorkerRegistration(ServiceWorkerRegistration* aReg) override;
void Update(const nsCString& aNewestWorkerScriptUrl,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) override;
void Unregister(ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) override;
void SetNavigationPreloadEnabled(
bool aEnabled, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) override;
void SetNavigationPreloadHeader(
const nsCString& aHeader, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) override;
void GetNavigationPreloadState(
NavigationPreloadGetStateCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) override;
public:
explicit RemoteServiceWorkerRegistrationImpl(
const ServiceWorkerRegistrationDescriptor& aDescriptor);
void RevokeActor(ServiceWorkerRegistrationChild* aActor);
void UpdateState(const ServiceWorkerRegistrationDescriptor& aDescriptor);
void FireUpdateFound();
NS_INLINE_DECL_REFCOUNTING(RemoteServiceWorkerRegistrationImpl, override)
};
} // namespace mozilla::dom
#endif // mozilla_dom_remoteserviceworkerregistrationimpl_h__

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

@ -226,10 +226,10 @@ class BodyCopyHandle final : public nsIInterceptedBodyCallback {
nsCOMPtr<nsIRunnable> event;
if (NS_WARN_IF(NS_FAILED(aRv))) {
AsyncLog(mClosure->mInterceptedChannel, mClosure->mRespondWithScriptSpec,
mClosure->mRespondWithLineNumber,
mClosure->mRespondWithColumnNumber,
"InterceptionFailedWithURL"_ns, mClosure->mRequestURL);
::AsyncLog(
mClosure->mInterceptedChannel, mClosure->mRespondWithScriptSpec,
mClosure->mRespondWithLineNumber, mClosure->mRespondWithColumnNumber,
"InterceptionFailedWithURL"_ns, mClosure->mRequestURL);
event = new CancelChannelRunnable(mClosure->mInterceptedChannel,
mClosure->mRegistration,
NS_ERROR_INTERCEPTION_FAILED);

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

@ -8,6 +8,7 @@
#include "mozilla/dom/DOMMozPromiseRequestHolder.h"
#include "mozilla/dom/NavigationPreloadManager.h"
#include "mozilla/dom/NavigationPreloadManagerBinding.h"
#include "mozilla/dom/Notification.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PushManager.h"
@ -16,10 +17,14 @@
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
#include "mozilla/dom/ServiceWorkerUtils.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ScopeExit.h"
#include "nsCycleCollectionParticipant.h"
#include "nsPIDOMWindow.h"
#include "RemoteServiceWorkerRegistrationImpl.h"
#include "ServiceWorkerRegistrationChild.h"
using mozilla::ipc::ResponseRejectReason;
namespace mozilla::dom {
@ -41,23 +46,41 @@ const uint64_t kInvalidUpdateFoundId = 0;
ServiceWorkerRegistration::ServiceWorkerRegistration(
nsIGlobalObject* aGlobal,
const ServiceWorkerRegistrationDescriptor& aDescriptor,
ServiceWorkerRegistration::Inner* aInner)
const ServiceWorkerRegistrationDescriptor& aDescriptor)
: DOMEventTargetHelper(aGlobal),
mDescriptor(aDescriptor),
mInner(aInner),
mShutdown(false),
mScheduledUpdateFoundId(kInvalidUpdateFoundId),
mDispatchedUpdateFoundId(kInvalidUpdateFoundId) {
MOZ_DIAGNOSTIC_ASSERT(mInner);
::mozilla::ipc::PBackgroundChild* parentActor =
::mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!parentActor)) {
Shutdown();
return;
}
auto actor = ServiceWorkerRegistrationChild::Create();
if (NS_WARN_IF(!actor)) {
Shutdown();
return;
}
PServiceWorkerRegistrationChild* sentActor =
parentActor->SendPServiceWorkerRegistrationConstructor(
actor, aDescriptor.ToIPC());
if (NS_WARN_IF(!sentActor)) {
Shutdown();
return;
}
MOZ_DIAGNOSTIC_ASSERT(sentActor == actor);
mActor = std::move(actor);
mActor->SetOwner(this);
KeepAliveIfHasListenersFor(nsGkAtoms::onupdatefound);
mInner->SetServiceWorkerRegistration(this);
}
ServiceWorkerRegistration::~ServiceWorkerRegistration() {
mInner->ClearServiceWorkerRegistration(this);
}
ServiceWorkerRegistration::~ServiceWorkerRegistration() { Shutdown(); }
JSObject* ServiceWorkerRegistration::WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
@ -72,11 +95,8 @@ ServiceWorkerRegistration::CreateForMainThread(
MOZ_ASSERT(aWindow);
MOZ_ASSERT(NS_IsMainThread());
const RefPtr<Inner> inner =
new RemoteServiceWorkerRegistrationImpl(aDescriptor);
RefPtr<ServiceWorkerRegistration> registration =
new ServiceWorkerRegistration(aWindow->AsGlobal(), aDescriptor, inner);
new ServiceWorkerRegistration(aWindow->AsGlobal(), aDescriptor);
// This is not called from within the constructor, as it may call content code
// which can cause the deletion of the registration, so we need to keep a
// strong reference while calling it.
@ -94,11 +114,8 @@ ServiceWorkerRegistration::CreateForWorker(
MOZ_DIAGNOSTIC_ASSERT(aGlobal);
aWorkerPrivate->AssertIsOnWorkerThread();
const RefPtr<Inner> inner =
new RemoteServiceWorkerRegistrationImpl(aDescriptor);
RefPtr<ServiceWorkerRegistration> registration =
new ServiceWorkerRegistration(aGlobal, aDescriptor, inner);
new ServiceWorkerRegistration(aGlobal, aDescriptor);
// This is not called from within the constructor, as it may call content code
// which can cause the deletion of the registration, so we need to keep a
// strong reference while calling it.
@ -146,9 +163,9 @@ already_AddRefed<ServiceWorker> ServiceWorkerRegistration::GetActive() const {
already_AddRefed<NavigationPreloadManager>
ServiceWorkerRegistration::NavigationPreload() {
RefPtr<ServiceWorkerRegistration> reg = this;
if (!mNavigationPreloadManager) {
mNavigationPreloadManager =
MakeRefPtr<NavigationPreloadManager>(GetParentObject(), mInner);
mNavigationPreloadManager = MakeRefPtr<NavigationPreloadManager>(reg);
}
RefPtr<NavigationPreloadManager> ref = mNavigationPreloadManager;
return ref.forget();
@ -192,11 +209,6 @@ ServiceWorkerUpdateViaCache ServiceWorkerRegistration::GetUpdateViaCache(
}
already_AddRefed<Promise> ServiceWorkerRegistration::Update(ErrorResult& aRv) {
if (!mInner) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
nsIGlobalObject* global = GetParentObject();
if (!global) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
@ -238,9 +250,28 @@ already_AddRefed<Promise> ServiceWorkerRegistration::Update(ErrorResult& aRv) {
RefPtr<ServiceWorkerRegistration> self = this;
mInner->Update(
if (!mActor) {
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return outer.forget();
}
mActor->SendUpdate(
newestWorkerDescriptor.ref().ScriptURL(),
[outer, self](const ServiceWorkerRegistrationDescriptor& aDesc) {
[outer,
self](const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
const auto& rv = aResult.get_CopyableErrorResult();
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
outer->MaybeReject(CopyableErrorResult(rv));
return;
}
// success
const auto& ipcDesc =
aResult.get_IPCServiceWorkerRegistrationDescriptor();
nsIGlobalObject* global = self->GetParentObject();
// It's possible this binding was detached from the global. In cases
// where we use IPC with Promise callbacks, we use
@ -262,14 +293,18 @@ already_AddRefed<Promise> ServiceWorkerRegistration::Update(ErrorResult& aRv) {
return;
}
RefPtr<ServiceWorkerRegistration> ref =
global->GetOrCreateServiceWorkerRegistration(aDesc);
global->GetOrCreateServiceWorkerRegistration(
ServiceWorkerRegistrationDescriptor(ipcDesc));
if (!ref) {
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
outer->MaybeResolve(ref);
},
[outer, self](ErrorResult&& aRv) { outer->MaybeReject(std::move(aRv)); });
[outer](ResponseRejectReason&& aReason) {
// IPC layer error
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
});
return outer.forget();
}
@ -287,18 +322,28 @@ already_AddRefed<Promise> ServiceWorkerRegistration::Unregister(
return nullptr;
}
if (!mInner) {
if (!mActor) {
outer->MaybeResolve(false);
return outer.forget();
}
mInner->Unregister([outer](bool aSuccess) { outer->MaybeResolve(aSuccess); },
[outer](ErrorResult&& aRv) {
// register() should be resilient and resolve false
// instead of rejecting in most cases.
aRv.SuppressException();
outer->MaybeResolve(false);
});
mActor->SendUnregister(
[outer](Tuple<bool, CopyableErrorResult>&& aResult) {
if (Get<1>(aResult).Failed()) {
// application layer error
// register() should be resilient and resolve false instead of
// rejecting in most cases.
Get<1>(aResult).SuppressException();
outer->MaybeResolve(false);
return;
}
// success
outer->MaybeResolve(Get<0>(aResult));
},
[outer](ResponseRejectReason&& aReason) {
// IPC layer error
outer->MaybeResolve(false);
});
return outer.forget();
}
@ -377,6 +422,76 @@ already_AddRefed<Promise> ServiceWorkerRegistration::GetNotifications(
return Notification::WorkerGet(worker, aOptions, scope, aRv);
}
void ServiceWorkerRegistration::SetNavigationPreloadEnabled(
bool aEnabled, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendSetNavigationPreloadEnabled(
aEnabled,
[successCB = std::move(aSuccessCB), aFailureCB](bool aResult) {
if (!aResult) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
successCB(aResult);
},
[aFailureCB](ResponseRejectReason&& aReason) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void ServiceWorkerRegistration::SetNavigationPreloadHeader(
const nsCString& aHeader, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendSetNavigationPreloadHeader(
aHeader,
[successCB = std::move(aSuccessCB), aFailureCB](bool aResult) {
if (!aResult) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
successCB(aResult);
},
[aFailureCB](ResponseRejectReason&& aReason) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void ServiceWorkerRegistration::GetNavigationPreloadState(
NavigationPreloadGetStateCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendGetNavigationPreloadState(
[successCB = std::move(aSuccessCB),
aFailureCB](Maybe<IPCNavigationPreloadState>&& aState) {
if (NS_WARN_IF(!aState)) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
NavigationPreloadState state;
state.mEnabled = aState.ref().enabled();
state.mHeaderValue.Construct(std::move(aState.ref().headerValue()));
successCB(std::move(state));
},
[aFailureCB](ResponseRejectReason&& aReason) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
const ServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistration::Descriptor() const {
return mDescriptor;
@ -545,4 +660,29 @@ void ServiceWorkerRegistration::UpdateStateInternal(
}
}
void ServiceWorkerRegistration::RevokeActor(
ServiceWorkerRegistrationChild* aActor) {
MOZ_DIAGNOSTIC_ASSERT(mActor);
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
mActor->RevokeOwner(this);
mActor = nullptr;
mShutdown = true;
RegistrationCleared();
}
void ServiceWorkerRegistration::Shutdown() {
if (mShutdown) {
return;
}
mShutdown = true;
if (mActor) {
mActor->RevokeOwner(this);
mActor->MaybeStartTeardown();
mActor = nullptr;
}
}
} // namespace mozilla::dom

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

@ -25,6 +25,7 @@ class Promise;
class PushManager;
class WorkerPrivate;
class ServiceWorker;
class ServiceWorkerRegistrationChild;
#define NS_DOM_SERVICEWORKERREGISTRATION_IID \
{ \
@ -35,37 +36,6 @@ class ServiceWorker;
class ServiceWorkerRegistration final : public DOMEventTargetHelper {
public:
class Inner {
public:
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
virtual void SetServiceWorkerRegistration(
ServiceWorkerRegistration* aReg) = 0;
virtual void ClearServiceWorkerRegistration(
ServiceWorkerRegistration* aReg) = 0;
virtual void Update(const nsCString& aNewestWorkerScriptUrl,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) = 0;
virtual void Unregister(ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) = 0;
// Interface for NavigationPreload
virtual void SetNavigationPreloadEnabled(
bool aEnabled, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) = 0;
virtual void SetNavigationPreloadHeader(
const nsCString& aHeader, ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) = 0;
virtual void GetNavigationPreloadState(
NavigationPreloadGetStateCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) = 0;
};
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKERREGISTRATION_IID)
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistration,
@ -119,6 +89,17 @@ class ServiceWorkerRegistration final : public DOMEventTargetHelper {
already_AddRefed<Promise> GetNotifications(
const GetNotificationOptions& aOptions, ErrorResult& aRv);
void SetNavigationPreloadEnabled(bool aEnabled,
ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB);
void SetNavigationPreloadHeader(const nsCString& aHeader,
ServiceWorkerBoolCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB);
void GetNavigationPreloadState(NavigationPreloadGetStateCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB);
const ServiceWorkerRegistrationDescriptor& Descriptor() const;
void WhenVersionReached(uint64_t aVersion,
@ -126,10 +107,14 @@ class ServiceWorkerRegistration final : public DOMEventTargetHelper {
void MaybeDispatchUpdateFoundRunnable();
void RevokeActor(ServiceWorkerRegistrationChild* aActor);
void FireUpdateFound();
private:
ServiceWorkerRegistration(
nsIGlobalObject* aGlobal,
const ServiceWorkerRegistrationDescriptor& aDescriptor, Inner* aInner);
const ServiceWorkerRegistrationDescriptor& aDescriptor);
~ServiceWorkerRegistration();
@ -142,8 +127,11 @@ class ServiceWorkerRegistration final : public DOMEventTargetHelper {
void MaybeDispatchUpdateFound();
void Shutdown();
ServiceWorkerRegistrationDescriptor mDescriptor;
RefPtr<Inner> mInner;
RefPtr<ServiceWorkerRegistrationChild> mActor;
bool mShutdown;
RefPtr<ServiceWorker> mInstallingWorker;
RefPtr<ServiceWorker> mWaitingWorker;

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

@ -6,7 +6,7 @@
#include "ServiceWorkerRegistrationChild.h"
#include "RemoteServiceWorkerRegistrationImpl.h"
#include "ServiceWorkerRegistration.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/WorkerRef.h"
@ -26,14 +26,15 @@ void ServiceWorkerRegistrationChild::ActorDestroy(ActorDestroyReason aReason) {
IPCResult ServiceWorkerRegistrationChild::RecvUpdateState(
const IPCServiceWorkerRegistrationDescriptor& aDescriptor) {
if (mOwner) {
mOwner->UpdateState(ServiceWorkerRegistrationDescriptor(aDescriptor));
RefPtr<ServiceWorkerRegistration> owner = mOwner;
owner->UpdateState(ServiceWorkerRegistrationDescriptor(aDescriptor));
}
return IPC_OK();
}
IPCResult ServiceWorkerRegistrationChild::RecvFireUpdateFound() {
if (mOwner) {
mOwner->FireUpdateFound();
mOwner->MaybeDispatchUpdateFoundRunnable();
}
return IPC_OK();
}
@ -66,14 +67,14 @@ ServiceWorkerRegistrationChild::ServiceWorkerRegistrationChild()
: mOwner(nullptr), mTeardownStarted(false) {}
void ServiceWorkerRegistrationChild::SetOwner(
RemoteServiceWorkerRegistrationImpl* aOwner) {
ServiceWorkerRegistration* aOwner) {
MOZ_DIAGNOSTIC_ASSERT(!mOwner);
MOZ_DIAGNOSTIC_ASSERT(aOwner);
mOwner = aOwner;
}
void ServiceWorkerRegistrationChild::RevokeOwner(
RemoteServiceWorkerRegistrationImpl* aOwner) {
ServiceWorkerRegistration* aOwner) {
MOZ_DIAGNOSTIC_ASSERT(mOwner);
MOZ_DIAGNOSTIC_ASSERT(aOwner == mOwner);
mOwner = nullptr;

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

@ -15,12 +15,12 @@
namespace mozilla::dom {
class IPCWorkerRef;
class RemoteServiceWorkerRegistrationImpl;
class ServiceWorkerRegistration;
class ServiceWorkerRegistrationChild final
: public PServiceWorkerRegistrationChild {
RefPtr<IPCWorkerRef> mIPCWorkerRef;
RemoteServiceWorkerRegistrationImpl* mOwner;
ServiceWorkerRegistration* mOwner;
bool mTeardownStarted;
ServiceWorkerRegistrationChild();
@ -40,9 +40,9 @@ class ServiceWorkerRegistrationChild final
static RefPtr<ServiceWorkerRegistrationChild> Create();
void SetOwner(RemoteServiceWorkerRegistrationImpl* aOwner);
void SetOwner(ServiceWorkerRegistration* aOwner);
void RevokeOwner(RemoteServiceWorkerRegistrationImpl* aOwner);
void RevokeOwner(ServiceWorkerRegistration* aOwner);
void MaybeStartTeardown();
};

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

@ -50,7 +50,6 @@ UNIFIED_SOURCES += [
"NavigationPreloadManager.cpp",
"RemoteServiceWorkerContainerImpl.cpp",
"RemoteServiceWorkerImpl.cpp",
"RemoteServiceWorkerRegistrationImpl.cpp",
"ServiceWorker.cpp",
"ServiceWorkerActors.cpp",
"ServiceWorkerChild.cpp",