Bug 1580766 - Move BrowserId to nsFrameLoaderOwner, r=kmag

This makes it easier to handle both <xul:browser> and <iframe mozbrowser>
frameloader swaps.

Depends on D56245

Differential Revision: https://phabricator.services.mozilla.com/D77911
This commit is contained in:
Kashav Madan
2020-06-08 21:58:47 +00:00
parent 20ed8e3608
commit 6946bdca21
6 changed files with 39 additions and 61 deletions

View File

@@ -50,6 +50,7 @@
#include "nsGlobalWindowOuter.h" #include "nsGlobalWindowOuter.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsQueryObject.h"
#include "nsSandboxFlags.h" #include "nsSandboxFlags.h"
#include "nsScriptError.h" #include "nsScriptError.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
@@ -487,27 +488,24 @@ void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
Transaction txn; Transaction txn;
txn.SetEmbedderElementType(Some(aEmbedder->LocalName())); txn.SetEmbedderElementType(Some(aEmbedder->LocalName()));
if (RefPtr<XULFrameElement> xulFrame = // We don't care about browser Ids for chrome-type BrowsingContexts.
XULFrameElement::FromNode(aEmbedder)) { if (RefPtr<nsFrameLoaderOwner> owner = do_QueryObject(aEmbedder);
!IsChrome() && owner) {
uint64_t browserId = GetBrowserId(); uint64_t browserId = GetBrowserId();
uint64_t frameBrowserId = xulFrame->BrowserId(); uint64_t frameBrowserId = owner->GetBrowserId();
MOZ_DIAGNOSTIC_ASSERT(browserId != 0);
if (browserId != 0 && frameBrowserId == 0) { if (frameBrowserId == 0) {
// We'll arrive here if we're a top-level BrowsingContext for a window // We'll arrive here if we're a top-level BrowsingContext for a window
// or tab that was opened in a content process. There should be no // or tab that was opened in a content process. There should be no
// children to update at this point. This Id was generated in // children to update at this point. This Id was generated in
// ContentChild::ProvideWindowCommon. // ContentChild::ProvideWindowCommon.
MOZ_DIAGNOSTIC_ASSERT(IsTopContent()); MOZ_DIAGNOSTIC_ASSERT(IsTopContent());
MOZ_DIAGNOSTIC_ASSERT(Children().IsEmpty()); MOZ_DIAGNOSTIC_ASSERT(Children().IsEmpty());
xulFrame->SetBrowserId(browserId); owner->SetBrowserId(browserId);
} else if (browserId == 0 && frameBrowserId == 0) {
// We don't set a browser Id for chrome-type BrowsingContexts.
// XXX: Should we?
MOZ_DIAGNOSTIC_ASSERT(IsChrome());
} else { } else {
// In any other scenario, we would've inherited or generated an Id in // We would've inherited or generated an Id in CreateBrowsingContext.
// CreateBrowsingContext. MOZ_DIAGNOSTIC_ASSERT(browserId == frameBrowserId);
MOZ_DIAGNOSTIC_ASSERT(browserId != 0 && browserId == frameBrowserId);
} }
} }
@@ -2403,7 +2401,7 @@ void BrowsingContext::DidSet(FieldIndex<IDX_HasSessionHistory>,
bool BrowsingContext::CanSet(FieldIndex<IDX_BrowserId>, const uint32_t& aValue, bool BrowsingContext::CanSet(FieldIndex<IDX_BrowserId>, const uint32_t& aValue,
ContentParent* aSource) { ContentParent* aSource) {
// Should only be able to set if the ID is not already set. // Should only be able to set if the ID is not already set.
return GetBrowserId() == 0 && Children().IsEmpty() && !GetParent(); return GetBrowserId() == 0 && IsTop() && Children().IsEmpty();
} }
} // namespace dom } // namespace dom

View File

@@ -400,6 +400,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
bool UseGlobalHistory() const { return GetUseGlobalHistory(); } bool UseGlobalHistory() const { return GetUseGlobalHistory(); }
uint64_t BrowserId() const { return GetBrowserId(); }
bool IsLoading(); bool IsLoading();
// ScreenOrientation related APIs // ScreenOrientation related APIs
@@ -422,9 +424,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
void SetAllowContentRetargeting(bool aAllowContentRetargeting); void SetAllowContentRetargeting(bool aAllowContentRetargeting);
// Needed for the webidl property
uint64_t BrowserId() const { return GetBrowserId(); }
// Using the rules for choosing a browsing context we try to find // Using the rules for choosing a browsing context we try to find
// the browsing context with the given name in the set of // the browsing context with the given name in the set of
// transitively reachable browsing contexts. Performs access control // transitively reachable browsing contexts. Performs access control

View File

@@ -297,7 +297,7 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
// By default we just use the same browserId as the parent. // By default we just use the same browserId as the parent.
uint64_t browserId = parentBC->GetBrowserId(); uint64_t browserId = parentBC->GetBrowserId();
RefPtr<XULFrameElement> xulFrame = XULFrameElement::FromNode(aOwner); RefPtr<nsFrameLoaderOwner> owner = do_QueryObject(aOwner);
// Create our BrowsingContext without immediately attaching it. It's possible // Create our BrowsingContext without immediately attaching it. It's possible
// that no DocShell or remote browser will ever be created for this // that no DocShell or remote browser will ever be created for this
@@ -306,11 +306,10 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
// it will wind up attached as a child of the currently active inner window // it will wind up attached as a child of the currently active inner window
// for the BrowsingContext, and cause no end of trouble. // for the BrowsingContext, and cause no end of trouble.
if (IsTopContent(parentBC, aOwner)) { if (IsTopContent(parentBC, aOwner)) {
// Transitioning into a new content tree means we want a new browserId. if (owner && owner->GetBrowserId() != 0) {
if (xulFrame && xulFrame->BrowserId() != 0) {
// This frame has already been assigned an Id. This can happen for example // This frame has already been assigned an Id. This can happen for example
// if a frame is re-inserted into the DOM (i.e. on a remoteness change). // if a frame is re-inserted into the DOM (i.e. on a remoteness change).
browserId = xulFrame->BrowserId(); browserId = owner->GetBrowserId();
// This implies that we do not support changing a frame's "type" // This implies that we do not support changing a frame's "type"
// attribute. Doing so would mean needing to change the browser Id for the // attribute. Doing so would mean needing to change the browser Id for the
@@ -318,9 +317,8 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
MOZ_DIAGNOSTIC_ASSERT(browserId != parentBC->GetBrowserId()); MOZ_DIAGNOSTIC_ASSERT(browserId != parentBC->GetBrowserId());
} else { } else {
browserId = nsContentUtils::GenerateBrowserId(); browserId = nsContentUtils::GenerateBrowserId();
if (owner) {
if (xulFrame) { owner->SetBrowserId(browserId);
xulFrame->SetBrowserId(browserId);
} }
} }
@@ -332,10 +330,10 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
MOZ_ASSERT(!aOpenWindowInfo, MOZ_ASSERT(!aOpenWindowInfo,
"Can't have openWindowInfo for non-toplevel context"); "Can't have openWindowInfo for non-toplevel context");
if (xulFrame) { if (owner) {
MOZ_DIAGNOSTIC_ASSERT(xulFrame->BrowserId() == 0 || MOZ_DIAGNOSTIC_ASSERT(owner->GetBrowserId() == 0 ||
xulFrame->BrowserId() == browserId); owner->GetBrowserId() == browserId);
xulFrame->SetBrowserId(browserId); owner->SetBrowserId(browserId);
} }
return BrowsingContext::CreateDetached(parentInner, nullptr, frameName, return BrowsingContext::CreateDetached(parentInner, nullptr, frameName,
@@ -1285,16 +1283,11 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
MaybeUpdatePrimaryBrowserParent(eBrowserParentRemoved); MaybeUpdatePrimaryBrowserParent(eBrowserParentRemoved);
aOther->MaybeUpdatePrimaryBrowserParent(eBrowserParentRemoved); aOther->MaybeUpdatePrimaryBrowserParent(eBrowserParentRemoved);
RefPtr<XULFrameElement> ourXulFrame = XULFrameElement::FromNode(ourContent); // Setting the owner content does checks that the browsing context's browser
RefPtr<XULFrameElement> otherXulFrame = // ID matches the element it is being attached to so swap that here.
XULFrameElement::FromNode(otherContent); uint64_t ourBrowserId = aThisOwner->GetBrowserId();
if (ourXulFrame && otherXulFrame) { aThisOwner->SetBrowserId(aOtherOwner->GetBrowserId());
// Setting the owner content does checks that the browsing context's browser aOtherOwner->SetBrowserId(ourBrowserId);
// ID matches the element it is being attached to so swap that here.
uint64_t browserId = otherXulFrame->BrowserId();
otherXulFrame->SetBrowserId(ourXulFrame->BrowserId());
ourXulFrame->SetBrowserId(browserId);
}
SetOwnerContent(otherContent); SetOwnerContent(otherContent);
aOther->SetOwnerContent(ourContent); aOther->SetOwnerContent(ourContent);
@@ -1711,16 +1704,11 @@ nsresult nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
otherDocshell, ourOwner, otherDocshell, ourOwner,
ourBc->IsContent() ? ourChromeEventHandler.get() : nullptr); ourBc->IsContent() ? ourChromeEventHandler.get() : nullptr);
RefPtr<XULFrameElement> ourXulFrame = XULFrameElement::FromNode(ourContent); // Setting the owner content does checks that the browsing context's browser
RefPtr<XULFrameElement> otherXulFrame = // ID matches the element it is being attached to so swap that here.
XULFrameElement::FromNode(otherContent); uint64_t ourBrowserId = aThisOwner->GetBrowserId();
if (ourXulFrame && otherXulFrame) { aThisOwner->SetBrowserId(aOtherOwner->GetBrowserId());
// Setting the owner content does checks that the browsing context's browser aOtherOwner->SetBrowserId(ourBrowserId);
// ID matches the element it is being attached to so swap that here.
uint64_t browserId = otherXulFrame->BrowserId();
otherXulFrame->SetBrowserId(ourXulFrame->BrowserId());
ourXulFrame->SetBrowserId(browserId);
}
// Switch the owner content before we start calling AddTreeItemToTreeOwner. // Switch the owner content before we start calling AddTreeItemToTreeOwner.
// Note that we rely on this to deal with setting mObservingOwnerContent to // Note that we rely on this to deal with setting mObservingOwnerContent to

View File

@@ -58,6 +58,9 @@ class nsFrameLoaderOwner : public nsISupports {
void SubframeCrashed(); void SubframeCrashed();
uint64_t GetBrowserId() { return mBrowserId; }
void SetBrowserId(uint64_t aBrowserId) { mBrowserId = aBrowserId; }
private: private:
bool UseRemoteSubframes(); bool UseRemoteSubframes();
bool ShouldPreserveBrowsingContext( bool ShouldPreserveBrowsingContext(
@@ -86,6 +89,8 @@ class nsFrameLoaderOwner : public nsISupports {
protected: protected:
virtual ~nsFrameLoaderOwner() = default; virtual ~nsFrameLoaderOwner() = default;
RefPtr<nsFrameLoader> mFrameLoader; RefPtr<nsFrameLoader> mFrameLoader;
uint64_t mBrowserId = 0;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsFrameLoaderOwner, NS_FRAMELOADEROWNER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsFrameLoaderOwner, NS_FRAMELOADEROWNER_IID)

View File

@@ -69,13 +69,6 @@ Document* XULFrameElement::GetContentDocument() {
return nullptr; return nullptr;
} }
uint64_t XULFrameElement::BrowserId() { return mBrowserId; }
// Should only be called during initialization or frameloader swaps.
void XULFrameElement::SetBrowserId(uint64_t aBrowserId) {
mBrowserId = aBrowserId;
}
void XULFrameElement::LoadSrc() { void XULFrameElement::LoadSrc() {
if (!IsInUncomposedDoc() || !OwnerDoc()->GetRootElement()) { if (!IsInUncomposedDoc() || !OwnerDoc()->GetRootElement()) {
return; return;

View File

@@ -29,7 +29,7 @@ class BrowsingContext;
class XULFrameElement final : public nsXULElement, public nsFrameLoaderOwner { class XULFrameElement final : public nsXULElement, public nsFrameLoaderOwner {
public: public:
explicit XULFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) explicit XULFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
: nsXULElement(std::move(aNodeInfo)), mBrowserId(0) {} : nsXULElement(std::move(aNodeInfo)) {}
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULFrameElement, nsXULElement) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULFrameElement, nsXULElement)
@@ -39,7 +39,7 @@ class XULFrameElement final : public nsXULElement, public nsFrameLoaderOwner {
already_AddRefed<nsIWebNavigation> GetWebNavigation(); already_AddRefed<nsIWebNavigation> GetWebNavigation();
Nullable<WindowProxyHolder> GetContentWindow(); Nullable<WindowProxyHolder> GetContentWindow();
Document* GetContentDocument(); Document* GetContentDocument();
uint64_t BrowserId(); uint64_t BrowserId() { return GetBrowserId(); }
void SwapFrameLoaders(mozilla::dom::HTMLIFrameElement& aOtherLoaderOwner, void SwapFrameLoaders(mozilla::dom::HTMLIFrameElement& aOtherLoaderOwner,
mozilla::ErrorResult& rv); mozilla::ErrorResult& rv);
@@ -48,9 +48,6 @@ class XULFrameElement final : public nsXULElement, public nsFrameLoaderOwner {
void SwapFrameLoaders(nsFrameLoaderOwner* aOtherLoaderOwner, void SwapFrameLoaders(nsFrameLoaderOwner* aOtherLoaderOwner,
mozilla::ErrorResult& rv); mozilla::ErrorResult& rv);
// Should only be called during initialisation or frameloader swaps.
void SetBrowserId(uint64_t aBrowserId);
// nsIContent // nsIContent
virtual nsresult BindToTree(BindContext&, nsINode& aParent) override; virtual nsresult BindToTree(BindContext&, nsINode& aParent) override;
virtual void UnbindFromTree(bool aNullParent) override; virtual void UnbindFromTree(bool aNullParent) override;
@@ -74,8 +71,6 @@ class XULFrameElement final : public nsXULElement, public nsFrameLoaderOwner {
JS::Handle<JSObject*> aGivenProto) override; JS::Handle<JSObject*> aGivenProto) override;
void LoadSrc(); void LoadSrc();
uint64_t mBrowserId;
}; };
} // namespace dom } // namespace dom