From 6ce4e6b1e0e447ecc64d45fa93e4e71b8d018ffe Mon Sep 17 00:00:00 2001 From: Noemi Erli Date: Mon, 20 Apr 2020 22:28:20 +0300 Subject: [PATCH] Backed out 4 changesets (bug 1625513) for causing assertion in WindowGlobalChild.cpp Backed out changeset 0366bbc9e0f7 (bug 1625513) Backed out changeset 3554e0be2e66 (bug 1625513) Backed out changeset ad09a911bc43 (bug 1625513) Backed out changeset f2dbff5d584f (bug 1625513) --- browser/base/content/tabbrowser.js | 45 --- .../components/sessionstore/SessionStore.jsm | 238 +++++++++++++++ docshell/base/CanonicalBrowsingContext.cpp | 19 ++ docshell/base/CanonicalBrowsingContext.h | 6 + dom/chrome-webidl/BrowsingContext.webidl | 4 + dom/interfaces/base/nsIBrowser.idl | 21 -- js/xpconnect/loader/nsImportModule.cpp | 14 +- js/xpconnect/loader/nsImportModule.h | 52 +--- netwerk/base/moz.build | 1 + netwerk/base/nsIProcessSwitchRequestor.idl | 52 ++++ netwerk/ipc/DocumentLoadListener.cpp | 282 ++++++------------ netwerk/ipc/DocumentLoadListener.h | 25 +- netwerk/protocol/http/nsHttpChannel.cpp | 54 ++++ netwerk/protocol/http/nsHttpChannel.h | 26 +- netwerk/protocol/http/nsHttpHandler.cpp | 1 + netwerk/protocol/http/nsHttpHandler.h | 1 + .../content/widgets/browser-custom-element.js | 17 -- toolkit/modules/moz.build | 9 - toolkit/modules/nsIE10SUtils.idl | 37 --- 19 files changed, 506 insertions(+), 398 deletions(-) create mode 100644 netwerk/base/nsIProcessSwitchRequestor.idl delete mode 100644 toolkit/modules/nsIE10SUtils.idl diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js index eaa9492bc5ec..0d686dac8b4e 100644 --- a/browser/base/content/tabbrowser.js +++ b/browser/base/content/tabbrowser.js @@ -5682,51 +5682,6 @@ } } }, - - async performProcessSwitch( - aBrowser, - aRemoteType, - aSwitchId, - aReplaceBrowsingContext - ) { - E10SUtils.log().info( - `performing switch from ${aBrowser.remoteType} to ${aRemoteType}` - ); - - // Don't try to switch tabs before delayed startup is completed. - await window.delayedStartupPromise; - - // Perform a navigateAndRestore to trigger the process switch. - let tab = this.getTabForBrowser(aBrowser); - let loadArguments = { - newFrameloader: true, // Switch even if remoteType hasn't changed. - remoteType: aRemoteType, // Don't derive remoteType to switch to. - - // Information about which channel should be performing the load. - redirectLoadSwitchId: aSwitchId, - - // True if this is a process switch due to a policy mismatch, means we - // shouldn't preserve our browsing context. - replaceBrowsingContext: aReplaceBrowsingContext, - }; - - await SessionStore.navigateAndRestore(tab, loadArguments, -1); - - // If the process switch seems to have failed, send an error over to our - // caller, to give it a chance to kill our channel. - if ( - aBrowser.remoteType != aRemoteType || - !aBrowser.frameLoader || - !aBrowser.frameLoader.remoteTab - ) { - throw Cr.NS_ERROR_FAILURE; - } - - // Tell our caller to redirect the load into this newly created process. - let remoteTab = aBrowser.frameLoader.remoteTab; - E10SUtils.log().debug(`new tabID: ${remoteTab.tabId}`); - return remoteTab.contentProcessId; - }, }; /** diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm index bcb6aad7f172..4557105583df 100644 --- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -54,6 +54,7 @@ const OBSERVING = [ "browser:purge-session-history-for-domain", "idle-daily", "clear-origin-attributes-data", + "channel-on-may-change-process", ]; // XUL Window properties to (re)store @@ -518,6 +519,9 @@ var SessionStoreInternal = { // A counter to be used to generate a unique ID for each closed tab or window. _nextClosedId: 0, + // A monotonic value used to generate a unique ID for each process switch. + _switchIdMonotonic: 0, + // During the initial restore and setBrowserState calls tracks the number of // windows yet to be restored _restoreCount: -1, @@ -943,6 +947,9 @@ var SessionStoreInternal = { this._forgetTabsWithUserContextId(userContextId); } break; + case "channel-on-may-change-process": + this.onMayChangeProcess(aSubject); + break; } }, @@ -2912,6 +2919,237 @@ var SessionStoreInternal = { } }, + async _doTabProcessSwitch( + aBrowser, + aRemoteType, + aChannel, + aSwitchId, + aReplaceBrowsingContext + ) { + E10SUtils.log().info( + `performing switch from ${aBrowser.remoteType} to ${aRemoteType}` + ); + + // Don't try to switch tabs before delayed startup is completed. + await aBrowser.ownerGlobal.delayedStartupPromise; + + // Perform a navigateAndRestore to trigger the process switch. + let tab = aBrowser.ownerGlobal.gBrowser.getTabForBrowser(aBrowser); + let loadArguments = { + newFrameloader: true, // Switch even if remoteType hasn't changed. + remoteType: aRemoteType, // Don't derive remoteType to switch to. + + // Information about which channel should be performing the load. + redirectLoadSwitchId: aSwitchId, + + // True if this is a process switch due to a policy mismatch, means we + // shouldn't preserve our browsing context. + replaceBrowsingContext: aReplaceBrowsingContext, + }; + + await SessionStore.navigateAndRestore(tab, loadArguments, -1); + + // If the process switch seems to have failed, send an error over to our + // caller, to give it a chance to kill our channel. + if ( + aBrowser.remoteType != aRemoteType || + !aBrowser.frameLoader || + !aBrowser.frameLoader.remoteTab + ) { + throw Cr.NS_ERROR_FAILURE; + } + + // Tell our caller to redirect the load into this newly created process. + let remoteTab = aBrowser.frameLoader.remoteTab; + E10SUtils.log().debug(`new tabID: ${remoteTab.tabId}`); + return remoteTab.contentProcessId; + }, + + /** + * Perform a destructive process switch into a distinct process. + * This method is asynchronous, as it requires multiple calls into content + * processes. + */ + async _doProcessSwitch( + aBrowsingContext, + aRemoteType, + aChannel, + aSwitchId, + aReplaceBrowsingContext + ) { + // There are two relevant cases when performing a process switch for a + // browsing context: in-process and out-of-process embedders. + + // If our embedder is in-process (e.g. we're a xul:browser element embedded + // within ), then we can perform a process switch using the + // traditional mechanism. + if (aBrowsingContext.embedderElement) { + return this._doTabProcessSwitch( + aBrowsingContext.embedderElement, + aRemoteType, + aChannel, + aSwitchId, + aReplaceBrowsingContext + ); + } + + return aBrowsingContext.changeFrameRemoteness(aRemoteType, aSwitchId); + }, + + // Examine the channel response to see if we should change the process + // performing the given load. aRequestor implements nsIProcessSwitchRequestor + onMayChangeProcess(aRequestor) { + if (!E10SUtils.documentChannel()) { + throw new Error("This code is only used by document channel"); + } + + let switchRequestor; + try { + switchRequestor = aRequestor.QueryInterface(Ci.nsIProcessSwitchRequestor); + } catch (e) { + E10SUtils.log().warn(`object not compatible with process switching `); + return; + } + + const channel = switchRequestor.channel; + if (!channel.isDocument || !channel.loadInfo) { + return; // Not a document load. + } + + // Check that the document has a corresponding BrowsingContext. + let browsingContext = channel.loadInfo.targetBrowsingContext; + let isSubframe = + channel.loadInfo.externalContentPolicyType != + Ci.nsIContentPolicy.TYPE_DOCUMENT; + + if (!browsingContext) { + E10SUtils.log().debug(`no BrowsingContext - ignoring`); + return; + } + + // Determine if remote subframes should be used for this load. + let topBC = browsingContext.top; + if (!topBC.embedderElement) { + E10SUtils.log().debug(`no embedder for top - ignoring`); + return; + } + + let topDocShell = topBC.embedderElement.ownerGlobal.docShell; + let { useRemoteSubframes } = topDocShell.QueryInterface(Ci.nsILoadContext); + if (!useRemoteSubframes && isSubframe) { + E10SUtils.log().debug(`remote subframes disabled - ignoring`); + return; + } + + // Get principal for a document already loaded in the BrowsingContext. + let currentPrincipal = null; + if (browsingContext.currentWindowGlobal) { + currentPrincipal = browsingContext.currentWindowGlobal.documentPrincipal; + } + + // We can only perform a process switch on in-process frames if they are + // embedded within a normal tab. We can't do one of these swaps for a + // cross-origin frame. + if (browsingContext.embedderElement) { + let tabbrowser = browsingContext.embedderElement.getTabBrowser(); + if (!tabbrowser) { + E10SUtils.log().debug( + `cannot find tabbrowser for loading tab - ignoring` + ); + return; + } + + let tab = tabbrowser.getTabForBrowser(browsingContext.embedderElement); + if (!tab) { + E10SUtils.log().debug( + `not a normal tab, so cannot swap processes - ignoring` + ); + return; + } + } else if (!browsingContext.parent) { + E10SUtils.log().debug( + `no parent or in-process embedder element - ignoring` + ); + return; + } + + // Get the current remote type for the BrowsingContext. + let currentRemoteType = browsingContext.currentRemoteType; + if (currentRemoteType == E10SUtils.NOT_REMOTE) { + E10SUtils.log().debug(`currently not remote - ignoring`); + return; + } + + // Determine the process type the load should be performed in. + let resultPrincipal = Services.scriptSecurityManager.getChannelResultPrincipal( + channel + ); + + const isCOOPSwitch = + E10SUtils.useCrossOriginOpenerPolicy() && + switchRequestor.hasCrossOriginOpenerPolicyMismatch(); + + let preferredRemoteType = currentRemoteType; + if ( + E10SUtils.useCrossOriginOpenerPolicy() && + switchRequestor.crossOriginOpenerPolicy == + Ci.nsILoadInfo.OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP + ) { + // We want documents with a SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP + // COOP policy to be loaded in a separate process for which we can enable + // high resolution timers. + preferredRemoteType = + E10SUtils.WEB_REMOTE_COOP_COEP_TYPE_PREFIX + resultPrincipal.siteOrigin; + } else if (isCOOPSwitch) { + // If it is a coop switch, but doesn't have this flag, we want to switch + // to a default remoteType + preferredRemoteType = E10SUtils.DEFAULT_REMOTE_TYPE; + } + E10SUtils.log().info( + `currentRemoteType (${currentRemoteType}) preferredRemoteType: ${preferredRemoteType}` + ); + + let remoteType = E10SUtils.getRemoteTypeForPrincipal( + resultPrincipal, + true, + useRemoteSubframes, + preferredRemoteType, + currentPrincipal, + isSubframe + ); + + E10SUtils.log().debug( + `${currentRemoteType}, ${remoteType}, ${isCOOPSwitch}` + ); + + if (currentRemoteType == remoteType && !isCOOPSwitch) { + E10SUtils.log().debug(`type (${remoteType}) is compatible - ignoring`); + return; + } + + if ( + remoteType == E10SUtils.NOT_REMOTE || + currentRemoteType == E10SUtils.NOT_REMOTE + ) { + E10SUtils.log().debug(`non-remote source/target - ignoring`); + return; + } + + // ------------------------------------------------------------------------ + // DANGER ZONE: Perform a process switch into the new process. This is + // destructive. + // ------------------------------------------------------------------------ + let identifier = ++this._switchIdMonotonic; + let tabPromise = this._doProcessSwitch( + browsingContext, + remoteType, + channel, + identifier, + isCOOPSwitch + ); + switchRequestor.switchProcessTo(tabPromise, identifier); + }, + /* ........ nsISessionStore API .............. */ getBrowserState: function ssi_getBrowserState() { diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index 08626daad86b..63ba94d89b54 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -507,6 +507,25 @@ CanonicalBrowsingContext::ChangeFrameRemoteness(const nsAString& aRemoteType, return promise.forget(); } +already_AddRefed CanonicalBrowsingContext::ChangeFrameRemoteness( + const nsAString& aRemoteType, uint64_t aPendingSwitchId, ErrorResult& aRv) { + nsIGlobalObject* global = xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr promise = Promise::Create(global, aRv); + if (aRv.Failed()) { + return nullptr; + } + + ChangeFrameRemoteness(aRemoteType, aPendingSwitchId) + ->Then( + GetMainThreadSerialEventTarget(), __func__, + [promise](BrowserParent* aBrowserParent) { + promise->MaybeResolve(aBrowserParent->Manager()->ChildID()); + }, + [promise](nsresult aRv) { promise->MaybeReject(aRv); }); + return promise.forget(); +} + MediaController* CanonicalBrowsingContext::GetMediaController() { // We would only create one media controller per tab, so accessing the // controller via the top-level browsing context. diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index 4298564b75da..cb315d16249e 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -105,6 +105,12 @@ class CanonicalBrowsingContext final : public BrowsingContext { RefPtr ChangeFrameRemoteness(const nsAString& aRemoteType, uint64_t aPendingSwitchId); + // Helper version for WebIDL - resolves to the PID where the load is being + // resumed. + already_AddRefed ChangeFrameRemoteness(const nsAString& aRemoteType, + uint64_t aPendingSwitchId, + ErrorResult& aRv); + // Return a media controller from the top-level browsing context that can // control all media belonging to this browsing context tree. Return nullptr // if the top-level browsing context has been discarded. diff --git a/dom/chrome-webidl/BrowsingContext.webidl b/dom/chrome-webidl/BrowsingContext.webidl index c861f6875526..95aed1c6bab8 100644 --- a/dom/chrome-webidl/BrowsingContext.webidl +++ b/dom/chrome-webidl/BrowsingContext.webidl @@ -102,6 +102,10 @@ interface CanonicalBrowsingContext : BrowsingContext { [Throws] void loadURI(DOMString aURI, optional LoadURIOptions aOptions = {}); + [Throws] + Promise changeFrameRemoteness( + DOMString remoteType, unsigned long long pendingSwitchId); + readonly attribute nsISHistory? sessionHistory; }; diff --git a/dom/interfaces/base/nsIBrowser.idl b/dom/interfaces/base/nsIBrowser.idl index 1524233206bd..242c6b98cc4f 100644 --- a/dom/interfaces/base/nsIBrowser.idl +++ b/dom/interfaces/base/nsIBrowser.idl @@ -173,25 +173,4 @@ interface nsIBrowser : nsISupports void updateSecurityUIForSecurityChange(in nsITransportSecurityInfo aSecurityInfo, in uint32_t aState, in boolean aIsSecureContext); - - /** - * Called by Gecko when it wants to change the process which is currently - * being used to render content in this tab. - * - * Returns a promise which will be resolved with the ChildID of the new - * process. - * - * @param aRemoteType the new remote type to switch this browser into - * @param aPendingSwitchId unique identifier for the ongoing - * process-switching load - * @param aReplaceBrowsingContext if true, do not preserve the - * BrowsingContext loaded inside this - * browser after changing processes. - */ - Promise performProcessSwitch(in AString aRemoteType, - in uint64_t aPendingSwitchId, - in boolean aReplaceBrowsingContext); - - /** If `true`, this browser supports the `performProcessSwitch` method */ - readonly attribute bool canPerformProcessSwitch; }; diff --git a/js/xpconnect/loader/nsImportModule.cpp b/js/xpconnect/loader/nsImportModule.cpp index 372ca6de75a3..a0cc86721740 100644 --- a/js/xpconnect/loader/nsImportModule.cpp +++ b/js/xpconnect/loader/nsImportModule.cpp @@ -17,8 +17,7 @@ using mozilla::dom::AutoJSAPI; namespace mozilla { namespace loader { -nsresult ImportModule(const char* aURI, const char* aExportName, - const nsIID& aIID, void** aResult) { +nsresult ImportModule(const char* aURI, const nsIID& aIID, void** aResult) { AutoJSAPI jsapi; MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope())); JSContext* cx = jsapi.cx(); @@ -28,17 +27,6 @@ nsresult ImportModule(const char* aURI, const char* aExportName, MOZ_TRY(mozJSComponentLoader::Get()->Import(cx, nsDependentCString(aURI), &global, &exports)); - if (aExportName) { - JS::RootedValue namedExport(cx); - if (!JS_GetProperty(cx, exports, aExportName, &namedExport)) { - return NS_ERROR_FAILURE; - } - if (!namedExport.isObject()) { - return NS_ERROR_XPC_BAD_CONVERT_JS; - } - exports.set(&namedExport.toObject()); - } - return nsXPConnect::XPConnect()->WrapJS(cx, exports, aIID, aResult); } diff --git a/js/xpconnect/loader/nsImportModule.h b/js/xpconnect/loader/nsImportModule.h index b1105278d367..e488f46d9914 100644 --- a/js/xpconnect/loader/nsImportModule.h +++ b/js/xpconnect/loader/nsImportModule.h @@ -15,21 +15,19 @@ namespace mozilla { namespace loader { -nsresult ImportModule(const char* aURI, const char* aExportName, - const nsIID& aIID, void** aResult); +nsresult ImportModule(const char* aURI, const nsIID& aIID, void** aResult); } // namespace loader } // namespace mozilla class MOZ_STACK_CLASS nsImportModule final : public nsCOMPtr_helper { public: - nsImportModule(const char* aURI, const char* aExportName, nsresult* aErrorPtr) - : mURI(aURI), mExportName(aExportName), mErrorPtr(aErrorPtr) {} + nsImportModule(const char* aURI, nsresult* aErrorPtr) + : mURI(aURI), mErrorPtr(aErrorPtr) {} virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, void** aResult) const override { - nsresult rv = - ::mozilla::loader::ImportModule(mURI, mExportName, aIID, aResult); + nsresult rv = ::mozilla::loader::ImportModule(mURI, aIID, aResult); if (mErrorPtr) { *mErrorPtr = rv; } @@ -38,7 +36,6 @@ class MOZ_STACK_CLASS nsImportModule final : public nsCOMPtr_helper { private: const char* mURI; - const char* mExportName; nsresult* mErrorPtr; }; @@ -67,47 +64,14 @@ class MOZ_STACK_CLASS nsImportModule final : public nsCOMPtr_helper { * "resource://meh/Foo.jsm"); * * MOZ_TRY(foo->Foo(42)); - * - * For JS modules which export all fields within a single named object, a second - * argument can be passed naming that object. - * - * Foo.jsm: - * - * var EXPORTED_SYMBOLS = ["Foo"]; - * - * var Foo = { - * function foo(bar) { - * return bar.toString(); - * } - * }; - * - * Thing.cpp: - * - * nsCOMPtr foo = do_ImportModule( - * "resource:://meh/Foo.jsm", "Foo"); */ -template -inline nsImportModule do_ImportModule(const char (&aURI)[N]) { - return {aURI, nullptr, nullptr}; +inline nsImportModule do_ImportModule(const char* aURI) { + return {aURI, nullptr}; } -template -inline nsImportModule do_ImportModule(const char (&aURI)[N], nsresult* aRv) { - return {aURI, nullptr, aRv}; -} - -template -inline nsImportModule do_ImportModule(const char (&aURI)[N], - const char (&aExportName)[N2]) { - return {aURI, aExportName, nullptr}; -} - -template -inline nsImportModule do_ImportModule(const char (&aURI)[N], - const char (&aExportName)[N2], - nsresult* aRv) { - return {aURI, aExportName, aRv}; +inline nsImportModule do_ImportModule(const char* aURI, nsresult* aRv) { + return {aURI, aRv}; } #endif // defined nsImportModule_h diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 2b4c95083886..d83ccc1c7221 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -75,6 +75,7 @@ XPIDL_SOURCES += [ 'nsIPermission.idl', 'nsIPermissionManager.idl', 'nsIPrivateBrowsingChannel.idl', + 'nsIProcessSwitchRequestor.idl', 'nsIProgressEventSink.idl', 'nsIPrompt.idl', 'nsIProtocolHandler.idl', diff --git a/netwerk/base/nsIProcessSwitchRequestor.idl b/netwerk/base/nsIProcessSwitchRequestor.idl new file mode 100644 index 000000000000..3656485ee597 --- /dev/null +++ b/netwerk/base/nsIProcessSwitchRequestor.idl @@ -0,0 +1,52 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIChannel.idl" + +/** + * The nsIProcessSwitchRequestor interface allows clients to instruct + * SessionStore.jsm that a channel setup has completed and a process switch + * may be required. This works alongside the on-may-change-process observer + * notification. + * This interface must be used only from the XPCOM main thread. + */ +[scriptable, uuid(fce8497b-c57c-4557-b360-3efefc83eff5)] +interface nsIProcessSwitchRequestor : nsISupports +{ + /** + * The underlying channel object that was intercepted and that could trigger + * a process. + */ + readonly attribute nsIChannel channel; + + /** + * Instructs the callee to be loaded in a new process. Like 'redirectTo' + * this can only be used on channels that have not yet called their + * listener's OnStartRequest(). Can only be called during the + * channel-on-may-change-process observer notification. + * + * @param aTabPromise a promise which resolves to a nsIRemotTab object + * which the load will proceed in. + * @param aIdentifier a 64-bit ID which will be provided to the + * ChildProcessChannelListener. + */ + [must_use] void switchProcessTo(in Promise aTabPromise, + in unsigned long long aIdentifier); + + /** + * Used to determine if there is a Cross-Origin-Opener-Policy mismatch + * that would require switching the channel to another process. + * @throws NS_ERROR_NOT_AVAILABLE if we don't have a responseHead + */ + [must_use] boolean hasCrossOriginOpenerPolicyMismatch(); + + /** + * Returns a cached CrossOriginOpenerPolicy that is computed just before we + * determine if there is a policy mismatch. + * @throws NS_ERROR_NOT_AVAILABLE if called before onStartRequest + */ + [must_use, binaryname(CachedCrossOriginOpenerPolicy)] readonly attribute nsILoadInfo_CrossOriginOpenerPolicy crossOriginOpenerPolicy; +}; diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index 03b04b4ff953..5f4d76262021 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -41,9 +41,6 @@ #include "mozilla/dom/WindowGlobalParent.h" #include "mozilla/StaticPrefs_security.h" #include "nsICookieService.h" -#include "nsIBrowser.h" -#include "nsIE10SUtils.h" -#include "nsImportModule.h" #ifdef ANDROID # include "mozilla/widget/nsWindow.h" @@ -241,6 +238,7 @@ NS_INTERFACE_MAP_BEGIN(DocumentLoadListener) NS_INTERFACE_MAP_ENTRY(nsIParentChannel) NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectReadyCallback) NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink) + NS_INTERFACE_MAP_ENTRY(nsIProcessSwitchRequestor) NS_INTERFACE_MAP_ENTRY(nsIMultiPartChannelListener) NS_INTERFACE_MAP_ENTRY_CONCRETE(DocumentLoadListener) NS_INTERFACE_MAP_END @@ -885,196 +883,26 @@ void DocumentLoadListener::SerializeRedirectData( aArgs.loadStateLoadType() = mLoadStateLoadType; } -bool DocumentLoadListener::MaybeTriggerProcessSwitch() { - MOZ_DIAGNOSTIC_ASSERT(!mDoingProcessSwitch, - "Already in the middle of switching?"); - MOZ_DIAGNOSTIC_ASSERT(mChannel); - MOZ_DIAGNOSTIC_ASSERT(mParentChannelListener); +void DocumentLoadListener::TriggerCrossProcessSwitch() { + MOZ_ASSERT(mRedirectContentProcessIdPromise); + MOZ_ASSERT(!mDoingProcessSwitch, "Already in the middle of switching?"); + MOZ_ASSERT(NS_IsMainThread()); - LOG(("DocumentLoadListener MaybeTriggerProcessSwitch [this=%p]", this)); + LOG(("DocumentLoadListener TriggerCrossProcessSwitch [this=%p]", this)); - // Get the BrowsingContext which will be switching processes. - RefPtr browsingContext = - mParentChannelListener->GetBrowsingContext(); - if (NS_WARN_IF(!browsingContext)) { - LOG(("Process Switch Abort: no browsing context")); - return false; - } - if (!browsingContext->IsContent()) { - LOG(("Process Switch Abort: non-content browsing context")); - return false; - } - if (browsingContext->GetParent() && !browsingContext->UseRemoteSubframes()) { - LOG(("Process Switch Abort: remote subframes disabled")); - return false; - } - - // We currently can't switch processes for toplevel loads unless they're - // loaded within a browser tab. - // FIXME: Ideally we won't do this in the future. - nsCOMPtr browser; - if (!browsingContext->GetParent()) { - Element* browserElement = browsingContext->GetEmbedderElement(); - if (!browserElement) { - LOG(("Process Switch Abort: cannot get browser element")); - return false; - } - browser = browserElement->AsBrowser(); - if (!browser) { - LOG(("Process Switch Abort: not loaded within nsIBrowser")); - return false; - } - bool loadedInTab = false; - if (NS_FAILED(browser->GetCanPerformProcessSwitch(&loadedInTab)) || - !loadedInTab) { - LOG(("Process Switch Abort: browser is not loaded in a tab")); - return false; - } - } - - // Get information about the current document loaded in our BrowsingContext. - nsCOMPtr currentPrincipal; - if (RefPtr wgp = - browsingContext->GetCurrentWindowGlobal()) { - currentPrincipal = wgp->DocumentPrincipal(); - } - RefPtr currentProcess = browsingContext->GetContentParent(); - if (!currentProcess) { - LOG(("Process Switch Abort: frame currently not remote")); - return false; - } - - // Get the final principal, used to select which process to load into. - nsCOMPtr resultPrincipal; - nsresult rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal( - mChannel, getter_AddRefs(resultPrincipal)); - if (NS_FAILED(rv)) { - LOG(("Process Switch Abort: failed to get channel result principal")); - return false; - } - - if (resultPrincipal->IsSystemPrincipal()) { - LOG(("Process Switch Abort: cannot switch process for system principal")); - return false; - } - - // Determine our COOP status, which will be used to determine our preferred - // remote type. - bool isCOOPSwitch = HasCrossOriginOpenerPolicyMismatch(); - nsILoadInfo::CrossOriginOpenerPolicy coop = - nsILoadInfo::OPENER_POLICY_UNSAFE_NONE; - if (RefPtr httpChannel = do_QueryObject(mChannel)) { - MOZ_ALWAYS_SUCCEEDS(httpChannel->GetCrossOriginOpenerPolicy(&coop)); - } - - nsAutoString preferredRemoteType(currentProcess->GetRemoteType()); - if (coop == - nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP) { - // We want documents with SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP COOP - // policy to be loaded in a separate process in which we can enable - // high-resolution timers. - nsAutoCString siteOrigin; - resultPrincipal->GetSiteOrigin(siteOrigin); - preferredRemoteType.Assign( - NS_LITERAL_STRING(WITH_COOP_COEP_REMOTE_TYPE_PREFIX)); - preferredRemoteType.Append(NS_ConvertUTF8toUTF16(siteOrigin)); - } else if (isCOOPSwitch) { - // If we're doing a COOP switch, we do not need any affinity to the current - // remote type. Clear it back to the default value. - preferredRemoteType.Assign(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE)); - } - MOZ_DIAGNOSTIC_ASSERT(!preferredRemoteType.IsEmpty(), - "Unexpected empty remote type!"); - - LOG( - ("DocumentLoadListener GetRemoteTypeForPrincipal " - "[this=%p, currentProcess=%s, preferredRemoteType=%s]", - this, NS_ConvertUTF16toUTF8(currentProcess->GetRemoteType()).get(), - NS_ConvertUTF16toUTF8(preferredRemoteType).get())); - - nsCOMPtr e10sUtils = - do_ImportModule("resource://gre/modules/E10SUtils.jsm", "E10SUtils"); - if (!e10sUtils) { - LOG(("Process Switch Abort: Could not import E10SUtils")); - return false; - } - - nsAutoString remoteType; - rv = e10sUtils->GetRemoteTypeForPrincipal( - resultPrincipal, browsingContext->UseRemoteTabs(), - browsingContext->UseRemoteSubframes(), preferredRemoteType, - currentPrincipal, browsingContext->GetParent(), remoteType); - if (NS_WARN_IF(NS_FAILED(rv))) { - LOG(("Process Switch Abort: getRemoteTypeForPrincipal threw an exception")); - return false; - } - - // Check if a process switch is needed. - if (currentProcess->GetRemoteType() == remoteType && !isCOOPSwitch) { - LOG(("Process Switch Abort: type (%s) is compatible", - NS_ConvertUTF16toUTF8(remoteType).get())); - return false; - } - if (NS_WARN_IF(remoteType.IsEmpty())) { - LOG(("Process Switch Abort: non-remote target process")); - return false; - } - - LOG(("Process Switch: Changing Remoteness from '%s' to '%s'", - NS_ConvertUTF16toUTF8(currentProcess->GetRemoteType()).get(), - NS_ConvertUTF16toUTF8(remoteType).get())); - - // XXX: This is super hacky, and we should be able to do something better. - static uint64_t sNextCrossProcessRedirectIdentifier = 0; - mCrossProcessRedirectIdentifier = ++sNextCrossProcessRedirectIdentifier; mDoingProcessSwitch = true; RefPtr self = this; - // At this point, we're actually going to perform a process switch, which - // involves calling into other logic. - if (browsingContext->GetParent()) { - LOG(("Process Switch: Calling ChangeFrameRemoteness")); - // If we're switching a subframe, ask BrowsingContext to do it for us. - MOZ_ASSERT(!isCOOPSwitch); - browsingContext - ->ChangeFrameRemoteness(remoteType, mCrossProcessRedirectIdentifier) - ->Then( - GetMainThreadSerialEventTarget(), __func__, - [self](BrowserParent* aBrowserParent) { - MOZ_ASSERT(self->mChannel, - "Something went wrong, channel got cancelled"); - self->TriggerRedirectToRealChannel( - Some(aBrowserParent->Manager()->ChildID())); - }, - [self](nsresult aStatusCode) { - MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error"); - self->RedirectToRealChannelFinished(aStatusCode); - }); - return true; - } - - LOG(("Process Switch: Calling nsIBrowser::PerformProcessSwitch")); - // We're switching a toplevel BrowsingContext's process. This has to be done - // using nsIBrowser. - RefPtr domPromise; - browser->PerformProcessSwitch(remoteType, mCrossProcessRedirectIdentifier, - isCOOPSwitch, getter_AddRefs(domPromise)); - MOZ_DIAGNOSTIC_ASSERT(domPromise, - "PerformProcessSwitch didn't return a promise"); - - MozPromise::FromDomPromise(domPromise) - ->Then( - GetMainThreadSerialEventTarget(), __func__, - [self](uint64_t aCpId) { - MOZ_ASSERT(self->mChannel, - "Something went wrong, channel got cancelled"); - self->TriggerRedirectToRealChannel(Some(aCpId)); - }, - [self](nsresult aStatusCode) { - MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error"); - self->RedirectToRealChannelFinished(aStatusCode); - }); - return true; + mRedirectContentProcessIdPromise->Then( + GetMainThreadSerialEventTarget(), __func__, + [self, this](uint64_t aCpId) { + MOZ_ASSERT(mChannel, "Something went wrong, channel got cancelled"); + TriggerRedirectToRealChannel(Some(aCpId)); + }, + [self](nsresult aStatusCode) { + MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error"); + self->RedirectToRealChannelFinished(aStatusCode); + }); } RefPtr @@ -1255,10 +1083,18 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) { httpChannel->SetApplyConversion(false); } - // Determine if a new process needs to be spawned. If it does, this will - // trigger a cross process switch, and we should hold off on redirecting to - // the real channel. - if (status != NS_BINDING_ABORTED && MaybeTriggerProcessSwitch()) { + // notify "channel-on-may-change-process" observers which is typically + // SessionStore.jsm. This will determine if a new process needs to be + // spawned and if so SwitchProcessTo() will be called which will set a + // ContentProcessIdPromise. + if (status != NS_BINDING_ABORTED) { + nsCOMPtr obsService = services::GetObserverService(); + obsService->NotifyObservers(ToSupports(this), + "channel-on-may-change-process", nullptr); + } + + if (mRedirectContentProcessIdPromise) { + TriggerCrossProcessSwitch(); return NS_OK; } @@ -1421,8 +1257,10 @@ DocumentLoadListener::AsyncOnChannelRedirect( // include the state of all channels we redirected through. RefPtr httpChannel = do_QueryObject(aOldChannel); if (httpChannel) { - mHasCrossOriginOpenerPolicyMismatch |= - httpChannel->HasCrossOriginOpenerPolicyMismatch(); + bool mismatch = false; + MOZ_ALWAYS_SUCCEEDS( + httpChannel->HasCrossOriginOpenerPolicyMismatch(&mismatch)); + mHasCrossOriginOpenerPolicyMismatch |= mismatch; } // We don't need to confirm internal redirects or record any @@ -1513,22 +1351,70 @@ DocumentLoadListener::AsyncOnChannelRedirect( return NS_OK; } +//----------------------------------------------------------------------------- +// DocumentLoadListener::nsIProcessSwitchRequestor +//----------------------------------------------------------------------------- + +NS_IMETHODIMP DocumentLoadListener::GetChannel(nsIChannel** aChannel) { + MOZ_ASSERT(mChannel); + nsCOMPtr channel(mChannel); + channel.forget(aChannel); + return NS_OK; +} + +NS_IMETHODIMP DocumentLoadListener::SwitchProcessTo( + dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) { + MOZ_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG(aContentProcessIdPromise); + + mRedirectContentProcessIdPromise = + ContentProcessIdPromise::FromDomPromise(aContentProcessIdPromise); + mCrossProcessRedirectIdentifier = aIdentifier; + return NS_OK; +} + // This method returns the cached result of running the Cross-Origin-Opener // policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch -bool DocumentLoadListener::HasCrossOriginOpenerPolicyMismatch() { +NS_IMETHODIMP +DocumentLoadListener::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) { + MOZ_ASSERT(aMismatch); + + if (!aMismatch) { + return NS_ERROR_INVALID_ARG; + } + // If we found a COOP mismatch on an earlier channel and then // redirected away from that, we should use that result. if (mHasCrossOriginOpenerPolicyMismatch) { - return true; + *aMismatch = true; + return NS_OK; } RefPtr httpChannel = do_QueryObject(mChannel); if (!httpChannel) { // Not an nsHttpChannel assume it's okay to switch. - return false; + *aMismatch = false; + return NS_OK; } - return httpChannel->HasCrossOriginOpenerPolicyMismatch(); + return httpChannel->HasCrossOriginOpenerPolicyMismatch(aMismatch); +} + +NS_IMETHODIMP +DocumentLoadListener::GetCachedCrossOriginOpenerPolicy( + nsILoadInfo::CrossOriginOpenerPolicy* aPolicy) { + MOZ_ASSERT(aPolicy); + if (!aPolicy) { + return NS_ERROR_INVALID_ARG; + } + + RefPtr httpChannel = do_QueryObject(mChannel); + if (!httpChannel) { + *aPolicy = nsILoadInfo::OPENER_POLICY_UNSAFE_NONE; + return NS_OK; + } + + return httpChannel->GetCrossOriginOpenerPolicy(aPolicy); } auto DocumentLoadListener::AttachStreamFilter(base::ProcessId aChildProcessId) diff --git a/netwerk/ipc/DocumentLoadListener.h b/netwerk/ipc/DocumentLoadListener.h index 429ef3c0f0ba..0fbeaac1ebdc 100644 --- a/netwerk/ipc/DocumentLoadListener.h +++ b/netwerk/ipc/DocumentLoadListener.h @@ -20,6 +20,7 @@ #include "nsIObserver.h" #include "nsIParentChannel.h" #include "nsIParentRedirectingChannel.h" +#include "nsIProcessSwitchRequestor.h" #include "nsIRedirectResultListener.h" #include "nsIMultiPartChannel.h" @@ -87,6 +88,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor, public nsIParentChannel, public nsIChannelEventSink, public HttpChannelSecurityWarningReporter, + public nsIProcessSwitchRequestor, public nsIMultiPartChannelListener { public: explicit DocumentLoadListener(dom::CanonicalBrowsingContext* aBrowsingContext, @@ -107,6 +109,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor, NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK NS_DECL_NSICHANNELEVENTSINK + NS_DECL_NSIPROCESSSWITCHREQUESTOR NS_DECL_NSIMULTIPARTCHANNELLISTENER // We suspend the underlying channel when replacing ourselves with @@ -197,10 +200,10 @@ class DocumentLoadListener : public nsIInterfaceRequestor, // by us, and resumes the underlying source channel. void FinishReplacementChannelSetup(bool aSucceeded); - // Called from `OnStartRequest` to make the decision about whether or not to - // change process. This method will return `nullptr` if the current target - // process is appropriate. - bool MaybeTriggerProcessSwitch(); + // Called when we have a cross-process switch promise. Waits on the + // promise, and then call TriggerRedirectToRealChannel with the + // provided content process id. + void TriggerCrossProcessSwitch(); // A helper for TriggerRedirectToRealChannel that abstracts over // the same-process and cross-process switch cases and returns @@ -215,8 +218,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor, dom::CanonicalBrowsingContext* aBrowsingContext, nsDocShellLoadState* aLoadState, uint64_t aOuterWindowId); - bool HasCrossOriginOpenerPolicyMismatch(); - // This defines a variant that describes all the attribute setters (and their // parameters) from nsIParentChannel // @@ -371,8 +372,16 @@ class DocumentLoadListener : public nsIInterfaceRequestor, // channel. bool mIsFinished = false; - // This identifier is set by MaybeTriggerProcessSwitch, and is later - // passed to the childChannel in order to identify it in the new process. + typedef MozPromise + ContentProcessIdPromise; + // This promise is set following a on-may-change-process observer + // notification when the associated channel is getting relocated to another + // process. It will be resolved when that process is set up. + RefPtr mRedirectContentProcessIdPromise; + // This identifier is set at the same time as the + // mRedirectContentProcessIdPromise. + // This identifier is later passed to the childChannel in order to identify it + // once the promise is resolved. uint64_t mCrossProcessRedirectIdentifier = 0; }; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index f1c5a8e63f1f..356c80d4bcd8 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -6227,6 +6227,7 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel) NS_INTERFACE_MAP_ENTRY(nsITimerCallback) NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener) NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback) + NS_INTERFACE_MAP_ENTRY(nsIProcessSwitchRequestor) NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel) NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel) @@ -7421,6 +7422,59 @@ nsHttpChannel::GetRequestMethod(nsACString& aMethod) { return HttpBaseChannel::GetRequestMethod(aMethod); } +//----------------------------------------------------------------------------- +// nsHttpChannel::nsIProcessSwitchRequestor +//----------------------------------------------------------------------------- + +NS_IMETHODIMP nsHttpChannel::GetChannel(nsIChannel** aChannel) { + *aChannel = do_AddRef(this).take(); + return NS_OK; +} + +NS_IMETHODIMP nsHttpChannel::SwitchProcessTo( + dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) { + MOZ_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG(aContentProcessIdPromise); + + LOG(("nsHttpChannel::SwitchProcessTo [this=%p]", this)); + LogCallingScriptLocation(this); + + nsCOMPtr parentChannel; + NS_QueryNotificationCallbacks(this, parentChannel); + RefPtr documentChannelParent = + do_QueryObject(parentChannel); + // This is a temporary change as the DocumentChannelParent currently must go + // through the nsHttpChannel to perform a process switch via SessionStore. + if (!documentChannelParent) { + // We cannot do this after OnStartRequest of the listener has been called. + NS_ENSURE_FALSE(mOnStartRequestCalled, NS_ERROR_NOT_AVAILABLE); + } + + mRedirectContentProcessIdPromise = + ContentProcessIdPromise::FromDomPromise(aContentProcessIdPromise); + mCrossProcessRedirectIdentifier = aIdentifier; + return NS_OK; +} + +// This method returns the cached result of running the Cross-Origin-Opener +// policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch +NS_IMETHODIMP +nsHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) { + MOZ_ASSERT(aMismatch); + if (!aMismatch) { + return NS_ERROR_INVALID_ARG; + } + + *aMismatch = mHasCrossOriginOpenerPolicyMismatch; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetCachedCrossOriginOpenerPolicy( + nsILoadInfo::CrossOriginOpenerPolicy* aPolicy) { + return HttpBaseChannel::GetCrossOriginOpenerPolicy(aPolicy); +} + // See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e // This method runs steps 1-4 of the algorithm to compare // cross-origin-opener policies diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index f38c493e00ac..bab55b74ba77 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -32,6 +32,7 @@ #include "mozilla/Atomics.h" #include "mozilla/extensions/PStreamFilterParent.h" #include "mozilla/Mutex.h" +#include "nsIProcessSwitchRequestor.h" class nsDNSPrefetch; class nsICancelable; @@ -78,7 +79,8 @@ class nsHttpChannel final : public HttpBaseChannel, public nsIChannelWithDivertableParentListener, public nsIRaceCacheWithNetwork, public nsIRequestTailUnblockCallback, - public nsITimerCallback { + public nsITimerCallback, + public nsIProcessSwitchRequestor { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIREQUESTOBSERVER @@ -100,6 +102,7 @@ class nsHttpChannel final : public HttpBaseChannel, NS_DECL_NSIRACECACHEWITHNETWORK NS_DECL_NSITIMERCALLBACK NS_DECL_NSIREQUESTTAILUNBLOCKCALLBACK + NS_DECL_NSIPROCESSSWITCHREQUESTOR // nsIHttpAuthenticableChannel. We can't use // NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and @@ -277,6 +280,16 @@ class nsHttpChannel final : public HttpBaseChannel, } TransactionObserver* GetTransactionObserver() { return mTransactionObserver; } + typedef MozPromise + ContentProcessIdPromise; + already_AddRefed + TakeRedirectContentProcessIdPromise() { + return mRedirectContentProcessIdPromise.forget(); + } + uint64_t CrossProcessRedirectIdentifier() { + return mCrossProcessRedirectIdentifier; + } + CacheDisposition mCacheDisposition; protected: @@ -485,11 +498,6 @@ class nsHttpChannel final : public HttpBaseChannel, nsresult ProcessCrossOriginResourcePolicyHeader(); nsresult ComputeCrossOriginOpenerPolicyMismatch(); - // This method returns the cached result of running the Cross-Origin-Opener - // policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch - bool HasCrossOriginOpenerPolicyMismatch() { - return mHasCrossOriginOpenerPolicyMismatch; - } /** * A function to process a single security header (STS or PKP), assumes @@ -577,6 +585,12 @@ class nsHttpChannel final : public HttpBaseChannel, nsCOMPtr mRedirectChannel; nsCOMPtr mPreflightChannel; + // The associated childChannel is getting relocated to another process. + // This promise will be resolved when that process is set up. + RefPtr mRedirectContentProcessIdPromise; + // This identifier is passed to the childChannel in order to identify it. + uint64_t mCrossProcessRedirectIdentifier = 0; + // nsChannelClassifier checks this channel's URI against // the URI classifier service. // nsChannelClassifier will be invoked twice in InitLocalBlockList() and diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 29fe5ce13abd..ffe5928bd1a2 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -18,6 +18,7 @@ #include "nsStandardURL.h" #include "LoadContextInfo.h" #include "nsCategoryManagerUtils.h" +#include "nsIProcessSwitchRequestor.h" #include "nsSocketProviderService.h" #include "nsISocketProvider.h" #include "nsPrintfCString.h" diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index e586a63076a9..2121c9a06429 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -35,6 +35,7 @@ class nsIHttpUpgradeListener; class nsIPrefBranch; class nsICancelable; class nsICookieService; +class nsIProcessSwitchRequestor; class nsIIOService; class nsIRequestContextService; class nsISiteSecurityService; diff --git a/toolkit/content/widgets/browser-custom-element.js b/toolkit/content/widgets/browser-custom-element.js index 2ff20f57fa36..6284b7c9c583 100644 --- a/toolkit/content/widgets/browser-custom-element.js +++ b/toolkit/content/widgets/browser-custom-element.js @@ -2052,23 +2052,6 @@ } return origins; } - - get canPerformProcessSwitch() { - return this.getTabBrowser() != null; - } - - performProcessSwitch( - remoteType, - redirectLoadSwitchId, - replaceBrowsingContext - ) { - return this.getTabBrowser().performProcessSwitch( - this, - remoteType, - redirectLoadSwitchId, - replaceBrowsingContext - ); - } } MozXULElement.implementCustomInterface(MozBrowser, [Ci.nsIBrowser]); diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index cea924f9969f..3b189b333863 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -66,9 +66,6 @@ with Files('DeferredTask.jsm'): with Files("E10SUtils.jsm"): BUG_COMPONENT = ("Core", "Security: Process Sandboxing") -with Files("nsIE10SUtils.idl"): - BUG_COMPONENT = ("Core", "Security: Process Sandboxing") - with Files('Finder*.jsm'): BUG_COMPONENT = ('Toolkit', 'Find Toolbar') @@ -302,9 +299,3 @@ for var in ('MOZ_ALLOW_ADDON_SIDELOAD', JAR_MANIFESTS += ['jar.mn'] DEFINES['TOPOBJDIR'] = TOPOBJDIR - -XPIDL_SOURCES += [ - 'nsIE10SUtils.idl', -] - -XPIDL_MODULE = 'toolkit_modules' diff --git a/toolkit/modules/nsIE10SUtils.idl b/toolkit/modules/nsIE10SUtils.idl deleted file mode 100644 index 08fc26a3f078..000000000000 --- a/toolkit/modules/nsIE10SUtils.idl +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIPrincipal; - -/** - * C++ exposed interface for the `E10SUtils` object from the - * `resource://gre/modules/E10SUtils.jsm` module. - */ -[scriptable, uuid(1e18680e-052d-4509-a17e-678f5c495e02)] -interface nsIE10SUtils : nsISupports { - /** - * Determine what remote type should be used to load a document with the given - * principal. - * - * @param aPrincipal The result principal for the document being loaded. - * @param aMultiProcess Does the browser have remote tabs enabled. - * @param aRemoteSubframes Does the browser have remote subframes enabled. - * @param aPreferredRemoteType If multiple remote types are compatible with - * the load, prefer staying in this remote type. - * @param aCurrentPrincipal The principal of the currently loaded document. - * @param aIsSubframe Is the process switch occuring in a subframe. - * - * @return The remote type to complete this load in. - */ - AString getRemoteTypeForPrincipal(in nsIPrincipal aPrincipal, - in boolean aMultiProcess, - in boolean aRemoteSubframes, - in AString aPreferredRemoteType, - in nsIPrincipal aCurrentPrincipal, - in boolean aIsSubframe); -};