Bug 1562264 - Propagate remote/fission flags from parent to child for content window.open() calls, r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D40836
This commit is contained in:
Kashav Madan
2019-08-23 16:06:09 +00:00
parent 45f6e2526a
commit 16e23ab668
4 changed files with 61 additions and 10 deletions

View File

@@ -2081,6 +2081,12 @@ already_AddRefed<RemoteBrowser> ContentChild::CreateBrowser(
if (loadContext && loadContext->UsePrivateBrowsing()) { if (loadContext && loadContext->UsePrivateBrowsing()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW; chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
} }
if (loadContext && loadContext->UseRemoteTabs()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
}
if (loadContext && loadContext->UseRemoteSubframes()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_FISSION_WINDOW;
}
if (docShell->GetAffectPrivateSessionLifetime()) { if (docShell->GetAffectPrivateSessionLifetime()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME; chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
} }

View File

@@ -1187,6 +1187,12 @@ already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
if (loadContext && loadContext->UsePrivateBrowsing()) { if (loadContext && loadContext->UsePrivateBrowsing()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW; chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
} }
if (loadContext && loadContext->UseRemoteTabs()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
}
if (loadContext && loadContext->UseRemoteSubframes()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_FISSION_WINDOW;
}
if (docShell->GetAffectPrivateSessionLifetime()) { if (docShell->GetAffectPrivateSessionLifetime()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME; chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
} }
@@ -3338,12 +3344,12 @@ mozilla::ipc::IPCResult ContentParent::RecvConstructPopupBrowser(
if (!loadContext) { if (!loadContext) {
return IPC_FAIL(this, "Missing Opener LoadContext"); return IPC_FAIL(this, "Missing Opener LoadContext");
} }
if (loadContext->UsePrivateBrowsing()) {
bool isPrivate;
loadContext->GetUsePrivateBrowsing(&isPrivate);
if (isPrivate) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW; chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
} }
if (loadContext->UseRemoteSubframes()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_FISSION_WINDOW;
}
} }
// And because we're allocating a remote browser, of course the // And because we're allocating a remote browser, of course the
@@ -4696,11 +4702,10 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
{ {
// The content process should never be in charge of computing whether or // The content process should never be in charge of computing whether or
// not a window should be private or remote - the parent will do that. // not a window should be private - the parent will do that.
const uint32_t badFlags = nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW | const uint32_t badFlags = nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW | nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW |
nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME | nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
if (!!(aChromeFlags & badFlags)) { if (!!(aChromeFlags & badFlags)) {
return IPC_FAIL(this, "Forbidden aChromeFlags passed"); return IPC_FAIL(this, "Forbidden aChromeFlags passed");
} }
@@ -4709,6 +4714,23 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
BrowserHost* thisBrowserHost = BrowserHost* thisBrowserHost =
thisBrowserParent ? thisBrowserParent->GetBrowserHost() : nullptr; thisBrowserParent ? thisBrowserParent->GetBrowserHost() : nullptr;
MOZ_ASSERT(!thisBrowserParent == !thisBrowserHost); MOZ_ASSERT(!thisBrowserParent == !thisBrowserHost);
// The content process should not have set its remote or fission flags if the
// parent doesn't also have these set.
if (thisBrowserHost) {
nsCOMPtr<nsILoadContext> context = thisBrowserHost->GetLoadContext();
// TODO: This failure condition is more relaxed than it should be, since
// there are some cases where the child process still fails to set the
// correct chrome flags. See bug 1576204.
if (((aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW) &&
!context->UseRemoteTabs()) ||
((aChromeFlags & nsIWebBrowserChrome::CHROME_FISSION_WINDOW) &&
!context->UseRemoteSubframes())) {
return IPC_FAIL(this, "Unexpected aChromeFlags passed");
}
}
nsCOMPtr<nsIContent> frame; nsCOMPtr<nsIContent> frame;
if (thisBrowserParent) { if (thisBrowserParent) {
frame = thisBrowserParent->GetOwnerElement(); frame = thisBrowserParent->GetOwnerElement();

View File

@@ -691,6 +691,20 @@ nsresult nsWindowWatcher::OpenWindowInternal(
MOZ_ASSERT(XRE_IsParentProcess()); MOZ_ASSERT(XRE_IsParentProcess());
chromeFlags |= nsIWebBrowserChrome::CHROME_OPENAS_DIALOG; chromeFlags |= nsIWebBrowserChrome::CHROME_OPENAS_DIALOG;
} }
// Propagate the remote & fission status of the parent window, if available,
// to the child.
if (parentWindow) {
auto* docShell = nsDocShell::Cast(parentWindow->GetDocShell());
if (docShell->UseRemoteTabs()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
}
if (docShell->UseRemoteSubframes()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_FISSION_WINDOW;
}
}
} }
SizeSpec sizeSpec; SizeSpec sizeSpec;
@@ -2472,6 +2486,7 @@ int32_t nsWindowWatcher::GetWindowOpenLocation(nsPIDOMWindowOuter* aParent,
// which might have been automatically flipped by Gecko. // which might have been automatically flipped by Gecko.
int32_t uiChromeFlags = aChromeFlags; int32_t uiChromeFlags = aChromeFlags;
uiChromeFlags &= ~(nsIWebBrowserChrome::CHROME_REMOTE_WINDOW | uiChromeFlags &= ~(nsIWebBrowserChrome::CHROME_REMOTE_WINDOW |
nsIWebBrowserChrome::CHROME_FISSION_WINDOW |
nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW | nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW | nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW |
nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME); nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME);

View File

@@ -282,9 +282,17 @@ add_task(async function test_new_remote_window_flags() {
// as part of the BrowserChild, so we have to check those too. // as part of the BrowserChild, so we have to check those too.
let contentChromeFlags = await getContentChromeFlags(win); let contentChromeFlags = await getContentChromeFlags(win);
assertContentFlags(contentChromeFlags); assertContentFlags(contentChromeFlags);
Assert.ok(
!(contentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW), Assert.equal(
"Should not be remote in the content process." parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW,
contentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW,
"Should have matching remote value in parent and content"
);
Assert.equal(
parentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_FISSION_WINDOW,
contentChromeFlags & Ci.nsIWebBrowserChrome.CHROME_FISSION_WINDOW,
"Should have matching fission value in parent and content"
); );
await BrowserTestUtils.closeWindow(win); await BrowserTestUtils.closeWindow(win);