Bug 1522637 - Part 4: Support browsers in globals without gMultiProcessBrowser, r=qdot

Depends on D18604

Differential Revision: https://phabricator.services.mozilla.com/D18605

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2019-02-14 15:14:01 +00:00
Родитель 438cbbeca1
Коммит 60ebf8f8f0
1 изменённых файлов: 52 добавлений и 18 удалений

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

@ -2286,6 +2286,8 @@ var SessionStoreInternal = {
* processes. * processes.
*/ */
async _doProcessSwitch(aBrowser, aRemoteType, aChannel, aSwitchId) { async _doProcessSwitch(aBrowser, aRemoteType, aChannel, aSwitchId) {
debug(`[process-switch]: performing switch from ${aBrowser.remoteType} to ${aRemoteType}`);
// Don't try to switch tabs before delayed startup is completed. // Don't try to switch tabs before delayed startup is completed.
await aBrowser.ownerGlobal.delayedStartupPromise; await aBrowser.ownerGlobal.delayedStartupPromise;
@ -2309,7 +2311,9 @@ var SessionStoreInternal = {
} }
// Tell our caller to redirect the load into this newly created process. // Tell our caller to redirect the load into this newly created process.
return aBrowser.frameLoader.tabParent; let tabParent = aBrowser.frameLoader.tabParent;
debug(`[process-switch]: new tabID: ${tabParent.tabId}`);
return tabParent;
}, },
// Examine the channel response to see if we should change the process // Examine the channel response to see if we should change the process
@ -2323,17 +2327,21 @@ var SessionStoreInternal = {
return; // Not a document load. return; // Not a document load.
} }
// Check that this is a toplevel document load.
let cpType = aChannel.loadInfo.externalContentPolicyType; let cpType = aChannel.loadInfo.externalContentPolicyType;
let toplevel = cpType == Ci.nsIContentPolicy.TYPE_DOCUMENT; let toplevel = cpType == Ci.nsIContentPolicy.TYPE_DOCUMENT;
if (!toplevel) { if (!toplevel) {
return; // Not loading a toplevel document. debug(`[process-switch]: non-toplevel - ignoring`);
return;
} }
// Check that the document has a corresponding BrowsingContext.
let browsingContext = toplevel let browsingContext = toplevel
? aChannel.loadInfo.browsingContext ? aChannel.loadInfo.browsingContext
: aChannel.loadInfo.frameBrowsingContext; : aChannel.loadInfo.frameBrowsingContext;
if (!browsingContext) { if (!browsingContext) {
return; // Not loading in a browsing context. debug(`[process-switch]: no BrowsingContext - ignoring`);
return;
} }
// Get principal for a document already loaded in the BrowsingContext. // Get principal for a document already loaded in the BrowsingContext.
@ -2342,34 +2350,60 @@ var SessionStoreInternal = {
currentPrincipal = browsingContext.currentWindowGlobal.documentPrincipal; currentPrincipal = browsingContext.currentWindowGlobal.documentPrincipal;
} }
let parentChannel = aChannel.notificationCallbacks // Ensure we have an nsIParentChannel listener for a remote load.
.getInterface(Ci.nsIParentChannel); let parentChannel;
if (!parentChannel) { try {
return; // Not an actor channel parentChannel = aChannel.notificationCallbacks
.getInterface(Ci.nsIParentChannel);
} catch (e) {
debug(`[process-switch]: No nsIParentChannel callback - ignoring`);
return;
} }
let tabParent = parentChannel.QueryInterface(Ci.nsIInterfaceRequestor) // Ensure we have a nsITabParent for our remote load.
.getInterface(Ci.nsITabParent); let tabParent;
if (!tabParent || !tabParent.ownerElement) { try {
console.warn("warning: Missing tabParent"); tabParent = parentChannel.QueryInterface(Ci.nsIInterfaceRequestor)
return; // Not an embedded browsing context .getInterface(Ci.nsITabParent);
} catch (e) {
debug(`[process-switch]: No nsITabParent for channel - ignoring`);
return;
} }
// Ensure we're loaded in a regular tabbrowser environment, and can swap processes.
let browser = tabParent.ownerElement; let browser = tabParent.ownerElement;
if (browser.tagName !== "browser") { if (!browser) {
console.warn("warning: Not a xul:browser element:", browser.tagName); debug(`[process-switch]: TabParent has no ownerElement - ignoring`);
return; // Not a vanilla xul:browser element performing embedding.
} }
let tabbrowser = browser.ownerGlobal.gBrowser;
if (!tabbrowser) {
debug(`[process-switch]: cannot find tabbrowser for loading tab - ignoring`);
return;
}
let tab = tabbrowser.getTabForBrowser(browser);
if (!tab) {
debug(`[process-switch]: not a normal tab, so cannot swap processes - ignoring`);
return;
}
// Determine the process type the load should be performed in.
let resultPrincipal = let resultPrincipal =
Services.scriptSecurityManager.getChannelResultPrincipal(aChannel); Services.scriptSecurityManager.getChannelResultPrincipal(aChannel);
let useRemoteTabs = browser.ownerGlobal.gMultiProcessBrowser;
let remoteType = E10SUtils.getRemoteTypeForPrincipal(resultPrincipal, let remoteType = E10SUtils.getRemoteTypeForPrincipal(resultPrincipal,
useRemoteTabs, true,
browser.remoteType, browser.remoteType,
currentPrincipal); currentPrincipal);
if (browser.remoteType == remoteType) { if (browser.remoteType == remoteType) {
return; // Already in compatible process. debug(`[process-switch]: type (${remoteType}) is compatible - ignoring`);
return;
}
if (remoteType == E10SUtils.NOT_REMOTE ||
browser.remoteType == E10SUtils.NOT_REMOTE) {
debug(`[process-switch]: non-remote source/target - ignoring`);
return;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------