Bug 1474662 - Add chromeOuterWindowID to TabContext. r?kmag, r?baku
MozReview-Commit-ID: CAwDMW6rhE7
--- a/dom/base/ContentFrameMessageManager.h
+++ b/dom/base/ContentFrameMessageManager.h
@@ -47,16 +47,17 @@ public:
{
JS::Rooted<JSObject*> thisObj(aCx, GetWrapper());
GetSystemBindingNames(aCx, thisObj, aNames, aEnumerableOnly, aRv);
}
virtual already_AddRefed<nsPIDOMWindowOuter> GetContent(ErrorResult& aError) = 0;
virtual already_AddRefed<nsIDocShell> GetDocShell(ErrorResult& aError) = 0;
virtual already_AddRefed<nsIEventTarget> GetTabEventTarget() = 0;
+ virtual uint64_t ChromeOuterWindowID() = 0;
nsFrameMessageManager* GetMessageManager()
{
return mMessageManager;
}
void DisconnectMessageManager()
{
mMessageManager->Disconnect();
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -3341,29 +3341,37 @@ nsFrameLoader::GetNewTabContext(MutableT
nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(docShell);
NS_ENSURE_STATE(parentContext);
bool isPrivate = parentContext->UsePrivateBrowsing();
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
UIStateChangeType showAccelerators = UIStateChangeType_NoChange;
UIStateChangeType showFocusRings = UIStateChangeType_NoChange;
+ uint64_t chromeOuterWindowID = 0;
+
nsIDocument* doc = mOwnerContent->OwnerDoc();
if (doc) {
nsCOMPtr<nsPIWindowRoot> root = nsContentUtils::GetWindowRoot(doc);
if (root) {
showAccelerators =
root->ShowAccelerators() ? UIStateChangeType_Set : UIStateChangeType_Clear;
showFocusRings =
root->ShowFocusRings() ? UIStateChangeType_Set : UIStateChangeType_Clear;
+
+ nsPIDOMWindowOuter* outerWin = root->GetWindow();
+ if (outerWin) {
+ chromeOuterWindowID = outerWin->WindowID();
+ }
}
}
bool tabContextUpdated =
aTabContext->SetTabContext(OwnerIsMozBrowserFrame(),
+ chromeOuterWindowID,
showAccelerators,
showFocusRings,
attrs,
presentationURLStr);
NS_ENSURE_STATE(tabContextUpdated);
return NS_OK;
}
--- a/dom/base/nsInProcessTabChildGlobal.cpp
+++ b/dom/base/nsInProcessTabChildGlobal.cpp
@@ -209,16 +209,38 @@ nsInProcessTabChildGlobal::GetContent(Er
already_AddRefed<nsIEventTarget>
nsInProcessTabChildGlobal::GetTabEventTarget()
{
nsCOMPtr<nsIEventTarget> target = GetMainThreadEventTarget();
return target.forget();
}
+uint64_t
+nsInProcessTabChildGlobal::ChromeOuterWindowID()
+{
+ if (!mDocShell) {
+ return 0;
+ }
+
+ nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(mDocShell);
+ nsCOMPtr<nsIDocShellTreeItem> root;
+ nsresult rv = item->GetRootTreeItem(getter_AddRefs(root));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return 0;
+ }
+
+ nsPIDOMWindowOuter* topWin = root->GetWindow();
+ if (!topWin) {
+ return 0;
+ }
+
+ return topWin->WindowID();
+}
+
void
nsInProcessTabChildGlobal::FireUnloadEvent()
{
// We're called from nsDocument::MaybeInitializeFinalizeFrameLoaders, so it
// should be safe to run script.
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
// Don't let the unload event propagate to chrome event handlers.
--- a/dom/base/nsInProcessTabChildGlobal.h
+++ b/dom/base/nsInProcessTabChildGlobal.h
@@ -76,16 +76,17 @@ public:
GetContent(mozilla::ErrorResult& aError) override;
virtual already_AddRefed<nsIDocShell>
GetDocShell(mozilla::ErrorResult& aError) override
{
nsCOMPtr<nsIDocShell> docShell(mDocShell);
return docShell.forget();
}
virtual already_AddRefed<nsIEventTarget> GetTabEventTarget() override;
+ virtual uint64_t ChromeOuterWindowID() override;
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
NS_DECL_NSIINPROCESSCONTENTFRAMEMESSAGEMANAGER
void CacheFrameLoader(nsFrameLoader* aFrameLoader);
--- a/dom/chrome-webidl/MessageManager.webidl
+++ b/dom/chrome-webidl/MessageManager.webidl
@@ -474,16 +474,24 @@ interface ContentFrameMessageManager : E
[Throws]
readonly attribute nsIDocShell? docShell;
/**
* Returns the SchedulerEventTarget corresponding to the TabGroup
* for this frame.
*/
readonly attribute nsIEventTarget? tabEventTarget;
+
+ /**
+ * Returns the outerWindowID of the browser window hosting the frame.
+ * If, for some reason, the frameloader can't be resolved to a browser
+ * window, this will return 0.
+ */
+ readonly attribute long long chromeOuterWindowID;
+
};
// MessageManagerGlobal inherits from SyncMessageSender, which is a real interface, not a
// mixin. This will need to change when we implement mixins according to the current
// WebIDL spec.
ContentFrameMessageManager implements MessageManagerGlobal;
[ChromeOnly, Global, NeedResolve]
interface ContentProcessMessageManager
--- a/dom/ipc/PTabContext.ipdlh
+++ b/dom/ipc/PTabContext.ipdlh
@@ -28,28 +28,31 @@ namespace dom {
//
// It's an error to set isMozBrowserElement == false if opener is a mozbrowser
// element. Such a PopupIPCTabContext should be rejected by code which receives
// it.
struct PopupIPCTabContext
{
PBrowserOrId opener;
bool isMozBrowserElement;
+ uint64_t chromeOuterWindowID;
};
// An IPCTabContext which corresponds to an app, browser, or normal frame.
struct FrameIPCTabContext
{
// The originAttributes dictionary.
OriginAttributes originAttributes;
// Whether this is a mozbrowser frame. <iframe mozbrowser mozapp> and
// <xul:browser> are not considered to be mozbrowser frames.
bool isMozBrowserElement;
+ uint64_t chromeOuterWindowID;
+
// The requested presentation URL.
// This value would be empty if the TabContext isn't created for
// presented content.
nsString presentationURL;
// Keyboard indicator state inherited from the parent.
UIStateChangeType showAccelerators;
UIStateChangeType showFocusRings;
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -3594,16 +3594,25 @@ TabChildGlobal::GetDocShell(ErrorResult&
already_AddRefed<nsIEventTarget>
TabChildGlobal::GetTabEventTarget()
{
nsCOMPtr<nsIEventTarget> target = EventTargetFor(TaskCategory::Other);
return target.forget();
}
+uint64_t
+TabChildGlobal::ChromeOuterWindowID()
+{
+ if (!mTabChild) {
+ return 0;
+ }
+ return mTabChild->ChromeOuterWindowID();
+}
+
nsIPrincipal*
TabChildGlobal::GetPrincipal()
{
if (!mTabChild)
return nullptr;
return mTabChild->GetPrincipal();
}
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -100,16 +100,17 @@ public:
}
bool WrapGlobalObject(JSContext* aCx,
JS::RealmOptions& aOptions,
JS::MutableHandle<JSObject*> aReflector);
virtual already_AddRefed<nsPIDOMWindowOuter> GetContent(ErrorResult& aError) override;
virtual already_AddRefed<nsIDocShell> GetDocShell(ErrorResult& aError) override;
virtual already_AddRefed<nsIEventTarget> GetTabEventTarget() override;
+ virtual uint64_t ChromeOuterWindowID() override;
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
void
GetEventTargetParent(EventChainPreVisitor& aVisitor) override
{
aVisitor.mForceContentDispatch = true;
--- a/dom/ipc/TabContext.cpp
+++ b/dom/ipc/TabContext.cpp
@@ -18,16 +18,17 @@ using namespace mozilla::dom::ipc;
using namespace mozilla::layout;
namespace mozilla {
namespace dom {
TabContext::TabContext()
: mInitialized(false)
, mIsMozBrowserElement(false)
+ , mChromeOuterWindowID(0)
, mJSPluginID(-1)
, mShowAccelerators(UIStateChangeType_NoChange)
, mShowFocusRings(UIStateChangeType_NoChange)
{
}
bool
TabContext::IsMozBrowserElement() const
@@ -54,16 +55,22 @@ TabContext::IsJSPlugin() const
}
int32_t
TabContext::JSPluginId() const
{
return mJSPluginID;
}
+uint64_t
+TabContext::ChromeOuterWindowID() const
+{
+ return mChromeOuterWindowID;
+}
+
bool
TabContext::SetTabContext(const TabContext& aContext)
{
NS_ENSURE_FALSE(mInitialized, false);
*this = aContext;
mInitialized = true;
@@ -77,22 +84,24 @@ TabContext::SetPrivateBrowsingAttributes
}
bool
TabContext::UpdateTabContextAfterSwap(const TabContext& aContext)
{
// This is only used after already initialized.
MOZ_ASSERT(mInitialized);
- // The only permissable change is to `mIsMozBrowserElement`. All other fields
- // must match for the change to be accepted.
+ // The only permissable changes are to `mIsMozBrowserElement` and
+ // mChromeOuterWindowID. All other fields must match for the change
+ // to be accepted.
if (aContext.mOriginAttributes != mOriginAttributes) {
return false;
}
+ mChromeOuterWindowID = aContext.mChromeOuterWindowID;
mIsMozBrowserElement = aContext.mIsMozBrowserElement;
return true;
}
const OriginAttributes&
TabContext::OriginAttributesRef() const
{
return mOriginAttributes;
@@ -113,28 +122,30 @@ TabContext::ShowAccelerators() const
UIStateChangeType
TabContext::ShowFocusRings() const
{
return mShowFocusRings;
}
bool
TabContext::SetTabContext(bool aIsMozBrowserElement,
+ uint64_t aChromeOuterWindowID,
UIStateChangeType aShowAccelerators,
UIStateChangeType aShowFocusRings,
const OriginAttributes& aOriginAttributes,
const nsAString& aPresentationURL)
{
NS_ENSURE_FALSE(mInitialized, false);
// Veryify that app id matches mAppId passed in originAttributes
MOZ_RELEASE_ASSERT(aOriginAttributes.mAppId == NO_APP_ID);
mInitialized = true;
mIsMozBrowserElement = aIsMozBrowserElement;
+ mChromeOuterWindowID = aChromeOuterWindowID;
mOriginAttributes = aOriginAttributes;
mPresentationURL = aPresentationURL;
mShowAccelerators = aShowAccelerators;
mShowFocusRings = aShowFocusRings;
return true;
}
bool
@@ -151,25 +162,27 @@ IPCTabContext
TabContext::AsIPCTabContext() const
{
if (IsJSPlugin()) {
return IPCTabContext(JSPluginFrameIPCTabContext(mJSPluginID));
}
return IPCTabContext(FrameIPCTabContext(mOriginAttributes,
mIsMozBrowserElement,
+ mChromeOuterWindowID,
mPresentationURL,
mShowAccelerators,
mShowFocusRings));
}
MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
: mInvalidReason(nullptr)
{
bool isMozBrowserElement = false;
+ uint64_t chromeOuterWindowID = 0;
int32_t jsPluginId = -1;
OriginAttributes originAttributes;
nsAutoString presentationURL;
UIStateChangeType showAccelerators = UIStateChangeType_NoChange;
UIStateChangeType showFocusRings = UIStateChangeType_NoChange;
switch(aParams.type()) {
case IPCTabContext::TPopupIPCTabContext: {
@@ -211,30 +224,32 @@ MaybeInvalidTabContext::MaybeInvalidTabC
// our opener is browser element, we must be a new DOM window
// opened by it. In that case we inherit our containing app ID
// (if any).
//
// Otherwise, we're a new app window and we inherit from our
// opener app.
isMozBrowserElement = ipcContext.isMozBrowserElement();
originAttributes = context->mOriginAttributes;
+ chromeOuterWindowID = ipcContext.chromeOuterWindowID();
break;
}
case IPCTabContext::TJSPluginFrameIPCTabContext: {
const JSPluginFrameIPCTabContext &ipcContext =
aParams.get_JSPluginFrameIPCTabContext();
jsPluginId = ipcContext.jsPluginId();
break;
}
case IPCTabContext::TFrameIPCTabContext: {
const FrameIPCTabContext &ipcContext =
aParams.get_FrameIPCTabContext();
isMozBrowserElement = ipcContext.isMozBrowserElement();
+ chromeOuterWindowID = ipcContext.chromeOuterWindowID();
presentationURL = ipcContext.presentationURL();
showAccelerators = ipcContext.showAccelerators();
showFocusRings = ipcContext.showFocusRings();
originAttributes = ipcContext.originAttributes();
break;
}
case IPCTabContext::TUnsafeIPCTabContext: {
// XXXcatalinb: This used *only* by ServiceWorkerClients::OpenWindow.
@@ -253,16 +268,17 @@ MaybeInvalidTabContext::MaybeInvalidTabC
}
}
bool rv;
if (jsPluginId >= 0) {
rv = mTabContext.SetTabContextForJSPluginFrame(jsPluginId);
} else {
rv = mTabContext.SetTabContext(isMozBrowserElement,
+ chromeOuterWindowID,
showAccelerators,
showFocusRings,
originAttributes,
presentationURL);
}
if (!rv) {
mInvalidReason = "Couldn't initialize TabContext.";
}
--- a/dom/ipc/TabContext.h
+++ b/dom/ipc/TabContext.h
@@ -61,16 +61,18 @@ public:
* IsMozBrowserElement(). Returns false for <xul:browser>, which isn't a
* mozbrowser.
*/
bool IsMozBrowser() const;
bool IsJSPlugin() const;
int32_t JSPluginId() const;
+ uint64_t ChromeOuterWindowID() const;
+
/**
* OriginAttributesRef() returns the OriginAttributes of this frame to
* the caller. This is used to store any attribute associated with the frame's
* docshell.
*/
const OriginAttributes& OriginAttributesRef() const;
/**
@@ -100,16 +102,17 @@ protected:
bool SetTabContext(const TabContext& aContext);
/**
* Set the tab context's origin attributes to a private browsing value.
*/
void SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing);
bool SetTabContext(bool aIsMozBrowserElement,
+ uint64_t aChromeOuterWindowID,
UIStateChangeType aShowAccelerators,
UIStateChangeType aShowFocusRings,
const OriginAttributes& aOriginAttributes,
const nsAString& aPresentationURL);
/**
* Modify this TabContext to match the given TabContext. This is a special
* case triggered by nsFrameLoader::SwapWithOtherRemoteLoader which may have
@@ -138,16 +141,21 @@ private:
/**
* Whether this TabContext corresponds to a mozbrowser.
*
* <iframe mozbrowser> and <xul:browser> are not considered to be
* mozbrowser elements.
*/
bool mIsMozBrowserElement;
+ /**
+ * The outerWindowID of the window hosting the remote frameloader.
+ */
+ uint64_t mChromeOuterWindowID;
+
int32_t mJSPluginID;
/**
* OriginAttributes of the top level tab docShell
*/
OriginAttributes mOriginAttributes;
/**
@@ -172,22 +180,24 @@ class MutableTabContext : public TabCont
public:
bool SetTabContext(const TabContext& aContext)
{
return TabContext::SetTabContext(aContext);
}
bool
SetTabContext(bool aIsMozBrowserElement,
+ uint64_t aChromeOuterWindowID,
UIStateChangeType aShowAccelerators,
UIStateChangeType aShowFocusRings,
const OriginAttributes& aOriginAttributes,
const nsAString& aPresentationURL = EmptyString())
{
return TabContext::SetTabContext(aIsMozBrowserElement,
+ aChromeOuterWindowID,
aShowAccelerators,
aShowFocusRings,
aOriginAttributes,
aPresentationURL);
}
bool SetTabContextForJSPluginFrame(uint32_t aJSPluginID)
{