зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1496217 - Support process switching in GeckoView r=esawin
Differential Revision: https://phabricator.services.mozilla.com/D9589
This commit is contained in:
Родитель
1e1cda1530
Коммит
4e683c0261
|
@ -891,3 +891,8 @@ pref("media.navigator.permission.device", true);
|
|||
|
||||
// Allow system add-on updates
|
||||
pref("extensions.systemAddon.update.url", "https://aus5.mozilla.org/update/3/SystemAddons/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
|
||||
|
||||
// E10s stuff. We don't support 'file' or 'priveleged' process types.
|
||||
pref("browser.tabs.remote.separateFileUriProcess", false);
|
||||
pref("browser.tabs.remote.allowLinkedWebInFileUriProcess", true);
|
||||
pref("browser.tabs.remote.separatePrivilegedContentProcess", false);
|
||||
|
|
|
@ -7,6 +7,8 @@ ChromeUtils.import("resource://gre/modules/GeckoViewContentModule.jsm");
|
|||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
|
||||
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
|
||||
ErrorPageEventHandler: "chrome://geckoview/content/ErrorPageEventHandler.js",
|
||||
LoadURIDelegate: "resource://gre/modules/LoadURIDelegate.jsm",
|
||||
});
|
||||
|
@ -15,6 +17,12 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
class GeckoViewNavigationContent extends GeckoViewContentModule {
|
||||
onInit() {
|
||||
docShell.loadURIDelegate = this;
|
||||
|
||||
if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
let tabchild = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsITabChild);
|
||||
tabchild.webBrowserChrome = this;
|
||||
}
|
||||
}
|
||||
|
||||
// nsILoadURIDelegate.
|
||||
|
@ -51,6 +59,45 @@ class GeckoViewNavigationContent extends GeckoViewContentModule {
|
|||
return LoadURIDelegate.handleLoadError(content, this.eventDispatcher,
|
||||
aUri, aError, aErrorModule);
|
||||
}
|
||||
|
||||
// nsIWebBrowserChrome
|
||||
onBeforeLinkTraversal(aOriginalTarget, aLinkURI, aLinkNode, aIsAppTab) {
|
||||
debug `onBeforeLinkTraversal ${aLinkURI.displaySpec}`;
|
||||
return BrowserUtils.onBeforeLinkTraversal(aOriginalTarget, aLinkURI, aLinkNode, aIsAppTab);
|
||||
}
|
||||
|
||||
// nsIWebBrowserChrome
|
||||
shouldLoadURI(aDocShell, aURI, aReferrer, aHasPostData, aTriggeringPrincipal) {
|
||||
debug `shouldLoadURI ${aURI.displaySpec}`;
|
||||
|
||||
// We currently only support one remoteType, "web", so we only need to bail out
|
||||
// if we want to load this URI in the parent.
|
||||
// const remoteType = E10SUtils.getRemoteTypeForURIObject(aURI, true);
|
||||
// if (!remoteType) {
|
||||
// E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, false);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer, aHasPostData)) {
|
||||
E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// nsIWebBrowserChrome
|
||||
shouldLoadURIInThisProcess(aURI) {
|
||||
debug `shouldLoadURIInThisProcess ${aURI.displaySpec}`;
|
||||
return E10SUtils.shouldLoadURIInThisProcess(aURI);
|
||||
}
|
||||
|
||||
// nsIWebBrowserChrome
|
||||
reloadInFreshProcess(aDocShell, aURI, aReferrer, aTriggeringPrincipal, aLoadFlags) {
|
||||
debug `reloadInFreshProcess ${aURI.displaySpec}`;
|
||||
E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, true, aLoadFlags);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
let {debug, warn} = GeckoViewNavigationContent.initLogging("GeckoViewNavigation");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
|
||||
EventDispatcher: "resource://gre/modules/Messaging.jsm",
|
||||
GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
|
@ -98,6 +99,64 @@ var ModuleManager = {
|
|||
this._modules.forEach(aCallback, this);
|
||||
},
|
||||
|
||||
updateRemoteType(aRemoteType) {
|
||||
debug `updateRemoteType remoteType=${aRemoteType}`;
|
||||
|
||||
const currentRemoteType = this.browser.getAttribute("remoteType");
|
||||
|
||||
if (aRemoteType && !this.settings.useMultiprocess) {
|
||||
warn `Tried to create a remote browser in multiprocess mode`;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentRemoteType === aRemoteType) {
|
||||
// We're already using a child process of the correct type.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we're switching the remoteness (value of "remote" attr).
|
||||
debug `updateRemoteType: changing from '${currentRemoteType}' to '${aRemoteType}'`;
|
||||
|
||||
this.forEach(module => {
|
||||
if (module.enabled && module.impl) {
|
||||
module.impl.onDisable();
|
||||
}
|
||||
});
|
||||
|
||||
this.forEach(module => {
|
||||
if (module.impl) {
|
||||
module.impl.onDestroyBrowser();
|
||||
}
|
||||
});
|
||||
|
||||
const parent = this.browser.parentNode;
|
||||
this.browser.remove();
|
||||
if (aRemoteType) {
|
||||
this.browser.setAttribute("remote", "true");
|
||||
this.browser.setAttribute("remoteType", aRemoteType);
|
||||
} else {
|
||||
this.browser.setAttribute("remote", "false");
|
||||
this.browser.removeAttribute("remoteType");
|
||||
}
|
||||
|
||||
this.forEach(module => {
|
||||
if (module.impl) {
|
||||
module.impl.onInitBrowser();
|
||||
}
|
||||
});
|
||||
|
||||
parent.appendChild(this.browser);
|
||||
|
||||
this.forEach(module => {
|
||||
if (module.enabled && module.impl) {
|
||||
module.impl.onEnable();
|
||||
}
|
||||
});
|
||||
|
||||
this.browser.focus();
|
||||
return true;
|
||||
},
|
||||
|
||||
_updateSettings(aSettings) {
|
||||
Object.assign(this._settings, aSettings);
|
||||
this._frozenSettings = Object.freeze(Object.assign({}, this._settings));
|
||||
|
@ -304,6 +363,13 @@ function createBrowser() {
|
|||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("primary", "true");
|
||||
browser.setAttribute("flex", "1");
|
||||
|
||||
const settings = window.arguments[0].QueryInterface(Ci.nsIAndroidView).initData.settings;
|
||||
if (settings.useMultiprocess) {
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("remoteType", E10SUtils.DEFAULT_REMOTE_TYPE);
|
||||
}
|
||||
|
||||
return browser;
|
||||
}
|
||||
|
||||
|
|
|
@ -973,4 +973,15 @@ class NavigationDelegateTest : BaseSessionTest() {
|
|||
sessionRule.session.waitUntilCalled(GeckoSession.NavigationDelegate::class,
|
||||
"onNewSession")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun processSwitching() {
|
||||
// This loads in the parent process
|
||||
mainSession.loadUri("about:config")
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
// This will load a page in the child
|
||||
mainSession.loadTestPath(HELLO_HTML_PATH)
|
||||
sessionRule.waitForPageStop()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,28 +29,35 @@ class GeckoViewModule {
|
|||
}
|
||||
|
||||
get window() {
|
||||
return this._info.manager.window;
|
||||
return this.moduleManager.window;
|
||||
}
|
||||
|
||||
get browser() {
|
||||
return this._info.manager.browser;
|
||||
return this.moduleManager.browser;
|
||||
}
|
||||
|
||||
get messageManager() {
|
||||
return this._info.manager.messageManager;
|
||||
return this.moduleManager.messageManager;
|
||||
}
|
||||
|
||||
get eventDispatcher() {
|
||||
return this._info.manager.eventDispatcher;
|
||||
return this.moduleManager.eventDispatcher;
|
||||
}
|
||||
|
||||
get settings() {
|
||||
return this._info.manager.settings;
|
||||
return this.moduleManager.settings;
|
||||
}
|
||||
|
||||
get moduleManager() {
|
||||
return this._info.manager;
|
||||
}
|
||||
|
||||
// Override to initialize the browser before it is bound to the window.
|
||||
onInitBrowser() {}
|
||||
|
||||
// Override to cleanup when the browser is destroyed.
|
||||
onDestroyBrowser() {}
|
||||
|
||||
// Override to initialize module.
|
||||
onInit() {}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm");
|
|||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
|
||||
Utils: "resource://gre/modules/sessionstore/Utils.jsm",
|
||||
LoadURIDelegate: "resource://gre/modules/LoadURIDelegate.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
});
|
||||
|
@ -38,6 +40,8 @@ class GeckoViewNavigation extends GeckoViewModule {
|
|||
"GeckoView:Reload",
|
||||
"GeckoView:Stop",
|
||||
]);
|
||||
|
||||
this.messageManager.addMessageListener("Browser:LoadURI", this);
|
||||
}
|
||||
|
||||
// Bundle event handler.
|
||||
|
@ -73,6 +77,10 @@ class GeckoViewNavigation extends GeckoViewModule {
|
|||
navFlags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_POPUPS;
|
||||
}
|
||||
|
||||
const remoteType =
|
||||
E10SUtils.getRemoteTypeForURI(uri, this.settings.useMultiprocess);
|
||||
this.moduleManager.updateRemoteType(remoteType);
|
||||
|
||||
this.browser.loadURI(uri, {
|
||||
flags: navFlags,
|
||||
referrerURI: referrer,
|
||||
|
@ -90,6 +98,23 @@ class GeckoViewNavigation extends GeckoViewModule {
|
|||
// Message manager event handler.
|
||||
receiveMessage(aMsg) {
|
||||
debug `receiveMessage: ${aMsg.name}`;
|
||||
|
||||
switch (aMsg.name) {
|
||||
case "Browser:LoadURI":
|
||||
// This is triggered by E10SUtils.redirectLoad(), and means
|
||||
// we may need to change the remoteness of our browser and
|
||||
// load the URI.
|
||||
const { uri, flags, referrer, triggeringPrincipal } = aMsg.data.loadOptions;
|
||||
const remoteType =
|
||||
E10SUtils.getRemoteTypeForURI(uri, this.settings.useMultiprocess);
|
||||
|
||||
this.moduleManager.updateRemoteType(remoteType);
|
||||
this.browser.loadURI(aMsg.data.loadOptions.uri, {
|
||||
flags, referrerURI: referrer,
|
||||
triggeringPrincipal: Utils.deserializePrincipal(triggeringPrincipal),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
waitAndSetupWindow(aSessionId, { opener, nextTabParentId }) {
|
||||
|
|
|
@ -44,12 +44,6 @@ const USER_AGENT_MODE_VR = 2;
|
|||
// * multiprocess
|
||||
// * user agent override
|
||||
class GeckoViewSettings extends GeckoViewModule {
|
||||
onInitBrowser() {
|
||||
if (this.settings.useMultiprocess) {
|
||||
this.browser.setAttribute("remote", "true");
|
||||
}
|
||||
}
|
||||
|
||||
onInit() {
|
||||
debug `onInit`;
|
||||
this._useTrackingProtection = false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче