Bug 1462772 P3 Make ServiceWorker binding objects get or create a handle to their associated registration. r=mrbkap

This commit is contained in:
Ben Kelly 2018-07-02 07:44:18 -07:00
Родитель 4866ecedf2
Коммит f3b6e1d527
4 изменённых файлов: 99 добавлений и 3 удалений

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

@ -63,7 +63,7 @@ ServiceWorker::Create(nsIGlobalObject* aOwner,
return ref.forget(); return ref.forget();
} }
RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info); RefPtr<ServiceWorker::Inner> inner = new ServiceWorkerImpl(info, reg);
ref = new ServiceWorker(aOwner, aDescriptor, inner); ref = new ServiceWorker(aOwner, aDescriptor, inner);
return ref.forget(); return ref.forget();
} }
@ -86,6 +86,31 @@ ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
// This will update our state too. // This will update our state too.
mInner->AddServiceWorker(this); mInner->AddServiceWorker(this);
// Attempt to get an existing binding object for the registration
// associated with this ServiceWorker.
RefPtr<ServiceWorkerRegistration> reg = aGlobal->GetServiceWorkerRegistration(
ServiceWorkerRegistrationDescriptor(mDescriptor.RegistrationId(),
mDescriptor.PrincipalInfo(),
mDescriptor.Scope(),
ServiceWorkerUpdateViaCache::Imports));
if (reg) {
MaybeAttachToRegistration(reg);
} else {
RefPtr<ServiceWorker> self = this;
mInner->GetRegistration(
[self = std::move(self)] (const ServiceWorkerRegistrationDescriptor& aDescriptor) {
nsIGlobalObject* global = self->GetParentObject();
NS_ENSURE_TRUE_VOID(global);
RefPtr<ServiceWorkerRegistration> reg =
global->GetOrCreateServiceWorkerRegistration(aDescriptor);
self->MaybeAttachToRegistration(reg);
}, [] (ErrorResult& aRv) {
// do nothing
aRv.SuppressException();
});
}
} }
ServiceWorker::~ServiceWorker() ServiceWorker::~ServiceWorker()
@ -94,6 +119,10 @@ ServiceWorker::~ServiceWorker()
mInner->RemoveServiceWorker(this); mInner->RemoveServiceWorker(this);
} }
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorker,
DOMEventTargetHelper,
mRegistration);
NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper)
@ -201,5 +230,14 @@ ServiceWorker::DisconnectFromOwner()
DOMEventTargetHelper::DisconnectFromOwner(); DOMEventTargetHelper::DisconnectFromOwner();
} }
void
ServiceWorker::MaybeAttachToRegistration(ServiceWorkerRegistration* aRegistration)
{
MOZ_DIAGNOSTIC_ASSERT(aRegistration);
MOZ_DIAGNOSTIC_ASSERT(!mRegistration);
mRegistration = aRegistration;
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

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

@ -10,6 +10,7 @@
#include "mozilla/DOMEventTargetHelper.h" #include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ServiceWorkerDescriptor.h" #include "mozilla/dom/ServiceWorkerDescriptor.h"
#include "mozilla/dom/ServiceWorkerUtils.h"
#ifdef XP_WIN #ifdef XP_WIN
#undef PostMessage #undef PostMessage
@ -55,6 +56,12 @@ public:
virtual void virtual void
RemoveServiceWorker(ServiceWorker* aWorker) = 0; RemoveServiceWorker(ServiceWorker* aWorker) = 0;
// Get the associated registration for this ServiceWorker. The success
// callback should always be called asynchronously.
virtual void
GetRegistration(ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) = 0;
virtual void virtual void
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData, PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
const ClientInfo& aClientInfo, const ClientInfo& aClientInfo,
@ -65,6 +72,7 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKER_IID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKER_IID)
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorker, DOMEventTargetHelper)
IMPL_EVENT_HANDLER(statechange) IMPL_EVENT_HANDLER(statechange)
IMPL_EVENT_HANDLER(error) IMPL_EVENT_HANDLER(error)
@ -102,9 +110,13 @@ private:
// This class is reference-counted and will be destroyed from Release(). // This class is reference-counted and will be destroyed from Release().
~ServiceWorker(); ~ServiceWorker();
void
MaybeAttachToRegistration(ServiceWorkerRegistration* aRegistration);
ServiceWorkerDescriptor mDescriptor; ServiceWorkerDescriptor mDescriptor;
RefPtr<Inner> mInner; RefPtr<Inner> mInner;
RefPtr<ServiceWorkerRegistration> mRegistration;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorker, NS_DOM_SERVICEWORKER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorker, NS_DOM_SERVICEWORKER_IID)

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

@ -36,6 +36,42 @@ ServiceWorkerImpl::RemoveServiceWorker(ServiceWorker* aWorker)
mOuter = nullptr; mOuter = nullptr;
} }
void
ServiceWorkerImpl::GetRegistration(ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB)
{
// While we could immediate call success with our registration descriptor
// we instead queue a runnable to do this. This ensures that GetRegistration()
// is always async to match how the IPC implementation will work. It also
// ensure that if any events are triggered from providing the registration
// that they are fired from a runnable on the correct global's event target.
if (!mOuter) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
nsIGlobalObject* global = mOuter->GetParentObject();
if (!global) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
"ServiceWorkerImpl::GetRegistration",
[reg = mReg, successCB = std::move(aSuccessCB)] () mutable {
successCB(reg->Descriptor());
});
nsresult rv =
global->EventTargetFor(TaskCategory::Other)->Dispatch(r.forget(),
NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
aFailureCB(CopyableErrorResult(rv));
return;
}
}
void void
ServiceWorkerImpl::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData, ServiceWorkerImpl::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
const ClientInfo& aClientInfo, const ClientInfo& aClientInfo,
@ -54,11 +90,14 @@ ServiceWorkerImpl::SetState(ServiceWorkerState aState)
} }
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo) ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo,
ServiceWorkerRegistrationInfo* aReg)
: mInfo(aInfo) : mInfo(aInfo)
, mReg(aReg)
, mOuter(nullptr) , mOuter(nullptr)
{ {
MOZ_DIAGNOSTIC_ASSERT(mInfo); MOZ_DIAGNOSTIC_ASSERT(mInfo);
MOZ_DIAGNOSTIC_ASSERT(mReg);
} }
} // namespace dom } // namespace dom

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

@ -14,11 +14,13 @@ namespace mozilla {
namespace dom { namespace dom {
class ServiceWorkerInfo; class ServiceWorkerInfo;
class ServiceWorkerRegistrationInfo;
class ServiceWorkerImpl final : public ServiceWorker::Inner class ServiceWorkerImpl final : public ServiceWorker::Inner
, public ServiceWorkerInfo::Listener , public ServiceWorkerInfo::Listener
{ {
RefPtr<ServiceWorkerInfo> mInfo; RefPtr<ServiceWorkerInfo> mInfo;
RefPtr<ServiceWorkerRegistrationInfo> mReg;
ServiceWorker* mOuter; ServiceWorker* mOuter;
~ServiceWorkerImpl(); ~ServiceWorkerImpl();
@ -30,6 +32,10 @@ class ServiceWorkerImpl final : public ServiceWorker::Inner
void void
RemoveServiceWorker(ServiceWorker* aWorker) override; RemoveServiceWorker(ServiceWorker* aWorker) override;
void
GetRegistration(ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) override;
void void
PostMessage(RefPtr<ServiceWorkerCloneData>&& aData, PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
const ClientInfo& aClientInfo, const ClientInfo& aClientInfo,
@ -40,7 +46,8 @@ class ServiceWorkerImpl final : public ServiceWorker::Inner
SetState(ServiceWorkerState aState) override; SetState(ServiceWorkerState aState) override;
public: public:
explicit ServiceWorkerImpl(ServiceWorkerInfo* aInfo); ServiceWorkerImpl(ServiceWorkerInfo* aInfo,
ServiceWorkerRegistrationInfo* aReg);
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override); NS_INLINE_DECL_REFCOUNTING(ServiceWorkerImpl, override);
}; };