Bug 1433505 P1 Add the ServiceWorkerRegistrationDescriptor and backing IPC type. r=asuth

This commit is contained in:
Ben Kelly 2018-01-31 08:29:49 -08:00
Родитель 0baeaa5def
Коммит fcf562611d
6 изменённых файлов: 429 добавлений и 1 удалений

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

@ -0,0 +1,34 @@
/* 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 PBackgroundSharedTypes;
include IPCServiceWorkerDescriptor;
using ServiceWorkerUpdateViaCache from "mozilla/dom/ServiceWorkerIPCUtils.h";
namespace mozilla {
namespace dom {
// IPC type with enough information to create a ServiceWorker DOM object
// in a child process. Note that the state may be slightly out-of-sync
// with the parent and should be updated dynamically if necessary.
struct IPCServiceWorkerRegistrationDescriptor
{
// These values should match the principal and scope in each
// associated worker. It may be possible to optimize in the future,
// but for now we duplicate the information here to ensure correctness.
// Its possible we may need to reference a registration before the
// worker is installed yet, etc.
PrincipalInfo principalInfo;
nsCString scope;
ServiceWorkerUpdateViaCache updateViaCache;
OptionalIPCServiceWorkerDescriptor installing;
OptionalIPCServiceWorkerDescriptor waiting;
OptionalIPCServiceWorkerDescriptor active;
};
} // namespace dom
} // namespace mozilla

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

@ -25,7 +25,7 @@ enum class ServiceWorkerState : uint8_t;
// accurate. Currently the only variable field is the ServiceWorkerState.
class ServiceWorkerDescriptor final
{
// This class is largely a wrapper wround an IPDL generated struct. We
// This class is largely a wrapper around an IPDL generated struct. We
// need the wrapper class since IPDL generated code includes windows.h
// which is in turn incompatible with bindings code.
UniquePtr<IPCServiceWorkerDescriptor> mData;

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

@ -7,7 +7,12 @@
#define _mozilla_dom_ServiceWorkerIPCUtils_h
#include "ipc/IPCMessageUtils.h"
// Undo X11/X.h's definition of None
#undef None
#include "mozilla/dom/ServiceWorkerBinding.h"
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
namespace IPC {
@ -18,6 +23,13 @@ namespace IPC {
mozilla::dom::ServiceWorkerState::EndGuard_>
{};
template<>
struct ParamTraits<mozilla::dom::ServiceWorkerUpdateViaCache> :
public ContiguousEnumSerializer<mozilla::dom::ServiceWorkerUpdateViaCache,
mozilla::dom::ServiceWorkerUpdateViaCache::Imports,
mozilla::dom::ServiceWorkerUpdateViaCache::EndGuard_>
{};
} // namespace IPC
#endif // _mozilla_dom_ServiceWorkerIPCUtils_h

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

@ -0,0 +1,269 @@
/* -*- 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 "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "ServiceWorkerInfo.h"
namespace mozilla {
namespace dom {
Maybe<IPCServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::NewestInternal() const
{
Maybe<IPCServiceWorkerDescriptor> result;
if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(mData->installing().get_IPCServiceWorkerDescriptor());
} else if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(mData->waiting().get_IPCServiceWorkerDescriptor());
} else if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(mData->active().get_IPCServiceWorkerDescriptor());
}
return Move(result);
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
nsIPrincipal* aPrincipal,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache)
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>())
{
MOZ_ALWAYS_SUCCEEDS(
PrincipalToPrincipalInfo(aPrincipal, &mData->principalInfo()));
mData->scope() = aScope;
mData->updateViaCache() = aUpdateViaCache;
mData->installing() = void_t();
mData->waiting() = void_t();
mData->active() = void_t();
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache)
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aPrincipalInfo,
nsCString(aScope),
aUpdateViaCache,
void_t(),
void_t(),
void_t()))
{
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(const IPCServiceWorkerRegistrationDescriptor& aDescriptor)
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aDescriptor))
{
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(const ServiceWorkerRegistrationDescriptor& aRight)
{
// UniquePtr doesn't have a default copy constructor, so we can't rely
// on default copy construction. Use the assignment operator to
// minimize duplication.
operator=(aRight);
}
ServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistrationDescriptor::operator=(const ServiceWorkerRegistrationDescriptor& aRight)
{
mData.reset();
mData = MakeUnique<IPCServiceWorkerRegistrationDescriptor>(*aRight.mData);
MOZ_DIAGNOSTIC_ASSERT(IsValid());
return *this;
}
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(ServiceWorkerRegistrationDescriptor&& aRight)
: mData(Move(aRight.mData))
{
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
ServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistrationDescriptor::operator=(ServiceWorkerRegistrationDescriptor&& aRight)
{
mData.reset();
mData = Move(aRight.mData);
MOZ_DIAGNOSTIC_ASSERT(IsValid());
return *this;
}
bool
ServiceWorkerRegistrationDescriptor::operator==(const ServiceWorkerRegistrationDescriptor& aRight) const
{
return *mData == *aRight.mData;
}
ServiceWorkerUpdateViaCache
ServiceWorkerRegistrationDescriptor::UpdateViaCache() const
{
return mData->updateViaCache();
}
const mozilla::ipc::PrincipalInfo&
ServiceWorkerRegistrationDescriptor::PrincipalInfo() const
{
return mData->principalInfo();
}
const nsCString&
ServiceWorkerRegistrationDescriptor::Scope() const
{
return mData->scope();
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::GetInstalling() const
{
Maybe<ServiceWorkerDescriptor> result;
if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(ServiceWorkerDescriptor(
mData->installing().get_IPCServiceWorkerDescriptor()));
}
return Move(result);
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::GetWaiting() const
{
Maybe<ServiceWorkerDescriptor> result;
if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(ServiceWorkerDescriptor(
mData->waiting().get_IPCServiceWorkerDescriptor()));
}
return Move(result);
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::GetActive() const
{
Maybe<ServiceWorkerDescriptor> result;
if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
result.emplace(ServiceWorkerDescriptor(
mData->active().get_IPCServiceWorkerDescriptor()));
}
return Move(result);
}
Maybe<ServiceWorkerDescriptor>
ServiceWorkerRegistrationDescriptor::Newest() const
{
Maybe<ServiceWorkerDescriptor> result;
Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal());
if (newest.isSome()) {
result.emplace(ServiceWorkerDescriptor(newest.ref()));
}
return Move(result);
}
namespace {
bool
IsValidWorker(const OptionalIPCServiceWorkerDescriptor& aWorker,
const nsACString& aScope,
const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal)
{
if (aWorker.type() == OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
return true;
}
auto& worker = aWorker.get_IPCServiceWorkerDescriptor();
if (worker.scope() != aScope) {
return false;
}
auto& principalInfo = worker.principalInfo();
if (principalInfo.type() != mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
return false;
}
auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
if (contentPrincipal.originNoSuffix() != aContentPrincipal.originNoSuffix() ||
contentPrincipal.attrs() != aContentPrincipal.attrs()) {
return false;
}
return true;
}
} // anonymous namespace
bool
ServiceWorkerRegistrationDescriptor::IsValid() const
{
auto& principalInfo = PrincipalInfo();
if (principalInfo.type() != mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
return false;
}
auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
if (!IsValidWorker(mData->installing(), Scope(), contentPrincipal) ||
!IsValidWorker(mData->waiting(), Scope(), contentPrincipal) ||
!IsValidWorker(mData->active(), Scope(), contentPrincipal)) {
return false;
}
return true;
}
void
ServiceWorkerRegistrationDescriptor::SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache)
{
mData->updateViaCache() = aUpdateViaCache;
}
void
ServiceWorkerRegistrationDescriptor::SetWorkers(ServiceWorkerInfo* aInstalling,
ServiceWorkerInfo* aWaiting,
ServiceWorkerInfo* aActive)
{
if (aInstalling) {
mData->installing() = aInstalling->Descriptor().ToIPC();
} else {
mData->installing() = void_t();
}
if (aWaiting) {
mData->waiting() = aWaiting->Descriptor().ToIPC();
} else {
mData->waiting() = void_t();
}
if (aActive) {
mData->active() = aActive->Descriptor().ToIPC();
} else {
mData->active() = void_t();
}
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
void
ServiceWorkerRegistrationDescriptor::SetWorkers(OptionalIPCServiceWorkerDescriptor& aInstalling,
OptionalIPCServiceWorkerDescriptor& aWaiting,
OptionalIPCServiceWorkerDescriptor& aActive)
{
mData->installing() = aInstalling;
mData->waiting() = aWaiting;
mData->active() = aActive;
MOZ_DIAGNOSTIC_ASSERT(IsValid());
}
const IPCServiceWorkerRegistrationDescriptor&
ServiceWorkerRegistrationDescriptor::ToIPC() const
{
return *mData;
}
} // namespace dom
} // namespace mozilla

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

@ -0,0 +1,110 @@
/* -*- 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_ServiceWorkerRegistrationDescriptor_h
#define _mozilla_dom_ServiceWorkerRegistrationDescriptor_h
#include "mozilla/Maybe.h"
#include "mozilla/dom/IPCServiceWorkerRegistrationDescriptor.h"
#include "mozilla/dom/ServiceWorkerDescriptor.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
namespace ipc {
class PrincipalInfo;
} // namespace ipc
namespace dom {
class IPCServiceWorkerRegistrationDescriptor;
class ServiceWorkerInfo;
enum class ServiceWorkerUpdateViaCache : uint8_t;
// This class represents a snapshot of a particular
// ServiceWorkerRegistrationInfo object. It is threadsafe and can be
// transferred across processes.
class ServiceWorkerRegistrationDescriptor final
{
// This class is largely a wrapper wround an IPDL generated struct. We
// need the wrapper class since IPDL generated code includes windows.h
// which is in turn incompatible with bindings code.
UniquePtr<IPCServiceWorkerRegistrationDescriptor> mData;
Maybe<IPCServiceWorkerDescriptor>
NewestInternal() const;
public:
ServiceWorkerRegistrationDescriptor(nsIPrincipal* aPrincipal,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache);
ServiceWorkerRegistrationDescriptor(const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsACString& aScope,
ServiceWorkerUpdateViaCache aUpdateViaCache);
explicit ServiceWorkerRegistrationDescriptor(const IPCServiceWorkerRegistrationDescriptor& aDescriptor);
ServiceWorkerRegistrationDescriptor(const ServiceWorkerRegistrationDescriptor& aRight);
ServiceWorkerRegistrationDescriptor&
operator=(const ServiceWorkerRegistrationDescriptor& aRight);
ServiceWorkerRegistrationDescriptor(ServiceWorkerRegistrationDescriptor&& aRight);
ServiceWorkerRegistrationDescriptor&
operator=(ServiceWorkerRegistrationDescriptor&& aRight);
~ServiceWorkerRegistrationDescriptor() = default;
bool
operator==(const ServiceWorkerRegistrationDescriptor& aRight) const;
ServiceWorkerUpdateViaCache
UpdateViaCache() const;
const mozilla::ipc::PrincipalInfo&
PrincipalInfo() const;
const nsCString&
Scope() const;
Maybe<ServiceWorkerDescriptor>
GetInstalling() const;
Maybe<ServiceWorkerDescriptor>
GetWaiting() const;
Maybe<ServiceWorkerDescriptor>
GetActive() const;
Maybe<ServiceWorkerDescriptor>
Newest() const;
bool
IsValid() const;
void
SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache);
void
SetWorkers(ServiceWorkerInfo* aInstalling,
ServiceWorkerInfo* aWaiting,
ServiceWorkerInfo* aActive);
void
SetWorkers(OptionalIPCServiceWorkerDescriptor& aInstalling,
OptionalIPCServiceWorkerDescriptor& aWaiting,
OptionalIPCServiceWorkerDescriptor& aActive);
// Expose the underlying IPC type so that it can be passed via IPC.
const IPCServiceWorkerRegistrationDescriptor&
ToIPC() const;
};
} // namespace dom
} // namespace mozilla
#endif // _mozilla_dom_ServiceWorkerRegistrationDescriptor_h

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

@ -22,6 +22,7 @@ EXPORTS.mozilla.dom += [
'ServiceWorkerManagerParent.h',
'ServiceWorkerRegistrar.h',
'ServiceWorkerRegistration.h',
'ServiceWorkerRegistrationDescriptor.h',
'ServiceWorkerRegistrationInfo.h',
'ServiceWorkerUtils.h',
]
@ -43,6 +44,7 @@ UNIFIED_SOURCES += [
'ServiceWorkerRegisterJob.cpp',
'ServiceWorkerRegistrar.cpp',
'ServiceWorkerRegistration.cpp',
'ServiceWorkerRegistrationDescriptor.cpp',
'ServiceWorkerRegistrationInfo.cpp',
'ServiceWorkerScriptCache.cpp',
'ServiceWorkerUnregisterJob.cpp',
@ -54,6 +56,7 @@ UNIFIED_SOURCES += [
IPDL_SOURCES += [
'IPCServiceWorkerDescriptor.ipdlh',
'IPCServiceWorkerRegistrationDescriptor.ipdlh',
'PServiceWorkerManager.ipdl',
'PServiceWorkerUpdater.ipdl',
'ServiceWorkerRegistrarTypes.ipdlh',