diff options
Diffstat (limited to 'dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp')
-rw-r--r-- | dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp new file mode 100644 index 0000000000..1988df8c4a --- /dev/null +++ b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp @@ -0,0 +1,274 @@ +/* -*- 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/dom/IPCServiceWorkerRegistrationDescriptor.h" +#include "mozilla/ipc/PBackgroundSharedTypes.h" +#include "ServiceWorkerInfo.h" + +namespace mozilla::dom { + +using mozilla::ipc::PrincipalInfo; +using mozilla::ipc::PrincipalInfoToPrincipal; + +Maybe<IPCServiceWorkerDescriptor> +ServiceWorkerRegistrationDescriptor::NewestInternal() const { + Maybe<IPCServiceWorkerDescriptor> result; + if (mData->installing().isSome()) { + result.emplace(mData->installing().ref()); + } else if (mData->waiting().isSome()) { + result.emplace(mData->waiting().ref()); + } else if (mData->active().isSome()) { + result.emplace(mData->active().ref()); + } + return result; +} + +ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor( + uint64_t aId, uint64_t aVersion, nsIPrincipal* aPrincipal, + const nsACString& aScope, ServiceWorkerUpdateViaCache aUpdateViaCache) + : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>()) { + MOZ_ALWAYS_SUCCEEDS( + PrincipalToPrincipalInfo(aPrincipal, &mData->principalInfo())); + + mData->id() = aId; + mData->version() = aVersion; + mData->scope() = aScope; + mData->updateViaCache() = aUpdateViaCache; + mData->installing() = Nothing(); + mData->waiting() = Nothing(); + mData->active() = Nothing(); +} + +ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor( + uint64_t aId, uint64_t aVersion, + const mozilla::ipc::PrincipalInfo& aPrincipalInfo, const nsACString& aScope, + ServiceWorkerUpdateViaCache aUpdateViaCache) + : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>( + aId, aVersion, aPrincipalInfo, nsCString(aScope), aUpdateViaCache, + Nothing(), Nothing(), Nothing())) {} + +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) { + if (this == &aRight) { + return *this; + } + mData.reset(); + mData = MakeUnique<IPCServiceWorkerRegistrationDescriptor>(*aRight.mData); + MOZ_DIAGNOSTIC_ASSERT(IsValid()); + return *this; +} + +ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor( + ServiceWorkerRegistrationDescriptor&& aRight) + : mData(std::move(aRight.mData)) { + MOZ_DIAGNOSTIC_ASSERT(IsValid()); +} + +ServiceWorkerRegistrationDescriptor& +ServiceWorkerRegistrationDescriptor::operator=( + ServiceWorkerRegistrationDescriptor&& aRight) { + mData.reset(); + mData = std::move(aRight.mData); + MOZ_DIAGNOSTIC_ASSERT(IsValid()); + return *this; +} + +ServiceWorkerRegistrationDescriptor::~ServiceWorkerRegistrationDescriptor() { + // Non-default destructor to avoid exposing the IPC type in the header. +} + +bool ServiceWorkerRegistrationDescriptor::operator==( + const ServiceWorkerRegistrationDescriptor& aRight) const { + return *mData == *aRight.mData; +} + +uint64_t ServiceWorkerRegistrationDescriptor::Id() const { return mData->id(); } + +uint64_t ServiceWorkerRegistrationDescriptor::Version() const { + return mData->version(); +} + +ServiceWorkerUpdateViaCache +ServiceWorkerRegistrationDescriptor::UpdateViaCache() const { + return mData->updateViaCache(); +} + +const mozilla::ipc::PrincipalInfo& +ServiceWorkerRegistrationDescriptor::PrincipalInfo() const { + return mData->principalInfo(); +} + +Result<nsCOMPtr<nsIPrincipal>, nsresult> +ServiceWorkerRegistrationDescriptor::GetPrincipal() const { + AssertIsOnMainThread(); + return PrincipalInfoToPrincipal(mData->principalInfo()); +} + +const nsCString& ServiceWorkerRegistrationDescriptor::Scope() const { + return mData->scope(); +} + +Maybe<ServiceWorkerDescriptor> +ServiceWorkerRegistrationDescriptor::GetInstalling() const { + Maybe<ServiceWorkerDescriptor> result; + + if (mData->installing().isSome()) { + result.emplace(ServiceWorkerDescriptor(mData->installing().ref())); + } + + return result; +} + +Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::GetWaiting() + const { + Maybe<ServiceWorkerDescriptor> result; + + if (mData->waiting().isSome()) { + result.emplace(ServiceWorkerDescriptor(mData->waiting().ref())); + } + + return result; +} + +Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::GetActive() + const { + Maybe<ServiceWorkerDescriptor> result; + + if (mData->active().isSome()) { + result.emplace(ServiceWorkerDescriptor(mData->active().ref())); + } + + return result; +} + +Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::Newest() + const { + Maybe<ServiceWorkerDescriptor> result; + Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal()); + if (newest.isSome()) { + result.emplace(ServiceWorkerDescriptor(newest.ref())); + } + return result; +} + +bool ServiceWorkerRegistrationDescriptor::HasWorker( + const ServiceWorkerDescriptor& aDescriptor) const { + Maybe<ServiceWorkerDescriptor> installing = GetInstalling(); + Maybe<ServiceWorkerDescriptor> waiting = GetWaiting(); + Maybe<ServiceWorkerDescriptor> active = GetActive(); + return (installing.isSome() && installing.ref().Matches(aDescriptor)) || + (waiting.isSome() && waiting.ref().Matches(aDescriptor)) || + (active.isSome() && active.ref().Matches(aDescriptor)); +} + +namespace { + +bool IsValidWorker( + const Maybe<IPCServiceWorkerDescriptor>& aWorker, const nsACString& aScope, + const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal) { + if (aWorker.isNothing()) { + return true; + } + + auto& worker = aWorker.ref(); + 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) { + aInstalling->SetRegistrationVersion(Version()); + mData->installing() = Some(aInstalling->Descriptor().ToIPC()); + } else { + mData->installing() = Nothing(); + } + + if (aWaiting) { + aWaiting->SetRegistrationVersion(Version()); + mData->waiting() = Some(aWaiting->Descriptor().ToIPC()); + } else { + mData->waiting() = Nothing(); + } + + if (aActive) { + aActive->SetRegistrationVersion(Version()); + mData->active() = Some(aActive->Descriptor().ToIPC()); + } else { + mData->active() = Nothing(); + } + + MOZ_DIAGNOSTIC_ASSERT(IsValid()); +} + +void ServiceWorkerRegistrationDescriptor::SetVersion(uint64_t aVersion) { + MOZ_DIAGNOSTIC_ASSERT(aVersion > mData->version()); + mData->version() = aVersion; +} + +const IPCServiceWorkerRegistrationDescriptor& +ServiceWorkerRegistrationDescriptor::ToIPC() const { + return *mData; +} + +} // namespace mozilla::dom |