mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
8c2521e9d5
Backed out changeset 179ceb82c9e5 (bug 1640839) Backed out changeset 73f498a821f0 (bug 1640839) Backed out changeset dc2d3d0e0365 (bug 1640839) Backed out changeset ddc989ac0509 (bug 1640839) Backed out changeset e595bb3feea8 (bug 1640839) Backed out changeset c85aca04e27f (bug 1640839) Backed out changeset 98e8e3a4047a (bug 1640839) Backed out changeset 59ef180517db (bug 1640839) Backed out changeset af2f5e293662 (bug 1640839) Backed out changeset 89aa6d9dc598 (bug 1640839) Backed out changeset 67b722a722f9 (bug 1640839) Backed out changeset 24a9665c6ced (bug 1640839) Backed out changeset d93f199385e9 (bug 1640839)
287 lines
9.6 KiB
C++
287 lines
9.6 KiB
C++
/* -*- 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 "ServiceWorkerInfo.h"
|
|
|
|
#include "ServiceWorkerUtils.h"
|
|
#include "ServiceWorkerPrivate.h"
|
|
#include "ServiceWorkerScriptCache.h"
|
|
#include "mozilla/dom/ClientIPCTypes.h"
|
|
#include "mozilla/dom/ClientState.h"
|
|
#include "mozilla/dom/RemoteWorkerTypes.h"
|
|
#include "mozilla/dom/WorkerPrivate.h"
|
|
|
|
namespace mozilla::dom {
|
|
|
|
using mozilla::ipc::PrincipalInfo;
|
|
|
|
static_assert(nsIServiceWorkerInfo::STATE_PARSED ==
|
|
static_cast<uint16_t>(ServiceWorkerState::Parsed),
|
|
"ServiceWorkerState enumeration value should match state values "
|
|
"from nsIServiceWorkerInfo.");
|
|
static_assert(nsIServiceWorkerInfo::STATE_INSTALLING ==
|
|
static_cast<uint16_t>(ServiceWorkerState::Installing),
|
|
"ServiceWorkerState enumeration value should match state values "
|
|
"from nsIServiceWorkerInfo.");
|
|
static_assert(nsIServiceWorkerInfo::STATE_INSTALLED ==
|
|
static_cast<uint16_t>(ServiceWorkerState::Installed),
|
|
"ServiceWorkerState enumeration value should match state values "
|
|
"from nsIServiceWorkerInfo.");
|
|
static_assert(nsIServiceWorkerInfo::STATE_ACTIVATING ==
|
|
static_cast<uint16_t>(ServiceWorkerState::Activating),
|
|
"ServiceWorkerState enumeration value should match state values "
|
|
"from nsIServiceWorkerInfo.");
|
|
static_assert(nsIServiceWorkerInfo::STATE_ACTIVATED ==
|
|
static_cast<uint16_t>(ServiceWorkerState::Activated),
|
|
"ServiceWorkerState enumeration value should match state values "
|
|
"from nsIServiceWorkerInfo.");
|
|
static_assert(nsIServiceWorkerInfo::STATE_REDUNDANT ==
|
|
static_cast<uint16_t>(ServiceWorkerState::Redundant),
|
|
"ServiceWorkerState enumeration value should match state values "
|
|
"from nsIServiceWorkerInfo.");
|
|
static_assert(nsIServiceWorkerInfo::STATE_UNKNOWN ==
|
|
ServiceWorkerStateValues::Count,
|
|
"ServiceWorkerState enumeration value should match state values "
|
|
"from nsIServiceWorkerInfo.");
|
|
|
|
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetId(nsAString& aId) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
aId = mWorkerPrivateId;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetScriptSpec(nsAString& aScriptSpec) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
CopyUTF8toUTF16(mDescriptor.ScriptURL(), aScriptSpec);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetCacheName(nsAString& aCacheName) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
aCacheName = mCacheName;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetState(uint16_t* aState) {
|
|
MOZ_ASSERT(aState);
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
*aState = static_cast<uint16_t>(State());
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetDebugger(nsIWorkerDebugger** aResult) {
|
|
if (NS_WARN_IF(!aResult)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
return mServiceWorkerPrivate->GetDebugger(aResult);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetHandlesFetchEvents(bool* aValue) {
|
|
MOZ_ASSERT(aValue);
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (mHandlesFetch == Unknown) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
*aValue = HandlesFetch();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetInstalledTime(PRTime* _retval) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(_retval);
|
|
*_retval = mInstalledTime;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetActivatedTime(PRTime* _retval) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(_retval);
|
|
*_retval = mActivatedTime;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetRedundantTime(PRTime* _retval) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(_retval);
|
|
*_retval = mRedundantTime;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetNavigationFaultCount(uint32_t* aNavigationFaultCount) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(aNavigationFaultCount);
|
|
*aNavigationFaultCount = mNavigationFaultCount;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::GetTestingInjectCancellation(
|
|
nsresult* aTestingInjectCancellation) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(aTestingInjectCancellation);
|
|
*aTestingInjectCancellation = mTestingInjectCancellation;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::SetTestingInjectCancellation(
|
|
nsresult aTestingInjectCancellation) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
mTestingInjectCancellation = aTestingInjectCancellation;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::AttachDebugger() {
|
|
return mServiceWorkerPrivate->AttachDebugger();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
ServiceWorkerInfo::DetachDebugger() {
|
|
return mServiceWorkerPrivate->DetachDebugger();
|
|
}
|
|
|
|
void ServiceWorkerInfo::UpdateState(ServiceWorkerState aState) {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
#ifdef DEBUG
|
|
// Any state can directly transition to redundant, but everything else is
|
|
// ordered.
|
|
if (aState != ServiceWorkerState::Redundant) {
|
|
MOZ_ASSERT_IF(State() == ServiceWorkerState::EndGuard_,
|
|
aState == ServiceWorkerState::Installing);
|
|
MOZ_ASSERT_IF(State() == ServiceWorkerState::Installing,
|
|
aState == ServiceWorkerState::Installed);
|
|
MOZ_ASSERT_IF(State() == ServiceWorkerState::Installed,
|
|
aState == ServiceWorkerState::Activating);
|
|
MOZ_ASSERT_IF(State() == ServiceWorkerState::Activating,
|
|
aState == ServiceWorkerState::Activated);
|
|
}
|
|
// Activated can only go to redundant.
|
|
MOZ_ASSERT_IF(State() == ServiceWorkerState::Activated,
|
|
aState == ServiceWorkerState::Redundant);
|
|
#endif
|
|
// Flush any pending functional events to the worker when it transitions to
|
|
// the activated state.
|
|
// TODO: Do we care that these events will race with the propagation of the
|
|
// state change?
|
|
if (State() != aState) {
|
|
mServiceWorkerPrivate->UpdateState(aState);
|
|
}
|
|
mDescriptor.SetState(aState);
|
|
if (State() == ServiceWorkerState::Redundant) {
|
|
serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
|
|
mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
|
|
}
|
|
}
|
|
|
|
ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
|
|
const nsACString& aScope,
|
|
uint64_t aRegistrationId,
|
|
uint64_t aRegistrationVersion,
|
|
const nsACString& aScriptSpec,
|
|
const nsAString& aCacheName,
|
|
nsLoadFlags aImportsLoadFlags)
|
|
: mPrincipal(aPrincipal),
|
|
mDescriptor(GetNextID(), aRegistrationId, aRegistrationVersion,
|
|
aPrincipal, aScope, aScriptSpec, ServiceWorkerState::Parsed),
|
|
mCacheName(aCacheName),
|
|
mWorkerPrivateId(ComputeWorkerPrivateId()),
|
|
mImportsLoadFlags(aImportsLoadFlags),
|
|
mCreationTime(PR_Now()),
|
|
mCreationTimeStamp(TimeStamp::Now()),
|
|
mInstalledTime(0),
|
|
mActivatedTime(0),
|
|
mRedundantTime(0),
|
|
mServiceWorkerPrivate(new ServiceWorkerPrivate(this)),
|
|
mSkipWaitingFlag(false),
|
|
mHandlesFetch(Unknown),
|
|
mNavigationFaultCount(0),
|
|
mTestingInjectCancellation(NS_OK) {
|
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
|
MOZ_ASSERT(mPrincipal);
|
|
// cache origin attributes so we can use them off main thread
|
|
mOriginAttributes = mPrincipal->OriginAttributesRef();
|
|
MOZ_ASSERT(!mDescriptor.ScriptURL().IsEmpty());
|
|
MOZ_ASSERT(!mCacheName.IsEmpty());
|
|
MOZ_ASSERT(!mWorkerPrivateId.IsEmpty());
|
|
|
|
// Scripts of a service worker should always be loaded bypass service workers.
|
|
// Otherwise, we might not be able to update a service worker correctly, if
|
|
// there is a service worker generating the script.
|
|
MOZ_DIAGNOSTIC_ASSERT(mImportsLoadFlags &
|
|
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
|
|
}
|
|
|
|
ServiceWorkerInfo::~ServiceWorkerInfo() {
|
|
MOZ_ASSERT(mServiceWorkerPrivate);
|
|
mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
|
|
}
|
|
|
|
static uint64_t gServiceWorkerInfoCurrentID = 0;
|
|
|
|
uint64_t ServiceWorkerInfo::GetNextID() const {
|
|
return ++gServiceWorkerInfoCurrentID;
|
|
}
|
|
|
|
void ServiceWorkerInfo::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
|
|
const ClientInfo& aClientInfo,
|
|
const ClientState& aClientState) {
|
|
mServiceWorkerPrivate->SendMessageEvent(
|
|
std::move(aData),
|
|
ClientInfoAndState(aClientInfo.ToIPC(), aClientState.ToIPC()));
|
|
}
|
|
|
|
void ServiceWorkerInfo::UpdateInstalledTime() {
|
|
MOZ_ASSERT(State() == ServiceWorkerState::Installed);
|
|
MOZ_ASSERT(mInstalledTime == 0);
|
|
|
|
mInstalledTime =
|
|
mCreationTime +
|
|
static_cast<PRTime>(
|
|
(TimeStamp::Now() - mCreationTimeStamp).ToMicroseconds());
|
|
}
|
|
|
|
void ServiceWorkerInfo::UpdateActivatedTime() {
|
|
MOZ_ASSERT(State() == ServiceWorkerState::Activated);
|
|
MOZ_ASSERT(mActivatedTime == 0);
|
|
|
|
mActivatedTime =
|
|
mCreationTime +
|
|
static_cast<PRTime>(
|
|
(TimeStamp::Now() - mCreationTimeStamp).ToMicroseconds());
|
|
}
|
|
|
|
void ServiceWorkerInfo::UpdateRedundantTime() {
|
|
MOZ_ASSERT(State() == ServiceWorkerState::Redundant);
|
|
MOZ_ASSERT(mRedundantTime == 0);
|
|
|
|
mRedundantTime =
|
|
mCreationTime +
|
|
static_cast<PRTime>(
|
|
(TimeStamp::Now() - mCreationTimeStamp).ToMicroseconds());
|
|
}
|
|
|
|
void ServiceWorkerInfo::SetRegistrationVersion(uint64_t aVersion) {
|
|
mDescriptor.SetRegistrationVersion(aVersion);
|
|
}
|
|
|
|
} // namespace mozilla::dom
|