зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1582237
- Expose embedder inner window ID on BrowsingContext in all processes, r=farre
Differential Revision: https://phabricator.services.mozilla.com/D46802 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6135c6c044
Коммит
08192838cd
|
@ -259,9 +259,6 @@ void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
|
|||
// Notify the parent process of the embedding status. We don't need to do
|
||||
// this when clearing our embedder, as we're being destroyed either way.
|
||||
if (aEmbedder) {
|
||||
nsCOMPtr<nsIDocShell> container =
|
||||
do_QueryInterface(aEmbedder->OwnerDoc()->GetContainer());
|
||||
|
||||
// If our embedder element is being mutated to a different embedder, and we
|
||||
// have a parent edge, bad things might be happening!
|
||||
//
|
||||
|
@ -276,7 +273,8 @@ void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
|
|||
"cannot be in bfcache");
|
||||
|
||||
RefPtr<BrowsingContext> kungFuDeathGrip(this);
|
||||
RefPtr<BrowsingContext> newParent(container->GetBrowsingContext());
|
||||
RefPtr<BrowsingContext> newParent(
|
||||
aEmbedder->OwnerDoc()->GetBrowsingContext());
|
||||
mParent->mChildren.RemoveElement(this);
|
||||
if (newParent) {
|
||||
newParent->mChildren.AppendElement(this);
|
||||
|
@ -286,18 +284,9 @@ void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
|
|||
|
||||
nsCOMPtr<nsPIDOMWindowInner> inner =
|
||||
do_QueryInterface(aEmbedder->GetOwnerGlobal());
|
||||
if (inner) {
|
||||
RefPtr<WindowGlobalChild> wgc = inner->GetWindowGlobalChild();
|
||||
|
||||
// If we're in-process, synchronously perform the update to ensure we
|
||||
// don't get out of sync.
|
||||
// XXX(nika): This is super gross, and I don't like it one bit.
|
||||
if (RefPtr<WindowGlobalParent> wgp = wgc->GetParentActor()) {
|
||||
Canonical()->SetEmbedderWindowGlobal(wgp);
|
||||
} else {
|
||||
wgc->SendDidEmbedBrowsingContext(this);
|
||||
}
|
||||
}
|
||||
SetEmbedderInnerWindowId(inner ? inner->WindowID() : 0);
|
||||
} else {
|
||||
SetEmbedderInnerWindowId(0);
|
||||
}
|
||||
|
||||
mEmbedderElement = aEmbedder;
|
||||
|
@ -1026,9 +1015,8 @@ bool BrowsingContext::Transaction::Validate(BrowsingContext* aBrowsingContext,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BrowsingContext::Transaction::Validate(BrowsingContext* aBrowsingContext,
|
||||
ContentParent* aSource,
|
||||
uint64_t aEpoch) {
|
||||
bool BrowsingContext::Transaction::ValidateEpochs(
|
||||
BrowsingContext* aBrowsingContext, uint64_t aEpoch) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess(),
|
||||
"Should only be called in content process");
|
||||
|
||||
|
@ -1039,7 +1027,11 @@ bool BrowsingContext::Transaction::Validate(BrowsingContext* aBrowsingContext,
|
|||
}
|
||||
#include "mozilla/dom/BrowsingContextFieldList.h"
|
||||
|
||||
return Validate(aBrowsingContext, aSource);
|
||||
// NOTE: We don't call MaySet in a content process for messages sent from over
|
||||
// IPC. The message has already been validated in both the original sending
|
||||
// process (to get good errors), and in the parent process (to enforce trust).
|
||||
mValidated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BrowsingContext::Transaction::Apply(BrowsingContext* aBrowsingContext) {
|
||||
|
@ -1124,6 +1116,60 @@ void BrowsingContext::DidSetMuted() {
|
|||
});
|
||||
}
|
||||
|
||||
bool BrowsingContext::MaySetEmbedderInnerWindowId(const uint64_t& aValue,
|
||||
ContentParent* aSource) {
|
||||
// Generally allow clearing this. We may want to be more precise about this
|
||||
// check in the future.
|
||||
if (aValue == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we don't have a specified source, we're the setting process. The window
|
||||
// which we're setting this to must be in-process.
|
||||
RefPtr<BrowsingContext> impliedParent;
|
||||
if (!aSource) {
|
||||
nsGlobalWindowInner* innerWindow =
|
||||
nsGlobalWindowInner::GetInnerWindowWithId(aValue);
|
||||
if (NS_WARN_IF(!innerWindow)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
impliedParent = innerWindow->GetBrowsingContext();
|
||||
}
|
||||
|
||||
// If in the parent process, double-check ownership and WindowGlobalParent as
|
||||
// well.
|
||||
if (XRE_IsParentProcess()) {
|
||||
RefPtr<WindowGlobalParent> wgp =
|
||||
WindowGlobalParent::GetByInnerWindowId(aValue);
|
||||
if (NS_WARN_IF(!wgp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deduce the implied parent from the WindowGlobalParent actor.
|
||||
if (impliedParent) {
|
||||
MOZ_ASSERT(impliedParent == wgp->BrowsingContext());
|
||||
}
|
||||
impliedParent = wgp->BrowsingContext();
|
||||
|
||||
// Double-check ownership if we aren't the setter.
|
||||
if (aSource &&
|
||||
!impliedParent->Canonical()->IsOwnedByProcess(aSource->ChildID()) &&
|
||||
aSource->ChildID() !=
|
||||
impliedParent->Canonical()->GetInFlightProcessId()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If we would have an invalid implied parent, something has gone wrong.
|
||||
MOZ_ASSERT(impliedParent);
|
||||
if (NS_WARN_IF(mParent && mParent != impliedParent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
|
|
|
@ -375,14 +375,17 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
|
|||
nsresult Commit(BrowsingContext* aOwner);
|
||||
|
||||
// This method should be called before invoking `Apply` on this transaction
|
||||
// object.
|
||||
// object in the original process, and the parent process.
|
||||
//
|
||||
// |aSource| is the ContentParent which is performing the mutation in the
|
||||
// parent process.
|
||||
MOZ_MUST_USE bool Validate(BrowsingContext* aOwner, ContentParent* aSource,
|
||||
uint64_t aEpoch);
|
||||
MOZ_MUST_USE bool Validate(BrowsingContext* aOwner, ContentParent* aSource);
|
||||
|
||||
// This method shold be called before invoking `Apply` on this transaction
|
||||
// object in child processes messaged by the parent process. It clears out
|
||||
// out-of-date sets resolving epoch conflicts.
|
||||
MOZ_MUST_USE bool ValidateEpochs(BrowsingContext* aOwner, uint64_t aEpoch);
|
||||
|
||||
// You probably don't want to directly call this method - instead call
|
||||
// `Commit`, which will perform the necessary synchronization.
|
||||
//
|
||||
|
@ -522,6 +525,9 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
|
|||
// volume of all media elements.
|
||||
void DidSetMuted();
|
||||
|
||||
bool MaySetEmbedderInnerWindowId(const uint64_t& aValue,
|
||||
ContentParent* aSource);
|
||||
|
||||
// Type of BrowsingContent
|
||||
const Type mType;
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@ MOZ_BC_FIELD(OpenerId, uint64_t)
|
|||
|
||||
MOZ_BC_FIELD(OnePermittedSandboxedNavigatorId, uint64_t)
|
||||
|
||||
// Window ID of the inner window which embeds this BrowsingContext.
|
||||
MOZ_BC_FIELD(EmbedderInnerWindowId, uint64_t)
|
||||
|
||||
MOZ_BC_FIELD(HadOriginalOpener, bool)
|
||||
|
||||
// This field controls whether the browsing context is currently considered to
|
||||
|
|
|
@ -132,15 +132,14 @@ void CanonicalBrowsingContext::SetCurrentWindowGlobal(
|
|||
mCurrentWindowGlobal = aGlobal;
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::SetEmbedderWindowGlobal(
|
||||
WindowGlobalParent* aGlobal) {
|
||||
MOZ_RELEASE_ASSERT(aGlobal, "null embedder");
|
||||
if (RefPtr<BrowsingContext> parent = GetParent()) {
|
||||
MOZ_RELEASE_ASSERT(aGlobal->BrowsingContext() == parent,
|
||||
"Embedder has incorrect browsing context");
|
||||
already_AddRefed<WindowGlobalParent>
|
||||
CanonicalBrowsingContext::GetEmbedderWindowGlobal() const {
|
||||
uint64_t windowId = GetEmbedderInnerWindowId();
|
||||
if (windowId == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mEmbedderWindowGlobal = aGlobal;
|
||||
return WindowGlobalParent::GetByInnerWindowId(windowId);
|
||||
}
|
||||
|
||||
JSObject* CanonicalBrowsingContext::WrapObject(
|
||||
|
@ -151,14 +150,12 @@ JSObject* CanonicalBrowsingContext::WrapObject(
|
|||
void CanonicalBrowsingContext::Traverse(
|
||||
nsCycleCollectionTraversalCallback& cb) {
|
||||
CanonicalBrowsingContext* tmp = this;
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobals, mCurrentWindowGlobal,
|
||||
mEmbedderWindowGlobal);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobals, mCurrentWindowGlobal);
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::Unlink() {
|
||||
CanonicalBrowsingContext* tmp = this;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobals, mCurrentWindowGlobal,
|
||||
mEmbedderWindowGlobal);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobals, mCurrentWindowGlobal);
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() {
|
||||
|
|
|
@ -56,10 +56,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
}
|
||||
void SetCurrentWindowGlobal(WindowGlobalParent* aGlobal);
|
||||
|
||||
WindowGlobalParent* GetEmbedderWindowGlobal() const {
|
||||
return mEmbedderWindowGlobal;
|
||||
}
|
||||
void SetEmbedderWindowGlobal(WindowGlobalParent* aGlobal);
|
||||
already_AddRefed<WindowGlobalParent> GetEmbedderWindowGlobal() const;
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
@ -103,7 +100,6 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
// All live window globals within this browsing context.
|
||||
nsTHashtable<nsRefPtrHashKey<WindowGlobalParent>> mWindowGlobals;
|
||||
RefPtr<WindowGlobalParent> mCurrentWindowGlobal;
|
||||
RefPtr<WindowGlobalParent> mEmbedderWindowGlobal;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -4031,7 +4031,7 @@ mozilla::ipc::IPCResult ContentChild::RecvCommitBrowsingContextTransaction(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (!aTransaction.Validate(aContext, nullptr, aEpoch)) {
|
||||
if (!aTransaction.ValidateEpochs(aContext, aEpoch)) {
|
||||
return IPC_FAIL(this, "Invalid BrowsingContext transaction from Parent");
|
||||
}
|
||||
|
||||
|
|
|
@ -77,10 +77,6 @@ parent:
|
|||
/// Notify the parent that this PWindowGlobal is now the current global.
|
||||
async BecomeCurrentWindowGlobal();
|
||||
|
||||
/// Notify the parent that this PWindowGlobal has embedded the given
|
||||
/// BrowsingContext.
|
||||
async DidEmbedBrowsingContext(BrowsingContext aContext);
|
||||
|
||||
async Destroy();
|
||||
};
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ void WindowGlobalParent::Init(const WindowGlobalInit& aInit) {
|
|||
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
!mBrowsingContext->GetParent() ||
|
||||
mBrowsingContext->GetEmbedderWindowGlobal(),
|
||||
mBrowsingContext->GetEmbedderInnerWindowId(),
|
||||
"When creating a non-root WindowGlobalParent, the WindowGlobalParent "
|
||||
"for our embedder should've already been created.");
|
||||
|
||||
|
@ -165,7 +165,8 @@ bool WindowGlobalParent::IsProcessRoot() {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto* embedder = BrowsingContext()->GetEmbedderWindowGlobal();
|
||||
RefPtr<WindowGlobalParent> embedder =
|
||||
BrowsingContext()->GetEmbedderWindowGlobal();
|
||||
if (NS_WARN_IF(!embedder)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -174,8 +175,7 @@ bool WindowGlobalParent::IsProcessRoot() {
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult WindowGlobalParent::RecvLoadURI(
|
||||
dom::BrowsingContext* aTargetBC,
|
||||
nsDocShellLoadState* aLoadState) {
|
||||
dom::BrowsingContext* aTargetBC, nsDocShellLoadState* aLoadState) {
|
||||
if (!aTargetBC || aTargetBC->IsDiscarded()) {
|
||||
MOZ_LOG(
|
||||
BrowsingContext::GetLog(), LogLevel::Debug,
|
||||
|
@ -195,9 +195,8 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvLoadURI(
|
|||
|
||||
WindowGlobalParent* wgp = aTargetBC->Canonical()->GetCurrentWindowGlobal();
|
||||
if (!wgp) {
|
||||
MOZ_LOG(
|
||||
BrowsingContext::GetLog(), LogLevel::Debug,
|
||||
("ParentIPC: Target BrowsingContext has no WindowGlobalParent"));
|
||||
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
||||
("ParentIPC: Target BrowsingContext has no WindowGlobalParent"));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -303,13 +302,6 @@ bool WindowGlobalParent::IsCurrentGlobal() {
|
|||
return CanSend() && mBrowsingContext->GetCurrentWindowGlobal() == this;
|
||||
}
|
||||
|
||||
IPCResult WindowGlobalParent::RecvDidEmbedBrowsingContext(
|
||||
dom::BrowsingContext* aContext) {
|
||||
MOZ_ASSERT(aContext);
|
||||
aContext->Canonical()->SetEmbedderWindowGlobal(this);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> WindowGlobalParent::ChangeFrameRemoteness(
|
||||
dom::BrowsingContext* aBc, const nsAString& aRemoteType,
|
||||
uint64_t aPendingSwitchId, ErrorResult& aRv) {
|
||||
|
|
|
@ -151,8 +151,6 @@ class WindowGlobalParent final : public WindowGlobalActor,
|
|||
mozilla::ipc::IPCResult RecvDestroy();
|
||||
mozilla::ipc::IPCResult RecvRawMessage(const JSWindowActorMessageMeta& aMeta,
|
||||
const ClonedMessageData& aData);
|
||||
mozilla::ipc::IPCResult RecvDidEmbedBrowsingContext(
|
||||
dom::BrowsingContext* aContext);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче