Merge m-c to autoland. a=merge

This commit is contained in:
Ryan VanderMeulen 2020-03-30 14:57:26 -04:00
Родитель fb695f5c5e 5012cc0f5d
Коммит 609e39ab2e
11 изменённых файлов: 107 добавлений и 397 удалений

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

@ -163,9 +163,9 @@ class ClientChannelHelper : public nsIInterfaceRequestor,
NS_DECL_ISUPPORTS
virtual void CreateClientForPrincipal(nsILoadInfo* aLoadInfo,
nsIPrincipal* aPrincipal,
nsISerialEventTarget* aEventTarget) {
static void CreateClientForPrincipal(nsILoadInfo* aLoadInfo,
nsIPrincipal* aPrincipal,
nsISerialEventTarget* aEventTarget) {
// Create the new ClientSource. This should only happen for window
// Clients since support cross-origin redirects are blocked by the
// same-origin security policy.
@ -181,41 +181,16 @@ NS_IMPL_ISUPPORTS(ClientChannelHelper, nsIInterfaceRequestor,
nsIChannelEventSink);
class ClientChannelHelperParent final : public ClientChannelHelper {
~ClientChannelHelperParent() {
// This requires that if a load completes, the associated ClientSource is
// created and registers itself before this ClientChannelHelperParent is
// destroyed. Otherwise, we may incorrectly "forget" a future ClientSource
// which will actually be created.
SetFutureSourceInfo(Nothing());
}
~ClientChannelHelperParent() = default;
void CreateClient(nsILoadInfo* aLoadInfo, nsIPrincipal* aPrincipal) override {
CreateClientForPrincipal(aLoadInfo, aPrincipal, mEventTarget);
}
void SetFutureSourceInfo(Maybe<ClientInfo>&& aClientInfo) {
if (mRecentFutureSourceInfo) {
// No-op if the corresponding ClientSource has alrady been created, but
// it's not known if that's the case here.
ClientManager::ForgetFutureSource(*mRecentFutureSourceInfo);
}
if (aClientInfo) {
Unused << NS_WARN_IF(!ClientManager::ExpectFutureSource(*aClientInfo));
}
mRecentFutureSourceInfo = std::move(aClientInfo);
}
// Keep track of the most recent ClientInfo created which isn't backed by a
// ClientSource, which is used to notify ClientManagerService that the
// ClientSource won't ever actually be constructed.
Maybe<ClientInfo> mRecentFutureSourceInfo;
public:
void CreateClientForPrincipal(nsILoadInfo* aLoadInfo,
nsIPrincipal* aPrincipal,
nsISerialEventTarget* aEventTarget) override {
static void CreateClientForPrincipal(nsILoadInfo* aLoadInfo,
nsIPrincipal* aPrincipal,
nsISerialEventTarget* aEventTarget) {
// If we're managing redirects in the parent, then we don't want
// to create a new ClientSource (since those need to live with
// the global), so just allocate a new ClientInfo/id and we can
@ -225,7 +200,6 @@ class ClientChannelHelperParent final : public ClientChannelHelper {
ClientManager::CreateInfo(ClientType::Window, aPrincipal);
if (reservedInfo) {
aLoadInfo->SetReservedClientInfo(*reservedInfo);
SetFutureSourceInfo(std::move(reservedInfo));
}
}
ClientChannelHelperParent(nsIInterfaceRequestor* aOuter,
@ -320,12 +294,12 @@ nsresult AddClientChannelHelperInternal(nsIChannel* aChannel,
rv = aChannel->GetNotificationCallbacks(getter_AddRefs(outerCallbacks));
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<ClientChannelHelper> helper = new T(outerCallbacks, aEventTarget);
if (initialClientInfo.isNothing() && reservedClientInfo.isNothing()) {
helper->CreateClientForPrincipal(loadInfo, channelPrincipal, aEventTarget);
T::CreateClientForPrincipal(loadInfo, channelPrincipal, aEventTarget);
}
RefPtr<ClientChannelHelper> helper = new T(outerCallbacks, aEventTarget);
// Only set the callbacks helper if we are able to reserve the client
// successfully.
rv = aChannel->SetNotificationCallbacks(helper);

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

@ -27,13 +27,13 @@ void ClientHandleParent::ActorDestroy(ActorDestroyReason aReason) {
mSource->DetachHandle(this);
mSource = nullptr;
} else {
if (!mSourcePromiseHolder.IsEmpty()) {
CopyableErrorResult rv;
rv.ThrowAbortError("Client aborted");
mSourcePromiseHolder.Reject(rv, __func__);
}
mService->StopWaitingForSource(this, mClientId);
}
mSourcePromiseRequestHolder.DisconnectIfExists();
if (mSourcePromise) {
CopyableErrorResult rv;
rv.ThrowAbortError("Client aborted");
mSourcePromise->Reject(rv, __func__);
}
}
@ -63,20 +63,13 @@ ClientHandleParent::~ClientHandleParent() { MOZ_DIAGNOSTIC_ASSERT(!mSource); }
void ClientHandleParent::Init(const IPCClientInfo& aClientInfo) {
mClientId = aClientInfo.id();
mPrincipalInfo = aClientInfo.principalInfo();
mSource = mService->FindSource(aClientInfo.id(), aClientInfo.principalInfo());
if (!mSource) {
mService->WaitForSource(this, aClientInfo.id());
return;
}
// Callbacks are disconnected in ActorDestroy, so capturing `this` is safe.
mService->FindSource(aClientInfo.id(), aClientInfo.principalInfo())
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[this](ClientSourceParent* aSource) {
mSourcePromiseRequestHolder.Complete();
FoundSource(aSource);
},
[this](const CopyableErrorResult&) {
mSourcePromiseRequestHolder.Complete();
Unused << Send__delete__(this);
})
->Track(mSourcePromiseRequestHolder);
mSource->AttachHandle(this);
}
ClientSourceParent* ClientHandleParent::GetSource() const { return mSource; }
@ -86,17 +79,20 @@ RefPtr<SourcePromise> ClientHandleParent::EnsureSource() {
return SourcePromise::CreateAndResolve(mSource, __func__);
}
return mSourcePromiseHolder.Ensure(__func__);
if (!mSourcePromise) {
mSourcePromise = new SourcePromise::Private(__func__);
}
return mSourcePromise;
}
void ClientHandleParent::FoundSource(ClientSourceParent* aSource) {
MOZ_ASSERT(aSource->Info().Id() == mClientId);
if (!ClientMatchPrincipalInfo(aSource->Info().PrincipalInfo(),
mPrincipalInfo)) {
if (!mSourcePromiseHolder.IsEmpty()) {
if (mSourcePromise) {
CopyableErrorResult rv;
rv.ThrowAbortError("Client aborted");
mSourcePromiseHolder.Reject(rv, __func__);
mSourcePromise->Reject(rv, __func__);
}
Unused << Send__delete__(this);
return;
@ -104,7 +100,9 @@ void ClientHandleParent::FoundSource(ClientSourceParent* aSource) {
mSource = aSource;
mSource->AttachHandle(this);
mSourcePromiseHolder.ResolveIfExists(aSource, __func__);
if (mSourcePromise) {
mSourcePromise->Resolve(aSource, __func__);
}
}
} // namespace dom

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

@ -6,8 +6,6 @@
#ifndef _mozilla_dom_ClientHandleParent_h
#define _mozilla_dom_ClientHandleParent_h
#include "mozilla/MozPromise.h"
#include "mozilla/RefPtr.h"
#include "mozilla/dom/PClientHandleParent.h"
#include "mozilla/ErrorResult.h"
@ -23,18 +21,16 @@ typedef MozPromise<ClientSourceParent*, CopyableErrorResult,
class ClientHandleParent final : public PClientHandleParent {
RefPtr<ClientManagerService> mService;
// mSource and mSourcePromiseHolder are mutually exclusive.
ClientSourceParent* mSource;
// Operations will wait on this promise while mSource is null.
MozPromiseHolder<SourcePromise> mSourcePromiseHolder;
MozPromiseRequestHolder<SourcePromise> mSourcePromiseRequestHolder;
nsID mClientId;
PrincipalInfo mPrincipalInfo;
// A promise for HandleOps that want to access our ClientSourceParent.
// Resolved once FoundSource is called and we have a ClientSourceParent
// available.
RefPtr<SourcePromise::Private> mSourcePromise;
// PClientHandleParent interface
mozilla::ipc::IPCResult RecvTeardown() override;

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

@ -227,36 +227,6 @@ WorkerPrivate* ClientManager::GetWorkerPrivate() const {
return GetActor()->GetWorkerPrivate();
}
// Used to share logic between ExpectFutureSource and ForgetFutureSource.
/* static */ bool ClientManager::ExpectOrForgetFutureSource(
const ClientInfo& aClientInfo,
bool (PClientManagerChild::*aMethod)(const IPCClientInfo&)) {
bool rv = true;
RefPtr<ClientManager> mgr = ClientManager::GetOrCreateForCurrentThread();
mgr->MaybeExecute(
[&](ClientManagerChild* aActor) {
if (!(aActor->*aMethod)(aClientInfo.ToIPC())) {
rv = false;
}
},
[&] { rv = false; });
return rv;
}
/* static */ bool ClientManager::ExpectFutureSource(
const ClientInfo& aClientInfo) {
return ExpectOrForgetFutureSource(
aClientInfo, &PClientManagerChild::SendExpectFutureClientSource);
}
/* static */ bool ClientManager::ForgetFutureSource(
const ClientInfo& aClientInfo) {
return ExpectOrForgetFutureSource(
aClientInfo, &PClientManagerChild::SendForgetFutureClientSource);
}
// static
void ClientManager::Startup() {
MOZ_ASSERT(NS_IsMainThread());

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

@ -8,7 +8,6 @@
#include "mozilla/dom/ClientOpPromise.h"
#include "mozilla/dom/ClientThing.h"
#include "mozilla/dom/PClientManagerChild.h"
class nsIPrincipal;
@ -74,29 +73,7 @@ class ClientManager final : public ClientThing<ClientManagerChild> {
// Private methods called by ClientSource
mozilla::dom::WorkerPrivate* GetWorkerPrivate() const;
// Don't use - use {Expect,Forget}FutureSource instead.
static bool ExpectOrForgetFutureSource(
const ClientInfo& aClientInfo,
bool (PClientManagerChild::*aMethod)(const IPCClientInfo&));
public:
// Asynchronously declare that a ClientSource will possibly be constructed
// from an equivalent ClientInfo in the future. This must be called before any
// any ClientHandles are created with the ClientInfo to avoid race conditions
// when ClientHandles query the ClientManagerService.
//
// This method exists so that the ClientManagerService can determine if a
// particular ClientSource can be expected to exist in the future or has
// already existed and been destroyed.
//
// If it's later known that the expected ClientSource will not be
// constructed, ForgetFutureSource must be called.
static bool ExpectFutureSource(const ClientInfo& aClientInfo);
// May also be called even when the "future" source has become a "real"
// source, in which case this is a no-op.
static bool ForgetFutureSource(const ClientInfo& aClientInfo);
// Initialize the ClientManager at process start. This
// does book-keeping like creating a TLS identifier, etc.
// This should only be called by process startup code.

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

@ -10,7 +10,6 @@
#include "ClientManagerOpParent.h"
#include "ClientManagerService.h"
#include "ClientSourceParent.h"
#include "ClientValidation.h"
#include "mozilla/dom/PClientNavigateOpParent.h"
#include "mozilla/Unused.h"
@ -107,28 +106,5 @@ ClientManagerParent::~ClientManagerParent() { mService->RemoveManager(this); }
void ClientManagerParent::Init() { mService->AddManager(this); }
IPCResult ClientManagerParent::RecvExpectFutureClientSource(
const IPCClientInfo& aClientInfo) {
if (NS_WARN_IF(!ClientIsValidPrincipalInfo(aClientInfo.principalInfo()))) {
return IPC_FAIL(this, "Invalid PrincipalInfo.");
}
RefPtr<ClientManagerService> cms =
ClientManagerService::GetOrCreateInstance();
Unused << NS_WARN_IF(cms->ExpectFutureSource(aClientInfo));
return IPC_OK();
}
IPCResult ClientManagerParent::RecvForgetFutureClientSource(
const IPCClientInfo& aClientInfo) {
if (NS_WARN_IF(!ClientIsValidPrincipalInfo(aClientInfo.principalInfo()))) {
return IPC_FAIL(this, "Invalid PrincipalInfo.");
}
RefPtr<ClientManagerService> cms = ClientManagerService::GetInstance();
cms->ForgetFutureSource(aClientInfo);
return IPC_OK();
}
} // namespace dom
} // namespace mozilla

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

@ -52,12 +52,6 @@ class ClientManagerParent final : public PClientManagerParent {
PClientSourceParent* aActor,
const ClientSourceConstructorArgs& aArgs) override;
mozilla::ipc::IPCResult RecvExpectFutureClientSource(
const IPCClientInfo& aClientInfo) override;
mozilla::ipc::IPCResult RecvForgetFutureClientSource(
const IPCClientInfo& aClientInfo) override;
public:
ClientManagerParent();
~ClientManagerParent();

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

@ -11,7 +11,6 @@
#include "ClientOpenWindowUtils.h"
#include "ClientPrincipalUtils.h"
#include "ClientSourceParent.h"
#include "mozilla/dom/ClientIPCTypes.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ServiceWorkerManager.h"
#include "mozilla/dom/ServiceWorkerUtils.h"
@ -108,10 +107,6 @@ RefPtr<GenericPromise> OnShutdown() {
} // anonymous namespace
ClientManagerService::FutureClientSourceParent::FutureClientSourceParent(
const IPCClientInfo& aClientInfo)
: mPrincipalInfo(aClientInfo.principalInfo()) {}
ClientManagerService::ClientManagerService() : mShutdown(false) {
AssertIsOnBackgroundThread();
@ -141,7 +136,7 @@ ClientManagerService::ClientManagerService() : mShutdown(false) {
ClientManagerService::~ClientManagerService() {
AssertIsOnBackgroundThread();
MOZ_DIAGNOSTIC_ASSERT(mSourceTable.count() == 0);
MOZ_DIAGNOSTIC_ASSERT(mSourceTable.Count() == 0);
MOZ_DIAGNOSTIC_ASSERT(mManagerList.IsEmpty());
MOZ_DIAGNOSTIC_ASSERT(sClientManagerServiceInstance == this);
@ -167,38 +162,6 @@ void ClientManagerService::Shutdown() {
}
}
ClientSourceParent* ClientManagerService::MaybeUnwrapAsExistingSource(
const SourceTableEntry& aEntry) const {
AssertIsOnBackgroundThread();
if (aEntry.is<FutureClientSourceParent>()) {
return nullptr;
}
return aEntry.as<ClientSourceParent*>();
}
ClientSourceParent* ClientManagerService::FindExistingSource(
const nsID& aID, const PrincipalInfo& aPrincipalInfo) const {
AssertIsOnBackgroundThread();
auto entryPtr = mSourceTable.lookup(aID);
if (!entryPtr) {
return nullptr;
}
ClientSourceParent* source = MaybeUnwrapAsExistingSource(entryPtr->value());
if (!source || source->IsFrozen() ||
NS_WARN_IF(!ClientMatchPrincipalInfo(source->Info().PrincipalInfo(),
aPrincipalInfo))) {
return nullptr;
}
return source;
}
// static
already_AddRefed<ClientManagerService>
ClientManagerService::GetOrCreateInstance() {
@ -224,143 +187,72 @@ already_AddRefed<ClientManagerService> ClientManagerService::GetInstance() {
return ref.forget();
}
namespace {
bool IsNullPrincipalInfo(const PrincipalInfo& aPrincipalInfo) {
return aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo;
}
bool AreBothNullPrincipals(const PrincipalInfo& aPrincipalInfo1,
const PrincipalInfo& aPrincipalInfo2) {
return IsNullPrincipalInfo(aPrincipalInfo1) &&
IsNullPrincipalInfo(aPrincipalInfo2);
}
} // anonymous namespace
bool ClientManagerService::AddSource(ClientSourceParent* aSource) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(aSource);
const nsID& id = aSource->Info().Id();
auto entryPtr = mSourceTable.lookupForAdd(id);
if (entryPtr) {
SourceTableEntry& entry = entryPtr->value();
// Do not permit overwriting an existing ClientSource with the same
// UUID. This would allow a spoofed ClientParentSource actor to
// intercept postMessage() intended for the real actor.
if (NS_WARN_IF(entry.is<ClientSourceParent*>())) {
return false;
}
FutureClientSourceParent& placeHolder =
entry.as<FutureClientSourceParent>();
const PrincipalInfo& placeHolderPrincipalInfo = placeHolder.PrincipalInfo();
const PrincipalInfo& sourcePrincipalInfo = aSource->Info().PrincipalInfo();
// The placeholder FutureClientSourceParent's PrincipalInfo must match the
// real ClientSourceParent's PrincipalInfo. The only exception is if both
// are null principals (two null principals are considered unequal).
if (!AreBothNullPrincipals(placeHolderPrincipalInfo, sourcePrincipalInfo) &&
NS_WARN_IF(!ClientMatchPrincipalInfo(placeHolderPrincipalInfo,
sourcePrincipalInfo))) {
return false;
}
placeHolder.ResolvePromiseIfExists(aSource);
entry = AsVariant(aSource);
return true;
auto entry = mSourceTable.LookupForAdd(aSource->Info().Id());
// Do not permit overwriting an existing ClientSource with the same
// UUID. This would allow a spoofed ClientParentSource actor to
// intercept postMessage() intended for the real actor.
if (NS_WARN_IF(!!entry)) {
return false;
}
entry.OrInsert([&] { return aSource; });
return mSourceTable.add(entryPtr, id, AsVariant(aSource));
// Now that we've been created, notify any handles that were
// waiting on us.
auto* handles = mPendingHandles.GetValue(aSource->Info().Id());
if (handles) {
for (auto handle : *handles) {
handle->FoundSource(aSource);
}
}
mPendingHandles.Remove(aSource->Info().Id());
return true;
}
bool ClientManagerService::RemoveSource(ClientSourceParent* aSource) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(aSource);
auto entryPtr = mSourceTable.lookup(aSource->Info().Id());
if (NS_WARN_IF(!entryPtr)) {
auto entry = mSourceTable.Lookup(aSource->Info().Id());
if (NS_WARN_IF(!entry)) {
return false;
}
mSourceTable.remove(entryPtr);
entry.Remove();
return true;
}
bool ClientManagerService::ExpectFutureSource(
const IPCClientInfo& aClientInfo) {
AssertIsOnBackgroundThread();
const nsID& id = aClientInfo.id();
auto entryPtr = mSourceTable.lookupForAdd(id);
// Prevent overwrites.
if (NS_WARN_IF(static_cast<bool>(entryPtr))) {
return false;
}
return mSourceTable.add(
entryPtr, id,
SourceTableEntry(VariantIndex<0>(),
FutureClientSourceParent(aClientInfo)));
}
void ClientManagerService::ForgetFutureSource(
const IPCClientInfo& aClientInfo) {
AssertIsOnBackgroundThread();
auto entryPtr = mSourceTable.lookup(aClientInfo.id());
if (entryPtr) {
SourceTableEntry& entry = entryPtr->value();
if (entry.is<ClientSourceParent*>()) {
return;
}
CopyableErrorResult rv;
rv.ThrowInvalidStateError("Client creation aborted.");
entry.as<FutureClientSourceParent>().RejectPromiseIfExists(rv);
mSourceTable.remove(entryPtr);
}
}
RefPtr<SourcePromise> ClientManagerService::FindSource(
ClientSourceParent* ClientManagerService::FindSource(
const nsID& aID, const PrincipalInfo& aPrincipalInfo) {
AssertIsOnBackgroundThread();
auto entryPtr = mSourceTable.lookup(aID);
if (!entryPtr) {
CopyableErrorResult rv;
rv.ThrowInvalidStateError("Unknown client.");
return SourcePromise::CreateAndReject(rv, __func__);
auto entry = mSourceTable.Lookup(aID);
if (!entry) {
return nullptr;
}
SourceTableEntry& entry = entryPtr->value();
if (entry.is<FutureClientSourceParent>()) {
return entry.as<FutureClientSourceParent>().Promise();
}
ClientSourceParent* source = entry.as<ClientSourceParent*>();
ClientSourceParent* source = entry.Data();
if (source->IsFrozen() ||
NS_WARN_IF(!ClientMatchPrincipalInfo(source->Info().PrincipalInfo(),
aPrincipalInfo))) {
CopyableErrorResult rv;
rv.ThrowInvalidStateError("Unknown client.");
return SourcePromise::CreateAndReject(rv, __func__);
!ClientMatchPrincipalInfo(source->Info().PrincipalInfo(),
aPrincipalInfo)) {
return nullptr;
}
return SourcePromise::CreateAndResolve(source, __func__);
return source;
}
void ClientManagerService::WaitForSource(ClientHandleParent* aHandle,
const nsID& aID) {
auto& entry = mPendingHandles.GetOrInsert(aID);
entry.AppendElement(aHandle);
}
void ClientManagerService::StopWaitingForSource(ClientHandleParent* aHandle,
const nsID& aID) {
auto* entry = mPendingHandles.GetValue(aID);
if (entry) {
entry->RemoveElement(aHandle);
}
}
void ClientManagerService::AddManager(ClientManagerParent* aManager) {
@ -385,7 +277,7 @@ void ClientManagerService::RemoveManager(ClientManagerParent* aManager) {
RefPtr<ClientOpPromise> ClientManagerService::Navigate(
const ClientNavigateArgs& aArgs) {
ClientSourceParent* source =
FindExistingSource(aArgs.target().id(), aArgs.target().principalInfo());
FindSource(aArgs.target().id(), aArgs.target().principalInfo());
if (!source) {
CopyableErrorResult rv;
rv.ThrowInvalidStateError("Unknown client");
@ -511,11 +403,11 @@ RefPtr<ClientOpPromise> ClientManagerService::MatchAll(
RefPtr<PromiseListHolder> promiseList = new PromiseListHolder();
for (auto iter = mSourceTable.iter(); !iter.done(); iter.next()) {
ClientSourceParent* source =
MaybeUnwrapAsExistingSource(iter.get().value());
for (auto iter = mSourceTable.Iter(); !iter.Done(); iter.Next()) {
ClientSourceParent* source = iter.UserData();
MOZ_DIAGNOSTIC_ASSERT(source);
if (!source || source->IsFrozen() || !source->ExecutionReady()) {
if (source->IsFrozen() || !source->ExecutionReady()) {
continue;
}
@ -606,11 +498,11 @@ RefPtr<ClientOpPromise> ClientManagerService::Claim(
RefPtr<PromiseListHolder> promiseList = new PromiseListHolder();
for (auto iter = mSourceTable.iter(); !iter.done(); iter.next()) {
ClientSourceParent* source =
MaybeUnwrapAsExistingSource(iter.get().value());
for (auto iter = mSourceTable.Iter(); !iter.Done(); iter.Next()) {
ClientSourceParent* source = iter.UserData();
MOZ_DIAGNOSTIC_ASSERT(source);
if (!source || source->IsFrozen()) {
if (source->IsFrozen()) {
continue;
}
@ -652,8 +544,7 @@ RefPtr<ClientOpPromise> ClientManagerService::Claim(
RefPtr<ClientOpPromise> ClientManagerService::GetInfoAndState(
const ClientGetInfoAndStateArgs& aArgs) {
ClientSourceParent* source =
FindExistingSource(aArgs.id(), aArgs.principalInfo());
ClientSourceParent* source = FindSource(aArgs.id(), aArgs.principalInfo());
if (!source) {
CopyableErrorResult rv;
@ -664,11 +555,12 @@ RefPtr<ClientOpPromise> ClientManagerService::GetInfoAndState(
if (!source->ExecutionReady()) {
RefPtr<ClientManagerService> self = this;
// rejection ultimately converted to `undefined` in Clients::Get
return source->ExecutionReadyPromise()->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[self = std::move(self), aArgs]() {
[self, aArgs]() -> RefPtr<ClientOpPromise> {
ClientSourceParent* source =
self->FindExistingSource(aArgs.id(), aArgs.principalInfo());
self->FindSource(aArgs.id(), aArgs.principalInfo());
if (!source) {
CopyableErrorResult rv;
@ -694,8 +586,7 @@ bool ClientManagerService::HasWindow(
const PrincipalInfo& aPrincipalInfo, const nsID& aClientId) {
AssertIsOnBackgroundThread();
ClientSourceParent* source = FindExistingSource(aClientId, aPrincipalInfo);
ClientSourceParent* source = FindSource(aClientId, aPrincipalInfo);
if (!source) {
return false;
}

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

@ -6,12 +6,7 @@
#ifndef _mozilla_dom_ClientManagerService_h
#define _mozilla_dom_ClientManagerService_h
#include "ClientHandleParent.h"
#include "ClientOpPromise.h"
#include "mozilla/Assertions.h"
#include "mozilla/HashTable.h"
#include "mozilla/MozPromise.h"
#include "mozilla/Variant.h"
#include "nsDataHashtable.h"
namespace mozilla {
@ -33,59 +28,13 @@ class ContentParent;
// browser. This service runs on the PBackground thread. To interact
// it with it please use the ClientManager and ClientHandle classes.
class ClientManagerService final {
// Placeholder type that represents a ClientSourceParent that may be created
// in the future (e.g. while a redirect chain is being resolved).
//
// Each FutureClientSourceParent has a promise that callbacks may be chained
// to; the promise will be resolved when the associated ClientSourceParent is
// created or rejected when it's known that it'll never be created.
class FutureClientSourceParent {
public:
explicit FutureClientSourceParent(const IPCClientInfo& aClientInfo);
const mozilla::ipc::PrincipalInfo& PrincipalInfo() const {
return mPrincipalInfo;
}
already_AddRefed<SourcePromise> Promise() {
return mPromiseHolder.Ensure(__func__);
}
void ResolvePromiseIfExists(ClientSourceParent* aSource) {
MOZ_ASSERT(aSource);
mPromiseHolder.ResolveIfExists(aSource, __func__);
}
void RejectPromiseIfExists(const CopyableErrorResult& aRv) {
MOZ_ASSERT(aRv.Failed());
mPromiseHolder.RejectIfExists(aRv, __func__);
}
private:
const mozilla::ipc::PrincipalInfo mPrincipalInfo;
MozPromiseHolder<SourcePromise> mPromiseHolder;
RefPtr<ClientManagerService> mService = ClientManagerService::GetInstance();
};
using SourceTableEntry =
Variant<FutureClientSourceParent, ClientSourceParent*>;
struct nsIDHasher {
using Key = nsID;
using Lookup = Key;
static HashNumber hash(const Lookup& aLookup) {
return HashBytes(&aLookup, sizeof(Lookup));
}
static bool match(const Key& aKey, const Lookup& aLookup) {
return aKey.Equals(aLookup);
}
};
// Store the possible ClientSourceParent objects in a hash table. We want to
// Store the ClientSourceParent objects in a hash table. We want to
// optimize for insertion, removal, and lookup by UUID.
HashMap<nsID, SourceTableEntry, nsIDHasher> mSourceTable;
nsDataHashtable<nsIDHashKey, ClientSourceParent*> mSourceTable;
// The set of handles waiting for their corresponding ClientSourceParent
// to be created.
nsDataHashtable<nsIDHashKey, nsTArray<ClientHandleParent*>> mPendingHandles;
nsTArray<ClientManagerParent*> mManagerList;
@ -96,16 +45,6 @@ class ClientManagerService final {
void Shutdown();
// Returns nullptr if aEntry isn't a ClientSourceParent (i.e. it's a
// FutureClientSourceParent).
ClientSourceParent* MaybeUnwrapAsExistingSource(
const SourceTableEntry& aEntry) const;
// Returns nullptr if the ClientSourceParent doesn't exist yet (i.e. it's a
// FutureClientSourceParent or has already been destroyed) or is frozen.
ClientSourceParent* FindExistingSource(
const nsID& aID, const mozilla::ipc::PrincipalInfo& aPrincipalInfo) const;
public:
static already_AddRefed<ClientManagerService> GetOrCreateInstance();
@ -116,16 +55,15 @@ class ClientManagerService final {
bool RemoveSource(ClientSourceParent* aSource);
// Returns true when a FutureClientSourceParent is successfully added.
bool ExpectFutureSource(const IPCClientInfo& aClientInfo);
// May still be called if it's possible that the FutureClientSourceParent
// no longer exists.
void ForgetFutureSource(const IPCClientInfo& aClientInfo);
RefPtr<SourcePromise> FindSource(
ClientSourceParent* FindSource(
const nsID& aID, const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
// Called when a ClientHandle is created before the corresponding
// ClientSource. Will call FoundSource on the ClientHandleParent when it
// becomes available.
void WaitForSource(ClientHandleParent* aHandle, const nsID& aID);
void StopWaitingForSource(ClientHandleParent* aHandle, const nsID& aID);
void AddManager(ClientManagerParent* aManager);
void RemoveManager(ClientManagerParent* aManager);

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

@ -32,9 +32,6 @@ parent:
async PClientManagerOp(ClientOpConstructorArgs aArgs);
async PClientSource(ClientSourceConstructorArgs aArgs);
async ExpectFutureClientSource(IPCClientInfo aClientInfo);
async ForgetFutureClientSource(IPCClientInfo aClientInfo);
child:
async PClientNavigateOp(ClientNavigateOpConstructorArgs aArgs);

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

@ -7,7 +7,6 @@
EXPORTS.mozilla.dom += [
'ClientChannelHelper.h',
'ClientHandle.h',
'ClientHandleParent.h',
'ClientInfo.h',
'ClientIPCUtils.h',
'ClientManager.h',