diff --git a/dom/serviceworkers/PServiceWorkerContainer.ipdl b/dom/serviceworkers/PServiceWorkerContainer.ipdl index 3bd9eff4d2f7..f57846ffb6cb 100644 --- a/dom/serviceworkers/PServiceWorkerContainer.ipdl +++ b/dom/serviceworkers/PServiceWorkerContainer.ipdl @@ -27,6 +27,9 @@ parent: async GetRegistrations(IPCClientInfo aClientInfo) returns (IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult aResult); + async GetReady(IPCClientInfo aClientInfo) + returns (IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult aResult); + child: async __delete__(); }; diff --git a/dom/serviceworkers/RemoteServiceWorkerContainerImpl.cpp b/dom/serviceworkers/RemoteServiceWorkerContainerImpl.cpp index 6bd39d934154..9bc959627318 100644 --- a/dom/serviceworkers/RemoteServiceWorkerContainerImpl.cpp +++ b/dom/serviceworkers/RemoteServiceWorkerContainerImpl.cpp @@ -157,7 +157,28 @@ RemoteServiceWorkerContainerImpl::GetReady(const ClientInfo& aClientInfo, ServiceWorkerRegistrationCallback&& aSuccessCB, ServiceWorkerFailureCallback&& aFailureCB) const { - // TODO + if (!mActor) { + aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR)); + return; + } + + mActor->SendGetReady(aClientInfo.ToIPC(), + [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)); + }); } RemoteServiceWorkerContainerImpl::RemoteServiceWorkerContainerImpl() diff --git a/dom/serviceworkers/ServiceWorkerContainerParent.cpp b/dom/serviceworkers/ServiceWorkerContainerParent.cpp index 86c895b1eb92..996d492d7833 100644 --- a/dom/serviceworkers/ServiceWorkerContainerParent.cpp +++ b/dom/serviceworkers/ServiceWorkerContainerParent.cpp @@ -97,6 +97,26 @@ ServiceWorkerContainerParent::RecvGetRegistrations(const IPCClientInfo& aClientI return IPC_OK(); } +IPCResult +ServiceWorkerContainerParent::RecvGetReady(const IPCClientInfo& aClientInfo, + GetReadyResolver&& aResolver) +{ + if (!mProxy) { + aResolver(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR)); + return IPC_OK(); + } + + mProxy->GetReady(ClientInfo(aClientInfo))->Then( + GetCurrentThreadSerialEventTarget(), __func__, + [aResolver] (const ServiceWorkerRegistrationDescriptor& aDescriptor) { + aResolver(aDescriptor.ToIPC()); + }, [aResolver] (const CopyableErrorResult& aResult) { + aResolver(aResult); + }); + + return IPC_OK(); +} + ServiceWorkerContainerParent::ServiceWorkerContainerParent() { } diff --git a/dom/serviceworkers/ServiceWorkerContainerParent.h b/dom/serviceworkers/ServiceWorkerContainerParent.h index f8024a39898b..5cb0a43f246e 100644 --- a/dom/serviceworkers/ServiceWorkerContainerParent.h +++ b/dom/serviceworkers/ServiceWorkerContainerParent.h @@ -41,6 +41,10 @@ class ServiceWorkerContainerParent final : public PServiceWorkerContainerParent RecvGetRegistrations(const IPCClientInfo& aClientInfo, GetRegistrationsResolver&& aResolver) override; + mozilla::ipc::IPCResult + RecvGetReady(const IPCClientInfo& aClientInfo, + GetReadyResolver&& aResolver) override; + public: ServiceWorkerContainerParent(); ~ServiceWorkerContainerParent(); diff --git a/dom/serviceworkers/ServiceWorkerContainerProxy.cpp b/dom/serviceworkers/ServiceWorkerContainerProxy.cpp index a4f3345bfc30..17df30b2abfc 100644 --- a/dom/serviceworkers/ServiceWorkerContainerProxy.cpp +++ b/dom/serviceworkers/ServiceWorkerContainerProxy.cpp @@ -126,5 +126,32 @@ ServiceWorkerContainerProxy::GetRegistrations(const ClientInfo& aClientInfo) return promise; } +RefPtr +ServiceWorkerContainerProxy::GetReady(const ClientInfo& aClientInfo) +{ + AssertIsOnBackgroundThread(); + + RefPtr promise = + new ServiceWorkerRegistrationPromise::Private(__func__); + + nsCOMPtr r = NS_NewRunnableFunction(__func__, + [aClientInfo, promise] () mutable { + auto scopeExit = MakeScopeExit([&] { + promise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); + }); + + RefPtr swm = ServiceWorkerManager::GetInstance(); + NS_ENSURE_TRUE_VOID(swm); + + swm->WhenReady(aClientInfo)->ChainTo(promise.forget(), __func__); + + scopeExit.release(); + }); + + MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget())); + + return promise; +} + } // namespace dom } // namespace mozilla diff --git a/dom/serviceworkers/ServiceWorkerContainerProxy.h b/dom/serviceworkers/ServiceWorkerContainerProxy.h index c5a80fb936a0..c748e096f971 100644 --- a/dom/serviceworkers/ServiceWorkerContainerProxy.h +++ b/dom/serviceworkers/ServiceWorkerContainerProxy.h @@ -36,6 +36,9 @@ public: RefPtr GetRegistrations(const ClientInfo& aClientInfo); + RefPtr + GetReady(const ClientInfo& aClientInfo); + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ServiceWorkerContainerProxy); };