From 0f970fbb193b0116e6641dfec5b720245b0eb513 Mon Sep 17 00:00:00 2001 From: Cosmin Sabou Date: Fri, 24 Apr 2020 11:15:12 +0300 Subject: [PATCH] Backed out 20 changesets (bug 1602318) for causing multiple types of failures. CLOSED TREE Backed out changeset f71e3eff7a8c (bug 1602318) Backed out changeset 0e0bdebf223b (bug 1602318) Backed out changeset 44e82f4339a1 (bug 1602318) Backed out changeset 5f341ebd8591 (bug 1602318) Backed out changeset 088ea9d20617 (bug 1602318) Backed out changeset 5de6321939f2 (bug 1602318) Backed out changeset f5742e84912b (bug 1602318) Backed out changeset 13bec3079540 (bug 1602318) Backed out changeset 6c24ba022911 (bug 1602318) Backed out changeset 5d0fc0102a7f (bug 1602318) Backed out changeset fc4efd11e643 (bug 1602318) Backed out changeset 028bd63e710d (bug 1602318) Backed out changeset 21ad350f9617 (bug 1602318) Backed out changeset 8f27319f2c34 (bug 1602318) Backed out changeset db2832973382 (bug 1602318) Backed out changeset 1756c7584491 (bug 1602318) Backed out changeset 983e5a9abe02 (bug 1602318) Backed out changeset a1b9429b3298 (bug 1602318) Backed out changeset 7d1c0d968a09 (bug 1602318) Backed out changeset a3b056ec6be3 (bug 1602318) --- .../general/browser_tab_detach_restore.js | 2 +- .../performance/browser_preferences_usage.js | 2 +- .../test/tabs/browser_e10s_switchbrowser.js | 4 +- .../browser/browser_ext_tabs_onUpdated.js | 14 +- .../test/browser/browser_google_behavior.js | 14 +- .../browser/browser_searchEngine_behaviors.js | 9 +- .../components/search/test/browser/head.js | 67 ++++ .../components/sessionstore/test/browser.ini | 1 + .../sessionstore/test/browser_broadcast.js | 13 +- .../tests/browser/browser_canonizeURL.js | 7 +- docshell/base/BrowsingContext.cpp | 81 +---- docshell/base/BrowsingContext.h | 19 +- docshell/base/CanonicalBrowsingContext.cpp | 71 ---- docshell/base/CanonicalBrowsingContext.h | 18 - docshell/base/LoadContext.cpp | 8 + docshell/base/LoadContext.h | 18 + docshell/base/nsDocShell.cpp | 51 +-- docshell/base/nsDocShell.h | 1 + docshell/base/nsDocShellLoadState.cpp | 42 +-- docshell/base/nsDocShellLoadState.h | 10 - docshell/base/nsILoadContext.idl | 8 + .../BrowserElementPromptService.jsm | 3 +- dom/chrome-webidl/BrowsingContext.webidl | 25 -- dom/ipc/BrowserParent.cpp | 1 + dom/ipc/ContentChild.cpp | 5 +- dom/ipc/ContentChild.h | 3 +- dom/ipc/DOMTypes.ipdlh | 2 - dom/ipc/PContent.ipdl | 3 +- ...rowser_test_referrer_loadInOtherProcess.js | 2 +- ...rowser_ConsoleStoragePBTest_perwindowpb.js | 62 ++-- modules/libpref/init/StaticPrefList.yaml | 7 - netwerk/ipc/DocumentChannelChild.cpp | 12 +- netwerk/ipc/DocumentChannelParent.cpp | 24 +- netwerk/ipc/DocumentChannelParent.h | 6 +- netwerk/ipc/DocumentLoadListener.cpp | 310 ++---------------- netwerk/ipc/DocumentLoadListener.h | 58 +--- netwerk/ipc/NeckoParent.cpp | 38 ++- netwerk/ipc/NeckoParent.h | 5 +- netwerk/ipc/PNecko.ipdl | 4 +- netwerk/ipc/ParentProcessDocumentChannel.cpp | 6 +- netwerk/ipc/SocketProcessHost.cpp | 4 - netwerk/ipc/SocketProcessImpl.cpp | 1 - .../protocol/http/ParentChannelListener.cpp | 22 +- ...rowser_unknownContentType_delayedbutton.js | 2 - ...rowser_unknownContentType_dialog_layout.js | 2 - .../test/xpinstall/browser_datauri.js | 6 +- .../test/xpinstall/browser_enabled.js | 19 +- .../test/xpinstall/browser_enabled2.js | 6 +- .../test/xpinstall/browser_enabled3.js | 6 +- .../prefetch/OfflineCacheUpdateParent.cpp | 5 + 50 files changed, 343 insertions(+), 766 deletions(-) diff --git a/browser/base/content/test/general/browser_tab_detach_restore.js b/browser/base/content/test/general/browser_tab_detach_restore.js index 5ea47f445300..76adae490457 100644 --- a/browser/base/content/test/general/browser_tab_detach_restore.js +++ b/browser/base/content/test/general/browser_tab_detach_restore.js @@ -15,7 +15,7 @@ add_task(async function() { let tab = BrowserTestUtils.addTab(gBrowser); BrowserTestUtils.loadURI(tab.linkedBrowser, uri); - await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, uri); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); await TabStateFlusher.flush(tab.linkedBrowser); let key = tab.linkedBrowser.permanentKey; diff --git a/browser/base/content/test/performance/browser_preferences_usage.js b/browser/base/content/test/performance/browser_preferences_usage.js index a9313c601a25..58a152b62726 100644 --- a/browser/base/content/test/performance/browser_preferences_usage.js +++ b/browser/base/content/test/performance/browser_preferences_usage.js @@ -198,7 +198,7 @@ add_task(async function navigate_around() { // This is accessed in debug only. }, "toolkit.cosmeticAnimations.enabled": { - min: 30, + min: 45, max: 55, }, }; diff --git a/browser/base/content/test/tabs/browser_e10s_switchbrowser.js b/browser/base/content/test/tabs/browser_e10s_switchbrowser.js index 331a7cb56bd2..9f1caa55a92f 100644 --- a/browser/base/content/test/tabs/browser_e10s_switchbrowser.js +++ b/browser/base/content/test/tabs/browser_e10s_switchbrowser.js @@ -71,7 +71,7 @@ var waitForLoad = async function(uri) { }; gBrowser.selectedBrowser.webNavigation.loadURI(uri, loadURIOptions); - await BrowserTestUtils.browserStopped(gBrowser, uri); + await BrowserTestUtils.browserStopped(gBrowser); // Some of the documents we're using in this test use Fluent, // and they may finish localization later. @@ -101,7 +101,7 @@ var waitForLoadWithFlags = async function( triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), }); - await BrowserTestUtils.browserStopped(gBrowser, uri); + await BrowserTestUtils.browserStopped(gBrowser); if (!(flags & Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY)) { if (flags & Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY) { gExpectedHistory.entries.pop(); diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js index 5954e3e70fd0..f898ec2d9086 100644 --- a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js +++ b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js @@ -215,15 +215,11 @@ add_task(async function test_without_tabs_permission() { await do_test_update(async function background() { const url = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html"; - let tab = null; + const tab = await browser.tabs.create({ url }); let count = 0; browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) { - // An attention change can happen during tabs.create, so - // we can't compare against tab yet. - if (!("attention" in changeInfo)) { - browser.test.assertEq(tabId, tab.id, "Check tab id"); - } + browser.test.assertEq(tabId, tab.id, "Check tab id"); browser.test.log(`onUpdated: ${JSON.stringify(changeInfo)}`); browser.test.assertFalse( @@ -241,9 +237,7 @@ add_task(async function test_without_tabs_permission() { if (changeInfo.status == "complete") { count++; - if (count === 1) { - browser.tabs.reload(tabId); - } else { + if (count === 2) { browser.test.log("Reload complete"); browser.tabs.onUpdated.removeListener(onUpdated); browser.tabs.remove(tabId); @@ -252,7 +246,7 @@ add_task(async function test_without_tabs_permission() { } }); - tab = await browser.tabs.create({ url }); + browser.tabs.reload(tab.id); }, false /* withPermissions */); }); diff --git a/browser/components/search/test/browser/browser_google_behavior.js b/browser/components/search/test/browser/browser_google_behavior.js index 485e65157c31..896383ad062b 100644 --- a/browser/components/search/test/browser/browser_google_behavior.js +++ b/browser/components/search/test/browser/browser_google_behavior.js @@ -185,17 +185,15 @@ async function testSearchEngine(engineDetails) { await test.preTest(tab); } - let promises = [ - BrowserTestUtils.waitForDocLoadAndStopIt( - "https://www.google.com/search?client=" + test.code + "&q=foo", - tab - ), - BrowserTestUtils.browserStopped(tab.linkedBrowser, null, true), - ]; + let stateChangePromise = promiseStateChangeURI(); await test.run(tab); - await Promise.all(promises); + let receivedURI = await stateChangePromise; + + let receivedURLParams = new URLSearchParams(receivedURI.split("?")[1]); + + Assert.equal(receivedURLParams.get("client"), test.code); if (test.postTest) { await test.postTest(tab); diff --git a/browser/components/search/test/browser/browser_searchEngine_behaviors.js b/browser/components/search/test/browser/browser_searchEngine_behaviors.js index e18130d6984e..7677051617c9 100644 --- a/browser/components/search/test/browser/browser_searchEngine_behaviors.js +++ b/browser/components/search/test/browser/browser_searchEngine_behaviors.js @@ -189,14 +189,13 @@ async function testSearchEngine(engineDetails) { await test.preTest(tab); } - let promises = [ - BrowserTestUtils.waitForDocLoadAndStopIt(test.searchURL, tab), - BrowserTestUtils.browserStopped(tab.linkedBrowser, null, true), - ]; + let stateChangePromise = promiseStateChangeURI(); await test.run(tab); - await Promise.all(promises); + let receivedURI = await stateChangePromise; + + Assert.equal(receivedURI, test.searchURL); } engine.alias = undefined; diff --git a/browser/components/search/test/browser/head.js b/browser/components/search/test/browser/head.js index f5e022fa371c..a9c235d6557d 100644 --- a/browser/components/search/test/browser/head.js +++ b/browser/components/search/test/browser/head.js @@ -109,6 +109,73 @@ async function promiseNewEngine(basename, options = {}) { return engine; } +let promiseStateChangeFrameScript = + "data:," + + encodeURIComponent( + `(${() => { + /* globals docShell, sendAsyncMessage */ + + const global = this; + const LISTENER = Symbol("listener"); + let listener = { + QueryInterface: ChromeUtils.generateQI([ + "nsISupportsWeakReference", + "nsIWebProgressListener", + ]), + + onStateChange: function onStateChange(webProgress, req, flags, status) { + // Only care about top-level document starts + if ( + !webProgress.isTopLevel || + !(flags & Ci.nsIWebProgressListener.STATE_START) + ) { + return; + } + + req.QueryInterface(Ci.nsIChannel); + let spec = req.originalURI.spec; + if (spec == "about:blank") { + return; + } + + delete global[LISTENER]; + docShell.removeProgressListener(listener); + + req.cancel(Cr.NS_ERROR_FAILURE); + + sendAsyncMessage("PromiseStateChange::StateChanged", spec); + }, + }; + + // Make sure the weak reference stays alive. + global[LISTENER] = listener; + + docShell.QueryInterface(Ci.nsIWebProgress); + docShell.addProgressListener( + listener, + Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT + ); + }})()` + ); + +function promiseStateChangeURI() { + const MSG = "PromiseStateChange::StateChanged"; + + return new Promise(resolve => { + let mm = window.getGroupMessageManager("browsers"); + mm.loadFrameScript(promiseStateChangeFrameScript, true); + + let listener = msg => { + mm.removeMessageListener(MSG, listener); + mm.removeDelayedFrameScript(promiseStateChangeFrameScript); + + resolve(msg.data); + }; + + mm.addMessageListener(MSG, listener); + }); +} + // Get an array of the one-off buttons. function getOneOffs() { let oneOffs = []; diff --git a/browser/components/sessionstore/test/browser.ini b/browser/components/sessionstore/test/browser.ini index 743a72ce717b..8af1e095a9ce 100644 --- a/browser/components/sessionstore/test/browser.ini +++ b/browser/components/sessionstore/test/browser.ini @@ -84,6 +84,7 @@ skip-if = fission || debug # bug 1211084 [browser_backup_recovery.js] skip-if = (verify && debug && (os == 'linux')) [browser_broadcast.js] +skip-if = fission || (os == 'mac') || (os == 'linux' && !debug && bits == 64) # Bug 1533895; Fission: SecurityError: The operation is insecure. [browser_capabilities.js] [browser_cleaner.js] [browser_crashedTabs.js] diff --git a/browser/components/sessionstore/test/browser_broadcast.js b/browser/components/sessionstore/test/browser_broadcast.js index 114e034e7af1..cdb5b2202b65 100644 --- a/browser/components/sessionstore/test/browser_broadcast.js +++ b/browser/components/sessionstore/test/browser_broadcast.js @@ -10,7 +10,7 @@ const INITIAL_VALUE = "browser_broadcast.js-initial-value-" + Date.now(); * closing a tab. */ add_task(async function flush_on_tabclose() { - let tab = await createTabWithStorageData(["http://example.com/"]); + let tab = await createTabWithStorageData(["http://example.com"]); let browser = tab.linkedBrowser; await modifySessionStorage(browser, { test: "on-tab-close" }); @@ -33,7 +33,7 @@ add_task(async function flush_on_tabclose() { * duplicating a tab. */ add_task(async function flush_on_duplicate() { - let tab = await createTabWithStorageData(["http://example.com/"]); + let tab = await createTabWithStorageData(["http://example.com"]); let browser = tab.linkedBrowser; await modifySessionStorage(browser, { test: "on-duplicate" }); @@ -61,7 +61,7 @@ add_task(async function flush_on_duplicate() { */ add_task(async function flush_on_windowclose() { let win = await promiseNewWindow(); - let tab = await createTabWithStorageData(["http://example.com/"], win); + let tab = await createTabWithStorageData(["http://example.com"], win); let browser = tab.linkedBrowser; await modifySessionStorage(browser, { test: "on-window-close" }); @@ -84,7 +84,7 @@ add_task(async function flush_on_windowclose() { * (via e.g. setTabState) and does not overwrite the new data. */ add_task(async function flush_on_settabstate() { - let tab = await createTabWithStorageData(["http://example.com/"]); + let tab = await createTabWithStorageData(["http://example.com"]); let browser = tab.linkedBrowser; // Flush to make sure our tab state is up-to-date. @@ -115,7 +115,7 @@ add_task(async function flush_on_settabstate() { * that hasn't been received by chrome, yet. */ add_task(async function flush_on_tabclose_racy() { - let tab = await createTabWithStorageData(["http://example.com/"]); + let tab = await createTabWithStorageData(["http://example.com"]); let browser = tab.linkedBrowser; // Flush to make sure we start with an empty queue. @@ -152,8 +152,7 @@ async function createTabWithStorageData(urls, win = window) { for (let url of urls) { BrowserTestUtils.loadURI(browser, url); - await promiseBrowserLoaded(browser, true, url); - dump("Loaded url: " + url + "\n"); + await promiseBrowserLoaded(browser); await modifySessionStorage(browser, { test: INITIAL_VALUE }); } diff --git a/browser/components/urlbar/tests/browser/browser_canonizeURL.js b/browser/components/urlbar/tests/browser/browser_canonizeURL.js index d454bb060bab..1e8e642be8c8 100644 --- a/browser/components/urlbar/tests/browser/browser_canonizeURL.js +++ b/browser/components/urlbar/tests/browser/browser_canonizeURL.js @@ -55,16 +55,11 @@ add_task(async function checkCtrlWorks() { expectedURL, gBrowser.selectedBrowser ); - let promiseStopped = BrowserTestUtils.browserStopped( - gBrowser.selectedBrowser, - undefined, - true - ); gURLBar.focus(); gURLBar.inputField.value = inputValue.slice(0, -1); EventUtils.sendString(inputValue.slice(-1)); EventUtils.synthesizeKey("KEY_Enter", options); - await Promise.all([promiseLoad, promiseStopped]); + await promiseLoad; } }); diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index d76037c8b72c..0193a443839a 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -28,7 +28,6 @@ #include "mozilla/dom/WindowGlobalParent.h" #include "mozilla/dom/WindowProxyHolder.h" #include "mozilla/dom/SyncedContextInlines.h" -#include "mozilla/net/DocumentLoadListener.h" #include "mozilla/Assertions.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/Components.h" @@ -201,7 +200,6 @@ already_AddRefed BrowsingContext::CreateDetached( nsILoadInfo::EMBEDDER_POLICY_NULL); context->mFields.SetWithoutSyncing( nsILoadInfo::OPENER_POLICY_UNSAFE_NONE); - context->mFields.SetWithoutSyncing(false); if (aOpener && aOpener->SameOriginWithTop()) { // We inherit the opener policy if there is a creator and if the creator's @@ -1109,47 +1107,6 @@ bool BrowsingContext::CanSetOriginAttributes() { return true; } -Nullable BrowsingContext::GetAssociatedWindow() { - // nsILoadContext usually only returns same-process windows, - // so we intentionally return nullptr if this BC is out of - // process. - if (IsInProcess()) { - return WindowProxyHolder(this); - } - return nullptr; -} - -Nullable BrowsingContext::GetTopWindow() { - return Top()->GetAssociatedWindow(); -} - -Element* BrowsingContext::GetTopFrameElement() { - return Top()->GetEmbedderElement(); -} - -void BrowsingContext::SetUsePrivateBrowsing(bool aUsePrivateBrowsing, - ErrorResult& aError) { - nsresult rv = SetUsePrivateBrowsing(aUsePrivateBrowsing); - if (NS_FAILED(rv)) { - aError.Throw(rv); - } -} - -void BrowsingContext::SetUseTrackingProtectionWebIDL( - bool aUseTrackingProtection) { - SetForceEnableTrackingProtection(aUseTrackingProtection); -} - -void BrowsingContext::GetOriginAttributes(JSContext* aCx, - JS::MutableHandle aVal, - ErrorResult& aError) { - AssertOriginAttributesMatchPrivateBrowsing(); - - if (!ToJSValue(aCx, mOriginAttributes, aVal)) { - aError.NoteJSContextException(aCx); - } -} - NS_IMETHODIMP BrowsingContext::GetAssociatedWindow( mozIDOMWindowProxy** aAssociatedWindow) { nsCOMPtr win = GetDOMWindow(); @@ -1162,11 +1119,17 @@ NS_IMETHODIMP BrowsingContext::GetTopWindow(mozIDOMWindowProxy** aTopWindow) { } NS_IMETHODIMP BrowsingContext::GetTopFrameElement(Element** aTopFrameElement) { - RefPtr topFrameElement = GetTopFrameElement(); + RefPtr topFrameElement = Top()->GetEmbedderElement(); topFrameElement.forget(aTopFrameElement); return NS_OK; } +NS_IMETHODIMP BrowsingContext::GetNestedFrameId(uint64_t* aNestedFrameId) { + // FIXME: nestedFrameId should be removed, as it was only used by B2G. + *aNestedFrameId = 0; + return NS_OK; +} + NS_IMETHODIMP BrowsingContext::GetIsContent(bool* aIsContent) { *aIsContent = IsContent(); return NS_OK; @@ -1342,7 +1305,6 @@ void BrowsingContext::AssertOriginAttributesMatchPrivateBrowsing() { NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowsingContext) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsILoadContext) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END @@ -1466,30 +1428,9 @@ nsresult BrowsingContext::LoadURI(nsDocShellLoadState* aLoadState, } if (ContentParent* cp = Canonical()->GetContentParent()) { - // Attempt to initiate this load immediately in the parent, if it succeeds - // it'll return a unique identifier so that we can find it later. - uint32_t loadIdentifier = 0; - if (Canonical()->AttemptLoadURIInParent(aLoadState, &loadIdentifier)) { - aLoadState->SetLoadIdentifier(loadIdentifier); - } - cp->TransmitBlobDataIfBlobURL(aLoadState->URI(), aLoadState->TriggeringPrincipal()); - - // Setup a confirmation callback once the content process receives this - // load. Normally we'd expect a PDocumentChannel actor to have been - // created to claim the load identifier by that time. If not, then it - // won't be coming, so make sure we clean up and deregister. - cp->SendLoadURI(this, aLoadState, aSetNavigating) - ->Then(GetMainThreadSerialEventTarget(), __func__, - [loadIdentifier]( - const PContentParent::LoadURIPromise::ResolveOrRejectValue& - aValue) { - if (loadIdentifier) { - net::DocumentLoadListener::CleanupParentLoadAttempt( - loadIdentifier); - } - }); + Unused << cp->SendLoadURI(this, aLoadState, aSetNavigating); } } return NS_OK; @@ -1896,12 +1837,6 @@ bool BrowsingContext::CanSet(FieldIndex, return CheckOnlyOwningProcessCanSet(aSource); } -bool BrowsingContext::CanSet(FieldIndex, - const bool& aWatchedByDevtools, - ContentParent* aSource) { - return CheckOnlyOwningProcessCanSet(aSource); -} - bool BrowsingContext::CanSet(FieldIndex, const nsString& aUserAgent, ContentParent* aSource) { diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index 170516a243c0..e49cab9cc6cd 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -123,7 +123,6 @@ class WindowProxyHolder; FIELD(MessageManagerGroup, nsString) \ FIELD(MaxTouchPointsOverride, uint8_t) \ FIELD(FullZoom, float) \ - FIELD(WatchedByDevtools, bool) \ FIELD(TextZoom, float) // BrowsingContext, in this context, is the cross process replicated @@ -261,8 +260,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { void RestoreChildren(Children&& aChildren, bool aFromIPC = false); // Triggers a load in the process which currently owns this BrowsingContext. - nsresult LoadURI(nsDocShellLoadState* aLoadState, - bool aSetNavigating = false); + nsresult LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating = false); nsresult InternalLoad(nsDocShellLoadState* aLoadState, nsIDocShell** aDocShell, nsIRequest** aRequest); @@ -355,19 +353,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { BrowsingContextGroup* Group() { return mGroup; } - // WebIDL bindings for nsILoadContext - Nullable GetAssociatedWindow(); - Nullable GetTopWindow(); - Element* GetTopFrameElement(); - bool GetIsContent() { return IsContent(); } - void SetUsePrivateBrowsing(bool aUsePrivateBrowsing, ErrorResult& aError); - // Needs a different name to disambiguate from the xpidl method with - // the same signature but different return value. - void SetUseTrackingProtectionWebIDL(bool aUseTrackingProtection); - bool UseTrackingProtectionWebIDL() { return UseTrackingProtection(); } - void GetOriginAttributes(JSContext* aCx, JS::MutableHandle aVal, - ErrorResult& aError); - bool InRDMPane() const { return GetInRDMPane(); } float FullZoom() const { return GetFullZoom(); } @@ -702,8 +687,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { ContentParent* aSource); bool CanSet(FieldIndex, const bool& aAllowPlugins, ContentParent* aSource); - bool CanSet(FieldIndex, const bool& aWatchedByDevtools, - ContentParent* aSource); template bool CanSet(FieldIndex, const T&, ContentParent*) { diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index f28981507cd3..08626daad86b 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -15,8 +15,6 @@ #include "mozilla/dom/PlaybackController.h" #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/NullPrincipal.h" -#include "mozilla/net/DocumentLoadListener.h" -#include "nsNetUtil.h" #include "nsGlobalWindowOuter.h" @@ -526,75 +524,6 @@ MediaController* CanonicalBrowsingContext::GetMediaController() { return mTabMediaController; } -bool CanonicalBrowsingContext::AttemptLoadURIInParent( - nsDocShellLoadState* aLoadState, uint32_t* aLoadIdentifier) { - // We currently only support starting loads directly from the - // CanonicalBrowsingContext for top-level BCs. - if (!IsTopContent() || !GetContentParent() || - !StaticPrefs::browser_tabs_documentchannel() || - !StaticPrefs::browser_tabs_documentchannel_parent_initiated()) { - return false; - } - - // We currently don't support initiating loads in the parent when they are - // watched by devtools. This is because devtools tracks loads using content - // process notifications, which happens after the load is initiated in this - // case. Devtools clears all prior requests when it detects a new navigation, - // so it drops the main document load that happened here. - if (GetWatchedByDevtools()) { - return false; - } - - // DocumentChannel currently only supports connecting channels into the - // content process, so we can only support schemes that will always be loaded - // there for now. Restrict to just http(s) for simplicity. - if (net::SchemeIsHTTP(aLoadState->URI()) || - net::SchemeIsHTTPS(aLoadState->URI())) { - return false; - } - - uint64_t outerWindowId = 0; - if (WindowGlobalParent* global = GetCurrentWindowGlobal()) { - nsCOMPtr currentURI = global->GetDocumentURI(); - if (currentURI) { - bool newURIHasRef = false; - aLoadState->URI()->GetHasRef(&newURIHasRef); - bool equalsExceptRef = false; - aLoadState->URI()->EqualsExceptRef(currentURI, &equalsExceptRef); - - if (equalsExceptRef && newURIHasRef) { - // This navigation is same-doc WRT the current one, we should pass it - // down to the docshell to be handled. - return false; - } - } - // If the current document has a beforeunload listener, then we need to - // start the load in that process after we fire the event. - if (global->HasBeforeUnload()) { - return false; - } - - outerWindowId = global->OuterWindowId(); - } - - // If we successfully open the DocumentChannel, then it'll register - // itself using aLoadIdentifier and be kept alive until it completes - // loading. - return net::DocumentLoadListener::OpenFromParent( - this, aLoadState, outerWindowId, aLoadIdentifier); -} - -void CanonicalBrowsingContext::StartDocumentLoad( - net::DocumentLoadListener* aLoad) { - mCurrentLoad = aLoad; -} -void CanonicalBrowsingContext::EndDocumentLoad( - net::DocumentLoadListener* aLoad) { - if (mCurrentLoad == aLoad) { - mCurrentLoad = nullptr; - } -} - NS_IMPL_CYCLE_COLLECTION_INHERITED(CanonicalBrowsingContext, BrowsingContext, mSessionHistory) diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index 84956e3a7c0c..4298564b75da 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -19,10 +19,6 @@ #include "nsISHEntry.h" namespace mozilla { -namespace net { -class DocumentLoadListener; -} - namespace dom { class WindowGlobalParent; @@ -114,9 +110,6 @@ class CanonicalBrowsingContext final : public BrowsingContext { // if the top-level browsing context has been discarded. MediaController* GetMediaController(); - bool AttemptLoadURIInParent(nsDocShellLoadState* aLoadState, - uint32_t* aLoadIdentifier); - bool HasHistoryEntry(nsISHEntry* aEntry) const { return aEntry && (aEntry == mOSHE || aEntry == mLSHE); } @@ -177,15 +170,6 @@ class CanonicalBrowsingContext final : public BrowsingContext { uint64_t mPendingSwitchId; }; - friend class net::DocumentLoadListener; - // Called when a DocumentLoadListener is created to start a load for - // this browsing context. - void StartDocumentLoad(net::DocumentLoadListener* aLoad); - // Called once DocumentLoadListener completes handling a load, and it - // is either complete, or handed off to the final channel to deliver - // data to the destination docshell. - void EndDocumentLoad(net::DocumentLoadListener* aLoad); - // XXX(farre): Store a ContentParent pointer here rather than mProcessId? // Indicates which process owns the docshell. uint64_t mProcessId; @@ -207,8 +191,6 @@ class CanonicalBrowsingContext final : public BrowsingContext { // context. RefPtr mTabMediaController; - RefPtr mCurrentLoad; - // These are being mirrored from docshell nsCOMPtr mOSHE; nsCOMPtr mLSHE; diff --git a/docshell/base/LoadContext.cpp b/docshell/base/LoadContext.cpp index 82de68472427..0336c52e2bf3 100644 --- a/docshell/base/LoadContext.cpp +++ b/docshell/base/LoadContext.cpp @@ -20,6 +20,7 @@ NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor) LoadContext::LoadContext(nsIPrincipal* aPrincipal, nsILoadContext* aOptionalBase) : mTopFrameElement(nullptr), + mNestedFrameId(0), mIsContent(true), mUseRemoteTabs(false), mUseRemoteSubframes(false), @@ -67,6 +68,13 @@ LoadContext::GetTopFrameElement(dom::Element** aElement) { return NS_OK; } +NS_IMETHODIMP +LoadContext::GetNestedFrameId(uint64_t* aId) { + NS_ENSURE_ARG(aId); + *aId = mNestedFrameId; + return NS_OK; +} + NS_IMETHODIMP LoadContext::GetIsContent(bool* aIsContent) { MOZ_ASSERT(mIsNotNull); diff --git a/docshell/base/LoadContext.h b/docshell/base/LoadContext.h index 470dd52bedc0..52b67d9d87de 100644 --- a/docshell/base/LoadContext.h +++ b/docshell/base/LoadContext.h @@ -36,6 +36,21 @@ class LoadContext final : public nsILoadContext, public nsIInterfaceRequestor { LoadContext(const IPC::SerializedLoadContext& aToCopy, dom::Element* aTopFrameElement, OriginAttributes& aAttrs) : mTopFrameElement(do_GetWeakReference(aTopFrameElement)), + mNestedFrameId(0), + mIsContent(aToCopy.mIsContent), + mUseRemoteTabs(aToCopy.mUseRemoteTabs), + mUseRemoteSubframes(aToCopy.mUseRemoteSubframes), + mUseTrackingProtection(aToCopy.mUseTrackingProtection), +#ifdef DEBUG + mIsNotNull(aToCopy.mIsNotNull), +#endif + mOriginAttributes(aAttrs) { + } + + LoadContext(const IPC::SerializedLoadContext& aToCopy, + uint64_t aNestedFrameId, OriginAttributes& aAttrs) + : mTopFrameElement(nullptr), + mNestedFrameId(aNestedFrameId), mIsContent(aToCopy.mIsContent), mUseRemoteTabs(aToCopy.mUseRemoteTabs), mUseRemoteSubframes(aToCopy.mUseRemoteSubframes), @@ -51,6 +66,7 @@ class LoadContext final : public nsILoadContext, public nsIInterfaceRequestor { bool aUseRemoteSubframes, bool aUseTrackingProtection, const OriginAttributes& aAttrs) : mTopFrameElement(do_GetWeakReference(aTopFrameElement)), + mNestedFrameId(0), mIsContent(aIsContent), mUseRemoteTabs(aUseRemoteTabs), mUseRemoteSubframes(aUseRemoteSubframes), @@ -66,6 +82,7 @@ class LoadContext final : public nsILoadContext, public nsIInterfaceRequestor { // Constructor taking reserved origin attributes. explicit LoadContext(OriginAttributes& aAttrs) : mTopFrameElement(nullptr), + mNestedFrameId(0), mIsContent(false), mUseRemoteTabs(false), mUseRemoteSubframes(false), @@ -84,6 +101,7 @@ class LoadContext final : public nsILoadContext, public nsIInterfaceRequestor { ~LoadContext() {} nsWeakPtr mTopFrameElement; + uint64_t mNestedFrameId; bool mIsContent; bool mUseRemoteTabs; bool mUseRemoteSubframes; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 66e1a777ac15..7923956d0994 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -9792,6 +9792,26 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState, mContentTypeHint.Truncate(); } + if (mLoadType == LOAD_NORMAL_ALLOW_MIXED_CONTENT || + mLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) { + rv = SetMixedContentChannel(channel); + NS_ENSURE_SUCCESS(rv, rv); + } else if (mMixedContentChannel) { + /* + * If the user "Disables Protection on This Page", we call + * SetMixedContentChannel for the first time, otherwise + * mMixedContentChannel is still null. + * Later, if the new channel passes a same orign check, we remember the + * users decision by calling SetMixedContentChannel using the new channel. + * This way, the user does not have to click the disable protection button + * over and over for browsing the same site. + */ + rv = nsContentUtils::CheckSameOrigin(mMixedContentChannel, channel); + if (NS_FAILED(rv) || NS_FAILED(SetMixedContentChannel(channel))) { + SetMixedContentChannel(nullptr); + } + } + rv = DoChannelLoad( channel, uriLoader, aLoadState->HasLoadFlags(INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER)); @@ -9999,26 +10019,6 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel, uint32_t aOpenFlags) { nsresult rv = NS_OK; - if (mLoadType == LOAD_NORMAL_ALLOW_MIXED_CONTENT || - mLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) { - rv = SetMixedContentChannel(aChannel); - NS_ENSURE_SUCCESS(rv, rv); - } else if (mMixedContentChannel) { - /* - * If the user "Disables Protection on This Page", we call - * SetMixedContentChannel for the first time, otherwise - * mMixedContentChannel is still null. - * Later, if the new channel passes a same orign check, we remember the - * users decision by calling SetMixedContentChannel using the new channel. - * This way, the user does not have to click the disable protection button - * over and over for browsing the same site. - */ - rv = nsContentUtils::CheckSameOrigin(mMixedContentChannel, aChannel); - if (NS_FAILED(rv) || NS_FAILED(SetMixedContentChannel(aChannel))) { - SetMixedContentChannel(nullptr); - } - } - // If anything fails here, make sure to clear our initial ClientSource. auto cleanupInitialClient = MakeScopeExit([&] { mInitialClientSource.reset(); }); @@ -10070,7 +10070,6 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel, // ClientInfo, so we just need to allocate a corresponding ClientSource. CreateReservedSourceIfNeeded(aChannel, win->EventTargetFor(TaskCategory::Other)); - rv = NS_OK; } else { rv = AddClientChannelHelper(aChannel, std::move(noReservedClient), GetInitialClientInfo(), @@ -11765,6 +11764,11 @@ nsDocShell::GetTopFrameElement(Element** aElement) { return mBrowsingContext->GetTopFrameElement(aElement); } +NS_IMETHODIMP +nsDocShell::GetNestedFrameId(uint64_t* aId) { + return mBrowsingContext->GetNestedFrameId(aId); +} + NS_IMETHODIMP nsDocShell::GetUseTrackingProtection(bool* aUseTrackingProtection) { return mBrowsingContext->GetUseTrackingProtection(aUseTrackingProtection); @@ -12436,6 +12440,10 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) { aLoadState->GetPendingRedirectedChannel(), previousURI, previousFlags, aRedirects); + MOZ_ASSERT( + (self->mCurrentURI && NS_IsAboutBlank(self->mCurrentURI)) || + !self->mTiming, + "timing object can't already exists in non-about:blank loads"); self->mTiming = new nsDOMNavigationTiming(self, aTiming); // If we're performing a history load, locate the correct history entry, @@ -12845,6 +12853,5 @@ nsDocShell::GetWatchedByDevtools(bool* aWatched) { NS_IMETHODIMP nsDocShell::SetWatchedByDevtools(bool aWatched) { mWatchedByDevtools = aWatched; - mBrowsingContext->SetWatchedByDevtools(aWatched); return NS_OK; } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index f8bfb58fc5a6..2a0e5273979e 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -305,6 +305,7 @@ class nsDocShell final : public nsDocLoader, NS_IMETHOD GetAssociatedWindow(mozIDOMWindowProxy**) override; NS_IMETHOD GetTopWindow(mozIDOMWindowProxy**) override; NS_IMETHOD GetTopFrameElement(mozilla::dom::Element**) override; + NS_IMETHOD GetNestedFrameId(uint64_t*) override; NS_IMETHOD GetIsContent(bool*) override; NS_IMETHOD GetUsePrivateBrowsing(bool*) override; NS_IMETHOD SetUsePrivateBrowsing(bool) override; diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index f8cab373451e..cbf9d5d860e6 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -85,8 +85,7 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI) mHasValidUserGestureActivation(false), mTypeHint(VoidCString()), mFileName(VoidString()), - mIsFromProcessingFrameAttributes(false), - mLoadIdentifier(0) { + mIsFromProcessingFrameAttributes(false) { MOZ_ASSERT(aURI, "Cannot create a LoadState with a null URI!"); } @@ -125,7 +124,7 @@ nsDocShellLoadState::nsDocShellLoadState( mPostDataStream = aLoadState.PostDataStream(); mHeadersStream = aLoadState.HeadersStream(); mSrcdocData = aLoadState.SrcdocData(); - mLoadIdentifier = aLoadState.LoadIdentifier(); + mResultPrincipalURI = aLoadState.ResultPrincipalURI(); if (!aLoadState.SHEntry() || !StaticPrefs::fission_sessionHistoryInParent()) { return; } @@ -136,42 +135,6 @@ nsDocShellLoadState::nsDocShellLoadState( } } -nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState& aOther) - : mReferrerInfo(aOther.mReferrerInfo), - mURI(aOther.mURI), - mOriginalURI(aOther.mOriginalURI), - mResultPrincipalURI(aOther.mResultPrincipalURI), - mResultPrincipalURIIsSome(aOther.mResultPrincipalURIIsSome), - mTriggeringPrincipal(aOther.mTriggeringPrincipal), - mCsp(aOther.mCsp), - mKeepResultPrincipalURIIfSet(aOther.mKeepResultPrincipalURIIfSet), - mLoadReplace(aOther.mLoadReplace), - mInheritPrincipal(aOther.mInheritPrincipal), - mPrincipalIsExplicit(aOther.mPrincipalIsExplicit), - mPrincipalToInherit(aOther.mPrincipalToInherit), - mStoragePrincipalToInherit(aOther.mStoragePrincipalToInherit), - mForceAllowDataURI(aOther.mForceAllowDataURI), - mOriginalFrameSrc(aOther.mOriginalFrameSrc), - mIsFormSubmission(aOther.mIsFormSubmission), - mLoadType(aOther.mLoadType), - mSHEntry(aOther.mSHEntry), - mTarget(aOther.mTarget), - mPostDataStream(aOther.mPostDataStream), - mHeadersStream(aOther.mHeadersStream), - mSrcdocData(aOther.mSrcdocData), - mSourceBrowsingContext(aOther.mSourceBrowsingContext), - mBaseURI(aOther.mBaseURI), - mLoadFlags(aOther.mLoadFlags), - mFirstParty(aOther.mFirstParty), - mHasValidUserGestureActivation(aOther.mHasValidUserGestureActivation), - mTypeHint(aOther.mTypeHint), - mFileName(aOther.mFileName), - mIsFromProcessingFrameAttributes(aOther.mIsFromProcessingFrameAttributes), - mPendingRedirectedChannel(aOther.mPendingRedirectedChannel), - mOriginalURIString(aOther.mOriginalURIString), - mCancelContentJSEpoch(aOther.mCancelContentJSEpoch), - mLoadIdentifier(aOther.mLoadIdentifier) {} - nsDocShellLoadState::~nsDocShellLoadState() {} nsresult nsDocShellLoadState::CreateFromPendingChannel( @@ -774,7 +737,6 @@ DocShellLoadStateInit nsDocShellLoadState::Serialize() { loadState.HeadersStream() = mHeadersStream; loadState.SrcdocData() = mSrcdocData; loadState.ResultPrincipalURI() = mResultPrincipalURI; - loadState.LoadIdentifier() = mLoadIdentifier; if (!mSHEntry || !StaticPrefs::fission_sessionHistoryInParent()) { // Without the pref, we don't have an actor for shentry and thus // we can't serialize it. We could write custom (de)serializers, diff --git a/docshell/base/nsDocShellLoadState.h b/docshell/base/nsDocShellLoadState.h index ced23aa18d76..ef486437de23 100644 --- a/docshell/base/nsDocShellLoadState.h +++ b/docshell/base/nsDocShellLoadState.h @@ -43,7 +43,6 @@ class nsDocShellLoadState final { explicit nsDocShellLoadState(nsIURI* aURI); explicit nsDocShellLoadState( const mozilla::dom::DocShellLoadStateInit& aLoadState); - explicit nsDocShellLoadState(const nsDocShellLoadState& aOther); static nsresult CreateFromPendingChannel(nsIChannel* aPendingChannel, nsDocShellLoadState** aResult); @@ -229,9 +228,6 @@ class nsDocShellLoadState final { return mCancelContentJSEpoch; } - void SetLoadIdentifier(uint32_t aIdent) { mLoadIdentifier = aIdent; } - uint32_t GetLoadIdentifier() const { return mLoadIdentifier; } - // When loading a document through nsDocShell::LoadURI(), a special set of // flags needs to be set based on other values in nsDocShellLoadState. This // function calculates those flags, before the LoadState is passed to @@ -392,12 +388,6 @@ class nsDocShellLoadState final { // An optional value to pass to nsIDocShell::setCancelJSEpoch // when initiating the load. mozilla::Maybe mCancelContentJSEpoch; - - // An optional identifier that refers to a DocumentLoadListener - // created in the parent process for this loads. DocumentChannels - // created in the content process can use this to find and attach - // to the in progress load. - uint32_t mLoadIdentifier; }; #endif /* nsDocShellLoadState_h__ */ diff --git a/docshell/base/nsILoadContext.idl b/docshell/base/nsILoadContext.idl index 234ba531c2b4..67b8ff1cd7b4 100644 --- a/docshell/base/nsILoadContext.idl +++ b/docshell/base/nsILoadContext.idl @@ -55,6 +55,14 @@ interface nsILoadContext : nsISupports */ readonly attribute Element topFrameElement; + /** + * If this LoadContext corresponds to a nested remote iframe, we don't have + * access to the topFrameElement. Instead, we must use this id to send + * messages. A return value of 0 signifies that this load context is not for + * a nested frame. + */ + readonly attribute unsigned long long nestedFrameId; + /** * True if the load context is content (as opposed to chrome). This is * determined based on the type of window the load is performed in, NOT based diff --git a/dom/browser-element/BrowserElementPromptService.jsm b/dom/browser-element/BrowserElementPromptService.jsm index 0218b0a09ca9..9ff49c2051d7 100644 --- a/dom/browser-element/BrowserElementPromptService.jsm +++ b/dom/browser-element/BrowserElementPromptService.jsm @@ -523,7 +523,8 @@ AuthPromptWrapper.prototype = { ); let frame = context.topFrameElement; if (!frame) { - return false; + // This function returns a boolean value + return !!context.nestedFrameId; } if (!BrowserElementPromptService.getBrowserElementParentForFrame(frame)) { diff --git a/dom/chrome-webidl/BrowsingContext.webidl b/dom/chrome-webidl/BrowsingContext.webidl index 28ad575e6d0a..d1580b0d040b 100644 --- a/dom/chrome-webidl/BrowsingContext.webidl +++ b/dom/chrome-webidl/BrowsingContext.webidl @@ -5,29 +5,6 @@ interface nsIDocShell; -interface mixin LoadContextMixin { - readonly attribute WindowProxy? associatedWindow; - - readonly attribute WindowProxy? topWindow; - - readonly attribute Element? topFrameElement; - - readonly attribute boolean isContent; - - [SetterThrows] - attribute boolean usePrivateBrowsing; - - readonly attribute boolean useRemoteTabs; - - readonly attribute boolean useRemoteSubframes; - - [BinaryName="useTrackingProtectionWebIDL"] - attribute boolean useTrackingProtection; - - [NewObject, Throws] - readonly attribute any originAttributes; -}; - [Exposed=Window, ChromeOnly] interface BrowsingContext { static BrowsingContext? get(unsigned long long aId); @@ -93,8 +70,6 @@ interface BrowsingContext { void setRDMPaneMaxTouchPoints(octet maxTouchPoints); }; -BrowsingContext includes LoadContextMixin; - [Exposed=Window, ChromeOnly] interface CanonicalBrowsingContext : BrowsingContext { sequence getWindowGlobals(); diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp index 0c047ab86a0c..d91bc04d6075 100644 --- a/dom/ipc/BrowserParent.cpp +++ b/dom/ipc/BrowserParent.cpp @@ -3795,6 +3795,7 @@ class FakeChannel final : public nsIChannel, elem.forget(aElement); return NS_OK; } + NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL; NS_IMETHOD GetIsContent(bool*) NO_IMPL; NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL; NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL; diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 3a5f89e5977c..20fb94008fe5 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -4089,10 +4089,7 @@ mozilla::ipc::IPCResult ContentChild::RecvScriptError( mozilla::ipc::IPCResult ContentChild::RecvLoadURI( const MaybeDiscarded& aContext, - nsDocShellLoadState* aLoadState, bool aSetNavigating, - LoadURIResolver&& aResolve) { - auto resolveOnExit = MakeScopeExit([&] { aResolve(true); }); - + nsDocShellLoadState* aLoadState, bool aSetNavigating) { if (aContext.IsNullOrDiscarded()) { return IPC_OK(); } diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index c3110e3a75e7..b85cd0aa1abe 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -792,8 +792,7 @@ class ContentChild final mozilla::ipc::IPCResult RecvLoadURI( const MaybeDiscarded& aContext, - nsDocShellLoadState* aLoadState, bool aSetNavigating, - LoadURIResolver&& aResolve); + nsDocShellLoadState* aLoadState, bool aSetNavigating); mozilla::ipc::IPCResult RecvInternalLoad( const MaybeDiscarded& aContext, diff --git a/dom/ipc/DOMTypes.ipdlh b/dom/ipc/DOMTypes.ipdlh index ada864e57000..6d4cc6520fd4 100644 --- a/dom/ipc/DOMTypes.ipdlh +++ b/dom/ipc/DOMTypes.ipdlh @@ -285,8 +285,6 @@ struct DocShellLoadStateInit // nsCOMPtr mSourceDocShell; // bool mIsSrcDocLoad; // useless without sourcedocshell // nsIChannel pendingRedirectedChannel; // sent through other mechanism - - uint32_t LoadIdentifier; }; struct TimedChannelInfo diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 968282bca34a..a32ad9d1fad7 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -841,8 +841,7 @@ child: async EvictContentViewers(uint64_t[] aToEvictSharedStateIDs); - async LoadURI(MaybeDiscardedBrowsingContext aContext, nsDocShellLoadState aLoadState, bool aSetNavigating) - returns (bool aSuccess); + async LoadURI(MaybeDiscardedBrowsingContext aContext, nsDocShellLoadState aLoadState, bool aSetNavigating); async InternalLoad(MaybeDiscardedBrowsingContext aContext, nsDocShellLoadState aLoadState, bool aTakeFocus); diff --git a/dom/security/test/general/browser_test_referrer_loadInOtherProcess.js b/dom/security/test/general/browser_test_referrer_loadInOtherProcess.js index 25ed6fbcc729..9b81af138df9 100644 --- a/dom/security/test/general/browser_test_referrer_loadInOtherProcess.js +++ b/dom/security/test/general/browser_test_referrer_loadInOtherProcess.js @@ -87,7 +87,7 @@ var waitForLoad = async function(uri) { }; gBrowser.selectedBrowser.webNavigation.loadURI(uri, loadURIOptions); - await BrowserTestUtils.browserStopped(gBrowser, uri); + await BrowserTestUtils.browserStopped(gBrowser); }; // Tests referrerInfo when navigating from a page in the remote process to main diff --git a/dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js b/dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js index 7eda392d63df..0ce1d4ad7587 100644 --- a/dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js +++ b/dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js @@ -32,40 +32,38 @@ function test() { } function doTest(aIsPrivateMode, aWindow, aCallback) { - BrowserTestUtils.browserLoaded( - aWindow.gBrowser.selectedBrowser, - false, - testURI - ).then(() => { - consoleObserver = { - observe(aSubject, aTopic, aData) { - if (aTopic == "console-api-log-event") { - afterEvents = ConsoleAPIStorage.getEvents(innerID); - is( - beforeEvents.length == afterEvents.length - 1, - storageShouldOccur, - "storage should" + (storageShouldOccur ? "" : " not") + " occur" - ); - - executeSoon(function() { - Services.obs.removeObserver( - consoleObserver, - "console-api-log-event" + BrowserTestUtils.browserLoaded(aWindow.gBrowser.selectedBrowser).then( + () => { + consoleObserver = { + observe(aSubject, aTopic, aData) { + if (aTopic == "console-api-log-event") { + afterEvents = ConsoleAPIStorage.getEvents(innerID); + is( + beforeEvents.length == afterEvents.length - 1, + storageShouldOccur, + "storage should" + (storageShouldOccur ? "" : " not") + " occur" ); - aCallback(); - }); - } - }, - }; - aWindow.Services.obs.addObserver( - consoleObserver, - "console-api-log-event" - ); - aWindow.nativeConsole.log( - "foo bar baz (private: " + aIsPrivateMode + ")" - ); - }); + executeSoon(function() { + Services.obs.removeObserver( + consoleObserver, + "console-api-log-event" + ); + aCallback(); + }); + } + }, + }; + + aWindow.Services.obs.addObserver( + consoleObserver, + "console-api-log-event" + ); + aWindow.nativeConsole.log( + "foo bar baz (private: " + aIsPrivateMode + ")" + ); + } + ); // We expect that console API messages are always stored. storageShouldOccur = true; diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index a6e023d6cf1d..d35bd87d447c 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -989,13 +989,6 @@ value: false mirror: always -# If set, use DocumentChannel to directly initiate loads from -# parent-process BrowsingContexts -- name: browser.tabs.documentchannel.parent-initiated - type: bool - value: true - mirror: always - - name: browser.tabs.remote.desktopbehavior type: bool value: false diff --git a/netwerk/ipc/DocumentChannelChild.cpp b/netwerk/ipc/DocumentChannelChild.cpp index 57b5536a4826..21a366ee1afc 100644 --- a/netwerk/ipc/DocumentChannelChild.cpp +++ b/netwerk/ipc/DocumentChannelChild.cpp @@ -97,13 +97,23 @@ DocumentChannelChild::AsyncOpen(nsIStreamListener* aListener) { args.timing() = Some(mTiming); } + nsCOMPtr iBrowserChild; + NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, + NS_GET_TEMPLATE_IID(nsIBrowserChild), + getter_AddRefs(iBrowserChild)); + BrowserChild* browserChild = static_cast(iBrowserChild.get()); + if (MissingRequiredBrowserChild(browserChild, "documentchannel")) { + return NS_ERROR_ILLEGAL_VALUE; + } + args.hasValidTransientUserAction() = GetDocShell() ->GetBrowsingContext() ->HasValidTransientUserGestureActivation(); gNeckoChild->SendPDocumentChannelConstructor( - this, GetDocShell()->GetBrowsingContext(), args); + this, browserChild, GetDocShell()->GetBrowsingContext(), + IPC::SerializedLoadContext(this), args); mIsPending = true; mWasOpened = true; diff --git a/netwerk/ipc/DocumentChannelParent.cpp b/netwerk/ipc/DocumentChannelParent.cpp index ad612b1d1889..022c42356e22 100644 --- a/netwerk/ipc/DocumentChannelParent.cpp +++ b/netwerk/ipc/DocumentChannelParent.cpp @@ -18,29 +18,27 @@ using namespace mozilla::dom; namespace mozilla { namespace net { -DocumentChannelParent::DocumentChannelParent() { +DocumentChannelParent::DocumentChannelParent(CanonicalBrowsingContext* aContext, + nsILoadContext* aLoadContext) { LOG(("DocumentChannelParent ctor [this=%p]", this)); + // Sometime we can get this called without a BrowsingContext, so that we have + // an actor to call SendFailedAsyncOpen on. + if (aContext) { + mParent = new DocumentLoadListener(aContext, aLoadContext, this); + } } DocumentChannelParent::~DocumentChannelParent() { LOG(("DocumentChannelParent dtor [this=%p]", this)); } -bool DocumentChannelParent::Init(dom::CanonicalBrowsingContext* aContext, - const DocumentChannelCreationArgs& aArgs) { +bool DocumentChannelParent::Init(const DocumentChannelCreationArgs& aArgs) { + MOZ_ASSERT(mParent); RefPtr loadState = new nsDocShellLoadState(aArgs.loadState()); LOG(("DocumentChannelParent Init [this=%p, uri=%s]", this, loadState->URI()->GetSpecOrDefault().get())); - if (loadState->GetLoadIdentifier()) { - mParent = DocumentLoadListener::ClaimParentLoad( - loadState->GetLoadIdentifier(), this); - return !!mParent; - } - - mParent = new DocumentLoadListener(aContext, this); - Maybe clientInfo; if (aArgs.initialClientInfo().isSome()) { clientInfo.emplace(ClientInfo(aArgs.initialClientInfo().ref())); @@ -48,7 +46,7 @@ bool DocumentChannelParent::Init(dom::CanonicalBrowsingContext* aContext, nsresult rv = NS_ERROR_UNEXPECTED; if (!mParent->Open(loadState, aArgs.loadFlags(), aArgs.cacheKey(), - Some(aArgs.channelId()), aArgs.asyncOpenTime(), + aArgs.channelId(), aArgs.asyncOpenTime(), aArgs.timing().refOr(nullptr), std::move(clientInfo), aArgs.outerWindowId(), aArgs.hasValidTransientUserAction(), &rv)) { @@ -63,7 +61,7 @@ DocumentChannelParent::RedirectToRealChannel( nsTArray>&& aStreamFilterEndpoints, uint32_t aRedirectFlags, uint32_t aLoadFlags) { - if (!CanSend() || !mParent) { + if (!CanSend()) { return PDocumentChannelParent::RedirectToRealChannelPromise:: CreateAndReject(ResponseRejectReason::ChannelClosed, __func__); } diff --git a/netwerk/ipc/DocumentChannelParent.h b/netwerk/ipc/DocumentChannelParent.h index 2cb5e5144c5f..1c270adf95c8 100644 --- a/netwerk/ipc/DocumentChannelParent.h +++ b/netwerk/ipc/DocumentChannelParent.h @@ -26,10 +26,10 @@ class DocumentChannelParent final : public ADocumentChannelBridge, public: NS_INLINE_DECL_REFCOUNTING(DocumentChannelParent, override); - explicit DocumentChannelParent(); + explicit DocumentChannelParent(dom::CanonicalBrowsingContext* aContext, + nsILoadContext* aLoadContext); - bool Init(dom::CanonicalBrowsingContext* aContext, - const DocumentChannelCreationArgs& aArgs); + bool Init(const DocumentChannelCreationArgs& aArgs); // PDocumentChannelParent bool RecvCancel(const nsresult& aStatus) { diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index 417e99f93e29..635dd9ebd350 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -33,12 +33,9 @@ #include "nsIViewSourceChannel.h" #include "nsImportModule.h" #include "nsMimeTypes.h" -#include "mozilla/dom/CanonicalBrowsingContext.h" #include "nsRedirectHistoryEntry.h" #include "nsURILoader.h" #include "nsWebNavigationInfo.h" -#include "nsDocShellLoadTypes.h" -#include "nsSandboxFlags.h" #ifdef ANDROID # include "mozilla/widget/nsWindow.h" @@ -241,21 +238,12 @@ NS_INTERFACE_MAP_BEGIN(DocumentLoadListener) NS_INTERFACE_MAP_END DocumentLoadListener::DocumentLoadListener( - CanonicalBrowsingContext* aBrowsingContext, - ADocumentChannelBridge* aBridge) { - MOZ_ASSERT(aBridge); + CanonicalBrowsingContext* aBrowsingContext, nsILoadContext* aLoadContext, + ADocumentChannelBridge* aBridge) + : mDocumentChannelBridge(aBridge), mLoadContext(aLoadContext) { LOG(("DocumentLoadListener ctor [this=%p]", this)); mParentChannelListener = new ParentChannelListener( - this, aBrowsingContext, aBrowsingContext->UsePrivateBrowsing()); -} - -DocumentLoadListener::DocumentLoadListener( - CanonicalBrowsingContext* aBrowsingContext, - base::ProcessId aPendingBridgeProcess) { - LOG(("DocumentLoadListener ctor [this=%p]", this)); - mParentChannelListener = new ParentChannelListener( - this, aBrowsingContext, aBrowsingContext->UsePrivateBrowsing()); - mPendingDocumentChannelBridgeProcess = Some(aPendingBridgeProcess); + this, aBrowsingContext, aLoadContext->UsePrivateBrowsing()); } DocumentLoadListener::~DocumentLoadListener() { @@ -310,7 +298,7 @@ already_AddRefed DocumentLoadListener::CreateLoadInfo( } else { // Build LoadInfo for TYPE_DOCUMENT OriginAttributes attrs; - aBrowsingContext->GetOriginAttributes(attrs); + mLoadContext->GetOriginAttributes(attrs); loadInfo = new LoadInfo(aBrowsingContext, aLoadState->TriggeringPrincipal(), attrs, aOuterWindowId, securityFlags, sandboxFlags); } @@ -352,16 +340,9 @@ GetTopWindowExcludingExtensionAccessibleContentFrames( return prev.forget(); } -CanonicalBrowsingContext* DocumentLoadListener::GetBrowsingContext() { - if (!mParentChannelListener) { - return nullptr; - } - return mParentChannelListener->GetBrowsingContext(); -} - bool DocumentLoadListener::Open( nsDocShellLoadState* aLoadState, nsLoadFlags aLoadFlags, uint32_t aCacheKey, - const Maybe& aChannelId, const TimeStamp& aAsyncOpenTime, + const uint64_t& aChannelId, const TimeStamp& aAsyncOpenTime, nsDOMNavigationTiming* aTiming, Maybe&& aInfo, uint64_t aOuterWindowId, bool aHasGesture, nsresult* aRv) { LOG(("DocumentLoadListener Open [this=%p, uri=%s]", this, @@ -370,7 +351,7 @@ bool DocumentLoadListener::Open( mParentChannelListener->GetBrowsingContext(); OriginAttributes attrs; - browsingContext->GetOriginAttributes(attrs); + mLoadContext->GetOriginAttributes(attrs); RefPtr embedderWGP = browsingContext->GetParentWindowGlobal(); @@ -432,8 +413,8 @@ bool DocumentLoadListener::Open( AntiTrackingUtils::HasStoragePermissionInParent(mChannel)); nsCOMPtr identChannel = do_QueryInterface(mChannel); - if (identChannel && aChannelId) { - Unused << identChannel->SetChannelId(*aChannelId); + if (identChannel) { + Unused << identChannel->SetChannelId(aChannelId); } RefPtr httpChannelImpl = do_QueryObject(mChannel); @@ -525,167 +506,9 @@ bool DocumentLoadListener::Open( mTiming = aTiming; mSrcdocData = aLoadState->SrcdocData(); mBaseURI = aLoadState->BaseURI(); - - if (auto* ctx = GetBrowsingContext()) { - ctx->StartDocumentLoad(this); - } return true; } -bool DocumentLoadListener::OpenFromParent( - dom::CanonicalBrowsingContext* aBrowsingContext, - nsDocShellLoadState* aLoadState, uint64_t aOuterWindowId, - uint32_t* aOutIdent) { - LOG(("DocumentLoadListener::OpenFromParent")); - - // We currently only support passing nullptr for aLoadInfo for - // top level browsing contexts. - if (!aBrowsingContext->IsTopContent() || - !aBrowsingContext->GetContentParent()) { - LOG(("DocumentLoadListener::OpenFromParent failed because of subdoc")); - return false; - } - - if (nsCOMPtr csp = aLoadState->Csp()) { - // Check CSP navigate-to - bool allowsNavigateTo = false; - nsresult rv = csp->GetAllowsNavigateTo(aLoadState->URI(), - aLoadState->IsFormSubmission(), - false, /* aWasRedirected */ - false, /* aEnforceWhitelist */ - &allowsNavigateTo); - if (NS_FAILED(rv) || !allowsNavigateTo) { - return false; - } - } - - // Any sort of reload/history load would need the cacheKey, and session - // history data for load flags. We don't have those available in the parent - // yet, so don't support these load types. - auto loadType = aLoadState->LoadType(); - if (loadType == LOAD_HISTORY || loadType == LOAD_RELOAD_NORMAL || - loadType == LOAD_RELOAD_CHARSET_CHANGE || - loadType == LOAD_RELOAD_CHARSET_CHANGE_BYPASS_CACHE || - loadType == LOAD_RELOAD_CHARSET_CHANGE_BYPASS_PROXY_AND_CACHE) { - LOG( - ("DocumentLoadListener::OpenFromParent failed because of history " - "load")); - return false; - } - - // Clone because this mutates the load flags in the load state, which - // breaks nsDocShells expectations of being able to do it. - RefPtr loadState = new nsDocShellLoadState(*aLoadState); - loadState->CalculateLoadURIFlags(); - - nsLoadFlags loadFlags = loadState->LoadFlags() | - nsIChannel::LOAD_DOCUMENT_URI | - nsIChannel::LOAD_CALL_CONTENT_SNIFFERS; - uint32_t sandboxFlags = aBrowsingContext->GetSandboxFlags(); - if ((sandboxFlags & (SANDBOXED_ORIGIN | SANDBOXED_SCRIPTS)) == 0) { - loadFlags |= nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE; - } - if (loadState->FirstParty()) { - // tag first party URL loads - loadFlags |= nsIChannel::LOAD_INITIAL_DOCUMENT_URI; - } - - RefPtr timing = new nsDOMNavigationTiming(nullptr); - timing->NotifyNavigationStart( - aBrowsingContext->GetIsActive() - ? nsDOMNavigationTiming::DocShellState::eActive - : nsDOMNavigationTiming::DocShellState::eInactive); - - // We're not a history load or a reload, so we don't need this. - uint32_t cacheKey = 0; - - // Loads start in the content process might have exposed a channel id to - // observers, so we need to preserve the value in the parent. That can't have - // happened here, so Nothing() is fine. - Maybe channelId = Nothing(); - - // Initial client info is only relevant for subdocument loads, which we're - // not supporting yet. - Maybe initialClientInfo; - - RefPtr listener = new DocumentLoadListener( - aBrowsingContext, aBrowsingContext->GetContentParent()->OtherPid()); - - nsresult rv; - bool result = listener->Open( - loadState, loadFlags, cacheKey, channelId, TimeStamp::Now(), timing, - std::move(initialClientInfo), aOuterWindowId, false, &rv); - if (result) { - // Create an entry in the redirect channel registrar to - // allocate an identifier for this load. - nsCOMPtr registrar = - RedirectChannelRegistrar::GetOrCreate(); - rv = registrar->RegisterChannel(nullptr, aOutIdent); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - // Register listener (as an nsIParentChannel) under our new identifier. - rv = registrar->LinkChannels(*aOutIdent, listener, nullptr); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - } - return result; -} - -void DocumentLoadListener::CleanupParentLoadAttempt(uint32_t aLoadIdent) { - nsCOMPtr registrar = - RedirectChannelRegistrar::GetOrCreate(); - - nsCOMPtr parentChannel; - registrar->GetParentChannel(aLoadIdent, getter_AddRefs(parentChannel)); - RefPtr loadListener = do_QueryObject(parentChannel); - - if (loadListener) { - // If the load listener is still registered, then we must have failed - // to connect DocumentChannel into it. Better cancel it! - loadListener->NotifyBridgeFailed(); - } - - registrar->DeregisterChannels(aLoadIdent); -} - -already_AddRefed DocumentLoadListener::ClaimParentLoad( - uint32_t aLoadIdent, ADocumentChannelBridge* aBridge) { - nsCOMPtr registrar = - RedirectChannelRegistrar::GetOrCreate(); - - nsCOMPtr parentChannel; - registrar->GetParentChannel(aLoadIdent, getter_AddRefs(parentChannel)); - RefPtr loadListener = do_QueryObject(parentChannel); - registrar->DeregisterChannels(aLoadIdent); - - MOZ_ASSERT(loadListener); - if (loadListener) { - loadListener->NotifyBridgeConnected(aBridge); - } - return loadListener.forget(); -} - -void DocumentLoadListener::NotifyBridgeConnected( - ADocumentChannelBridge* aBridge) { - LOG(("DocumentLoadListener NotifyBridgeConnected [this=%p]", this)); - MOZ_ASSERT(!mDocumentChannelBridge); - MOZ_ASSERT(mPendingDocumentChannelBridgeProcess); - MOZ_ASSERT(aBridge->OtherPid() == *mPendingDocumentChannelBridgeProcess); - - mDocumentChannelBridge = aBridge; - mPendingDocumentChannelBridgeProcess.reset(); - mBridgePromise.ResolveIfExists(aBridge, __func__); -} - -void DocumentLoadListener::NotifyBridgeFailed() { - LOG(("DocumentLoadListener NotifyBridgeFailed [this=%p]", this)); - MOZ_ASSERT(!mDocumentChannelBridge); - MOZ_ASSERT(mPendingDocumentChannelBridgeProcess); - mPendingDocumentChannelBridgeProcess.reset(); - - Cancel(NS_BINDING_ABORTED); - - mBridgePromise.RejectIfExists(false, __func__); -} - void DocumentLoadListener::DocumentChannelBridgeDisconnected() { LOG(("DocumentLoadListener DocumentChannelBridgeDisconnected [this=%p]", this)); @@ -696,10 +519,6 @@ void DocumentLoadListener::DocumentChannelBridgeDisconnected() { httpChannelImpl->SetWarningReporter(nullptr); } mDocumentChannelBridge = nullptr; - - if (auto* ctx = GetBrowsingContext()) { - ctx->EndDocumentLoad(this); - } } void DocumentLoadListener::Cancel(const nsresult& aStatusCode) { @@ -707,18 +526,9 @@ void DocumentLoadListener::Cancel(const nsresult& aStatusCode) { ("DocumentLoadListener Cancel [this=%p, " "aStatusCode=%" PRIx32 " ]", this, static_cast(aStatusCode))); - if (mDoingProcessSwitch) { - // If we've already initiated process-switching - // then we can no longer be cancelled and we'll - // disconnect the old listeners when done. - return; - } - - if (mChannel) { + if (mChannel && !mDoingProcessSwitch) { mChannel->Cancel(aStatusCode); } - - DisconnectChildListeners(aStatusCode, aStatusCode); } void DocumentLoadListener::DisconnectChildListeners(nsresult aStatus, @@ -728,20 +538,8 @@ void DocumentLoadListener::DisconnectChildListeners(nsresult aStatus, "aStatus=%" PRIx32 " aLoadGroupStatus=%" PRIx32 " ]", this, static_cast(aStatus), static_cast(aLoadGroupStatus))); - RefPtr keepAlive(this); if (mDocumentChannelBridge) { - // This will drop the bridge's reference to us, so we use keepAlive to - // make sure we don't get deleted until we exit the function. mDocumentChannelBridge->DisconnectChildListeners(aStatus, aLoadGroupStatus); - } else if (mPendingDocumentChannelBridgeProcess) { - EnsureBridge()->Then( - GetCurrentThreadSerialEventTarget(), __func__, - [keepAlive, aStatus, - aLoadGroupStatus](ADocumentChannelBridge* aBridge) { - aBridge->DisconnectChildListeners(aStatus, aLoadGroupStatus); - keepAlive->mDocumentChannelBridge = nullptr; - }, - [](bool aDummy) {}); } DocumentChannelBridgeDisconnected(); @@ -853,9 +651,6 @@ void DocumentLoadListener::FinishReplacementChannelSetup(bool aSucceeded) { redirectChannel->Delete(); } mChannel->Resume(); - if (auto* ctx = GetBrowsingContext()) { - ctx->EndDocumentLoad(this); - } return; } @@ -1036,11 +831,6 @@ bool DocumentLoadListener::ResumeSuspendedChannel( "Should not have added new stream listener function!"); mChannel->Resume(); - - if (auto* ctx = GetBrowsingContext()) { - ctx->EndDocumentLoad(this); - } - return !mIsFinished; } @@ -1065,17 +855,8 @@ void DocumentLoadListener::SerializeRedirectData( channelLoadInfo->GetPrincipalToInherit(getter_AddRefs(principalToInherit)); const RefPtr baseChannel = do_QueryObject(mChannel.get()); - - nsCOMPtr loadContext; - NS_QueryNotificationCallbacks(mChannel, loadContext); nsCOMPtr redirectLoadInfo; - - // Only use CloneLoadInfoForRedirect if we have a load context, - // since it internally tries to pull OriginAttributes from the - // the load context and asserts if they don't match the load info. - // We can end up without a load context if the channel has been aborted - // and the callbacks have been cleared. - if (baseChannel && loadContext) { + if (baseChannel) { redirectLoadInfo = baseChannel->CloneLoadInfoForRedirect( aArgs.uri(), nsIChannelEventSink::REDIRECT_INTERNAL); redirectLoadInfo->SetResultPrincipalURI(aArgs.uri()); @@ -1351,17 +1132,6 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch() { return true; } -auto DocumentLoadListener::EnsureBridge() -> RefPtr { - MOZ_ASSERT(mDocumentChannelBridge || mPendingDocumentChannelBridgeProcess); - if (mDocumentChannelBridge) { - MOZ_ASSERT(mBridgePromise.IsEmpty()); - return EnsureBridgePromise::CreateAndResolve(mDocumentChannelBridge, - __func__); - } - - return mBridgePromise.Ensure(__func__); -} - RefPtr DocumentLoadListener::RedirectToRealChannel( uint32_t aRedirectFlags, uint32_t aLoadFlags, @@ -1413,19 +1183,9 @@ DocumentLoadListener::RedirectToRealChannel( return cp->SendCrossProcessRedirect(args, std::move(aStreamFilterEndpoints)); } - - return EnsureBridge()->Then( - GetCurrentThreadSerialEventTarget(), __func__, - [endpoints = std::move(aStreamFilterEndpoints), aRedirectFlags, - aLoadFlags](ADocumentChannelBridge* aBridge) mutable { - return aBridge->RedirectToRealChannel(std::move(endpoints), - aRedirectFlags, aLoadFlags); - }, - [](bool aDummy) { - return PDocumentChannelParent::RedirectToRealChannelPromise:: - CreateAndReject(ipc::ResponseRejectReason::ActorDestroyed, - __func__); - }); + MOZ_ASSERT(mDocumentChannelBridge); + return mDocumentChannelBridge->RedirectToRealChannel( + std::move(aStreamFilterEndpoints), aRedirectFlags, aLoadFlags); } void DocumentLoadListener::TriggerRedirectToRealChannel( @@ -1530,7 +1290,10 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) { MOZ_DIAGNOSTIC_ASSERT(mChannel); RefPtr httpChannel = do_QueryObject(mChannel); - if (!mDocumentChannelBridge && !mPendingDocumentChannelBridgeProcess) { + // If this is a download, then redirect entirely within the parent. + // TODO, see bug 1574372. + + if (!mDocumentChannelBridge) { return NS_ERROR_UNEXPECTED; } @@ -1538,6 +1301,15 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) { // might cancel the channel. nsContentSecurityUtils::PerformCSPFrameAncestorAndXFOCheck(mChannel); + // Once we initiate a process switch, we ask the child to notify the + // listeners that we have completed. If the switch promise then gets + // rejected we also cancel the parent, which results in this being called. + // We don't need to forward it on though, since the child side is already + // completed. + if (mDoingProcessSwitch) { + return NS_OK; + } + // Generally we want to switch to a real channel even if the request failed, // since the listener might want to access protocol-specific data (like http // response headers) in its error handling. @@ -1547,7 +1319,7 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) { nsresult status = NS_OK; aRequest->GetStatus(&status); if (status == NS_ERROR_NO_CONTENT) { - DisconnectChildListeners(status, status); + mDocumentChannelBridge->DisconnectChildListeners(status, status); return NS_OK; } @@ -1660,10 +1432,10 @@ DocumentLoadListener::SetParentListener( NS_IMETHODIMP DocumentLoadListener::GetInterface(const nsIID& aIID, void** result) { - RefPtr browsingContext = - mParentChannelListener->GetBrowsingContext(); - if (aIID.Equals(NS_GET_IID(nsILoadContext)) && browsingContext) { - browsingContext.forget(result); + // Only support nsILoadContext if child channel's callbacks did too + if (aIID.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) { + nsCOMPtr copy = mLoadContext; + copy.forget(result); return NS_OK; } @@ -1768,20 +1540,8 @@ DocumentLoadListener::AsyncOnChannelRedirect( "mRedirects=%" PRIx32, this, uint32_t(mRedirects.Length()))); - // If this is a cross-origin redirect, then we should no longer allow - // mixed content. The destination docshell checks this in its redirect - // handling, but if we deliver to a new docshell (with a process switch) - // then this doesn't happen. - // Manually remove the allow mixed content flags. - nsresult rv = nsContentUtils::CheckSameOrigin(aOldChannel, aNewChannel); - if (NS_FAILED(rv)) { - if (mLoadStateLoadType == LOAD_NORMAL_ALLOW_MIXED_CONTENT) { - mLoadStateLoadType = LOAD_NORMAL; - } else if (mLoadStateLoadType == LOAD_RELOAD_ALLOW_MIXED_CONTENT) { - mLoadStateLoadType = LOAD_RELOAD_NORMAL; - } - MOZ_ASSERT(!LOAD_TYPE_HAS_FLAGS( - mLoadStateLoadType, nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT)); + if (!mDocumentChannelBridge) { + return NS_BINDING_ABORTED; } // We need the original URI of the current channel to use to open the real @@ -1799,7 +1559,7 @@ DocumentLoadListener::AsyncOnChannelRedirect( nsCOMPtr loadInfo = aOldChannel->LoadInfo(); nsCOMPtr originalUri; - rv = aOldChannel->GetOriginalURI(getter_AddRefs(originalUri)); + nsresult rv = aOldChannel->GetOriginalURI(getter_AddRefs(originalUri)); if (NS_FAILED(rv)) { aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI); return rv; diff --git a/netwerk/ipc/DocumentLoadListener.h b/netwerk/ipc/DocumentLoadListener.h index 3b7603a4295f..b36c2d7008f7 100644 --- a/netwerk/ipc/DocumentLoadListener.h +++ b/netwerk/ipc/DocumentLoadListener.h @@ -14,6 +14,7 @@ #include "mozilla/net/PDocumentChannelParent.h" #include "mozilla/net/ParentChannelListener.h" #include "mozilla/net/ADocumentChannelBridge.h" +#include "mozilla/dom/CanonicalBrowsingContext.h" #include "nsDOMNavigationTiming.h" #include "nsIInterfaceRequestor.h" #include "nsIParentChannel.h" @@ -29,9 +30,6 @@ } namespace mozilla { -namespace dom { -class CanonicalBrowsingContext; -} namespace net { using ChildEndpointPromise = MozPromise, bool, true>; @@ -91,34 +89,16 @@ class DocumentLoadListener : public nsIInterfaceRequestor, public nsIMultiPartChannelListener { public: explicit DocumentLoadListener(dom::CanonicalBrowsingContext* aBrowsingContext, + nsILoadContext* aLoadContext, ADocumentChannelBridge* aBridge); // Creates the channel, and then calls AsyncOpen on it. bool Open(nsDocShellLoadState* aLoadState, nsLoadFlags aLoadFlags, - uint32_t aCacheKey, const Maybe& aChannelId, + uint32_t aCacheKey, const uint64_t& aChannelId, const TimeStamp& aAsyncOpenTime, nsDOMNavigationTiming* aTiming, Maybe&& aInfo, uint64_t aOuterWindowId, bool aHasGesture, nsresult* aRv); - // Creates a DocumentLoadListener directly in the parent process without - // an associated DocumentChannelBridge. - // If successful it registers a unique identifier (return in aOutIdent) to - // keep it alive until a future bridge can attach to it, or we fail and clean - // up. - static bool OpenFromParent(dom::CanonicalBrowsingContext* aBrowsingContext, - nsDocShellLoadState* aLoadState, - uint64_t aOuterWindowId, uint32_t* aOutIdent); - - // Ensures that a load identifier allocated by OpenFromParent has - // been deregistered if it hasn't already been claimed. - // This also cancels the load. - static void CleanupParentLoadAttempt(uint32_t aLoadIdent); - - // Looks up aLoadIdent to find the associated, cleans up the registration - // and attaches aBridge as the listener. - static already_AddRefed ClaimParentLoad( - uint32_t aLoadIdent, ADocumentChannelBridge* aBridge); - NS_DECL_ISUPPORTS NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER @@ -185,9 +165,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor, if (mDocumentChannelBridge) { return mDocumentChannelBridge->OtherPid(); } - if (mPendingDocumentChannelBridgeProcess) { - return *mPendingDocumentChannelBridgeProcess; - } return 0; } @@ -209,26 +186,8 @@ class DocumentLoadListener : public nsIInterfaceRequestor, net::LastVisitInfo LastVisitInfo() const; protected: - DocumentLoadListener(dom::CanonicalBrowsingContext* aBrowsingContext, - base::ProcessId aPendingBridgeProcess); virtual ~DocumentLoadListener(); - // Called when we were created without a document channel bridge, - // and now it has been created and attached. - void NotifyBridgeConnected(ADocumentChannelBridge* aBridge); - - // Called when we were created without a document channel bridge, - // and creation has failed, and won't ever be attached. - void NotifyBridgeFailed(); - - // Returns a promise that resolves with the document channel bridge, - // waiting for a pending one if necessary. - // If we've failed to create a bridge, or a bridge has already been - // detached then rejects. - typedef MozPromise, bool, false> - EnsureBridgePromise; - RefPtr EnsureBridge(); - // Initiates the switch from DocumentChannel to the real protocol-specific // channel, and ensures that RedirectToRealChannelFinished is called when // this is complete. @@ -264,8 +223,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor, dom::CanonicalBrowsingContext* aBrowsingContext, nsDocShellLoadState* aLoadState, uint64_t aOuterWindowId); - dom::CanonicalBrowsingContext* GetBrowsingContext(); - bool HasCrossOriginOpenerPolicyMismatch() const; void ApplyPendingFunctions(nsISupports* aChannel) const; @@ -373,14 +330,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor, // shuts down to break this. RefPtr mDocumentChannelBridge; - // If we were created without a bridge, then this is set - // to Some() with the process id of the content process - // that will be creating our bridge soon. - Maybe mPendingDocumentChannelBridgeProcess; - - // Holds a promise for callers that want to wait on the document - // channel bridge becoming available. - MozPromiseHolder mBridgePromise; + nsCOMPtr mLoadContext; // The original URI of the current channel. If there are redirects, // then the value on the channel gets overwritten with the original diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp index 5faafc54c528..8b7aa00281c1 100644 --- a/netwerk/ipc/NeckoParent.cpp +++ b/netwerk/ipc/NeckoParent.cpp @@ -254,7 +254,7 @@ const char* NeckoParent::CreateChannelLoadContext( break; } case PBrowserOrId::TTabId: { - aResult = new LoadContext(aSerialized, nullptr, attrs); + aResult = new LoadContext(aSerialized, aBrowser.get_TabId(), attrs); break; } default: @@ -409,15 +409,43 @@ mozilla::ipc::IPCResult NeckoParent::RecvPFTPChannelConstructor( already_AddRefed NeckoParent::AllocPDocumentChannelParent( - const MaybeDiscarded& aContext, + PBrowserParent* aBrowser, const MaybeDiscarded& aContext, + const SerializedLoadContext& aSerialized, const DocumentChannelCreationArgs& args) { - RefPtr p = new DocumentChannelParent(); + // We still create the actor even if the BrowsingContext isn't available, + // so that we can send the reject message using it from + // RecvPDocumentChannelConstructor + CanonicalBrowsingContext* context = nullptr; + if (!aContext.IsNullOrDiscarded()) { + context = aContext.get_canonical(); + } + + nsCOMPtr requestingPrincipal; + // We only have the requesting principal in case of TYPE_SUBDOCUMENT. + // If we don't have an embedder window global, then it is probably a race and + // we will deal with that later in the code path. + if (context && !aContext.IsDiscarded() && context->GetParent()) { + if (RefPtr embedderWGP = + context->GetParentWindowGlobal()) { + requestingPrincipal = embedderWGP->DocumentPrincipal(); + } + } + + nsCOMPtr loadContext; + const char* error = CreateChannelLoadContext( + aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext); + if (error) { + return nullptr; + } + RefPtr p = + new DocumentChannelParent(context, loadContext); return p.forget(); } mozilla::ipc::IPCResult NeckoParent::RecvPDocumentChannelConstructor( - PDocumentChannelParent* aActor, + PDocumentChannelParent* aActor, PBrowserParent* aBrowser, const MaybeDiscarded& aContext, + const SerializedLoadContext& aSerialized, const DocumentChannelCreationArgs& aArgs) { DocumentChannelParent* p = static_cast(aActor); @@ -426,7 +454,7 @@ mozilla::ipc::IPCResult NeckoParent::RecvPDocumentChannelConstructor( return IPC_OK(); } - if (!p->Init(aContext.get_canonical(), aArgs)) { + if (!p->Init(aArgs)) { return IPC_FAIL_NO_REASON(this); } return IPC_OK(); diff --git a/netwerk/ipc/NeckoParent.h b/netwerk/ipc/NeckoParent.h index 7a7f2b078cca..4137cfd22569 100644 --- a/netwerk/ipc/NeckoParent.h +++ b/netwerk/ipc/NeckoParent.h @@ -126,11 +126,14 @@ class NeckoParent : public PNeckoParent { const uint16_t& port); already_AddRefed AllocPDocumentChannelParent( + PBrowserParent* aBrowser, const dom::MaybeDiscarded& aContext, + const SerializedLoadContext& aSerialized, const DocumentChannelCreationArgs& args); virtual mozilla::ipc::IPCResult RecvPDocumentChannelConstructor( - PDocumentChannelParent* aActor, + PDocumentChannelParent* aActor, PBrowserParent* aBrowser, const dom::MaybeDiscarded& aContext, + const SerializedLoadContext& aSerialized, const DocumentChannelCreationArgs& aArgs) override; bool DeallocPDocumentChannelParent(PDocumentChannelParent* channel); diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index 90d84fc8f549..ed0c176f1b89 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -88,7 +88,9 @@ parent: async PDNSRequest(nsCString hostName, nsCString trrServer, uint16_t type, OriginAttributes originAttributes, uint32_t flags); - async PDocumentChannel(MaybeDiscardedBrowsingContext browsingContext, + async PDocumentChannel(PBrowser browser, + MaybeDiscardedBrowsingContext browsingContext, + SerializedLoadContext loadContext, DocumentChannelCreationArgs args); async PWebSocketEventListener(uint64_t aInnerWindowID); diff --git a/netwerk/ipc/ParentProcessDocumentChannel.cpp b/netwerk/ipc/ParentProcessDocumentChannel.cpp index 5a8f605889b0..8096de837ece 100644 --- a/netwerk/ipc/ParentProcessDocumentChannel.cpp +++ b/netwerk/ipc/ParentProcessDocumentChannel.cpp @@ -107,9 +107,11 @@ ParentProcessDocumentChannel::OnRedirectVerifyCallback(nsresult aResult) { NS_IMETHODIMP ParentProcessDocumentChannel::AsyncOpen( nsIStreamListener* aListener) { LOG(("ParentProcessDocumentChannel AsyncOpen [this=%p]", this)); + nsCOMPtr loadContext; + NS_QueryNotificationCallbacks(this, loadContext); mDocumentLoadListener = new DocumentLoadListener( - GetDocShell()->GetBrowsingContext()->Canonical(), this); + GetDocShell()->GetBrowsingContext()->Canonical(), loadContext, this); LOG(("Created PPDocumentChannel with listener=%p", mDocumentLoadListener.get())); @@ -126,7 +128,7 @@ NS_IMETHODIMP ParentProcessDocumentChannel::AsyncOpen( nsresult rv = NS_OK; Maybe initialClientInfo = mInitialClientInfo; if (!mDocumentLoadListener->Open( - mLoadState, mLoadFlags, mCacheKey, Some(mChannelId), mAsyncOpenTime, + mLoadState, mLoadFlags, mCacheKey, mChannelId, mAsyncOpenTime, mTiming, std::move(initialClientInfo), GetDocShell()->GetOuterWindowID(), GetDocShell() diff --git a/netwerk/ipc/SocketProcessHost.cpp b/netwerk/ipc/SocketProcessHost.cpp index f8a2d831a0a0..8a7929b3d2d1 100644 --- a/netwerk/ipc/SocketProcessHost.cpp +++ b/netwerk/ipc/SocketProcessHost.cpp @@ -9,8 +9,6 @@ #include "nsIObserverService.h" #include "nsIOService.h" #include "SocketProcessParent.h" -#include "ProcessUtils.h" -#include "mozilla/ipc/FileDescriptor.h" #if defined(XP_LINUX) && defined(MOZ_SANDBOX) # include "mozilla/SandboxBroker.h" @@ -26,8 +24,6 @@ # include "mozilla/Sandbox.h" #endif -using namespace mozilla::ipc; - namespace mozilla { namespace net { diff --git a/netwerk/ipc/SocketProcessImpl.cpp b/netwerk/ipc/SocketProcessImpl.cpp index a67dd9c9bd39..9ad94aada622 100644 --- a/netwerk/ipc/SocketProcessImpl.cpp +++ b/netwerk/ipc/SocketProcessImpl.cpp @@ -11,7 +11,6 @@ #include "base/string_util.h" #include "mozilla/BackgroundHangMonitor.h" #include "mozilla/Preferences.h" -#include "ProcessUtils.h" #include "mozilla/ipc/IOThreadChild.h" #if defined(OS_WIN) && defined(MOZ_SANDBOX) diff --git a/netwerk/protocol/http/ParentChannelListener.cpp b/netwerk/protocol/http/ParentChannelListener.cpp index 636e5e894eb4..c4b78c4c5bde 100644 --- a/netwerk/protocol/http/ParentChannelListener.cpp +++ b/netwerk/protocol/http/ParentChannelListener.cpp @@ -430,21 +430,15 @@ ParentChannelListener::OpenURI(nsIURI* aURI) { nsCString spec; aURI->GetSpec(spec); - RefPtr bc = mBrowsingContext; + dom::LoadURIOptions loadURIOptions; + loadURIOptions.mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal(); + loadURIOptions.mLoadFlags = + nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | + nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL; - NS_DispatchToMainThread( - NS_NewRunnableFunction("ParentChannelListener::OpenURI", [spec, bc]() { - dom::LoadURIOptions loadURIOptions; - loadURIOptions.mTriggeringPrincipal = - nsContentUtils::GetSystemPrincipal(); - loadURIOptions.mLoadFlags = - nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | - nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL; - - ErrorResult rv; - bc->LoadURI(NS_ConvertUTF8toUTF16(spec), loadURIOptions, rv); - })); - return NS_OK; + ErrorResult rv; + mBrowsingContext->LoadURI(NS_ConvertUTF8toUTF16(spec), loadURIOptions, rv); + return rv.StealNSResult(); } NS_IMETHODIMP diff --git a/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_delayedbutton.js b/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_delayedbutton.js index d332f73a3624..7e051b3bc3a8 100644 --- a/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_delayedbutton.js +++ b/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_delayedbutton.js @@ -55,8 +55,6 @@ add_task(async function test_unknownContentType_delayedbutton() { { gBrowser, url: LOAD_URI, - waitForLoad: false, - waitForStateStop: true, }, async function() { let uctWindow = await UCTObserver.opened.promise; diff --git a/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_dialog_layout.js b/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_dialog_layout.js index bb41d61c7f69..f2597ac774df 100644 --- a/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_dialog_layout.js +++ b/toolkit/mozapps/downloads/tests/browser/browser_unknownContentType_dialog_layout.js @@ -68,8 +68,6 @@ add_task(async function test_unknownContentType_dialog_layout() { { gBrowser, url: test.url, - waitForLoad: false, - waitForStateStop: true, }, async function() { let uctWindow = await UCTObserver.opened.promise; diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_datauri.js b/toolkit/mozapps/extensions/test/xpinstall/browser_datauri.js index 294fdba58ff5..49fc7472896e 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_datauri.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_datauri.js @@ -46,10 +46,8 @@ function runTest() { "amosigned.xpi'", }); - BrowserTestUtils.openNewForegroundTab( - gBrowser, - TESTROOT + "redirect.sjs?mode=redirect" - ); + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); + BrowserTestUtils.loadURI(gBrowser, TESTROOT + "redirect.sjs?mode=redirect"); } function install_blocked(installInfo) { diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js index 92c9e348d4e2..08fd25645f8a 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js @@ -1,9 +1,11 @@ // ---------------------------------------------------------------------------- // Test whether an InstallTrigger.enabled is working -add_task(async function test() { - await BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT); +function test() { + waitForExplicitFinish(); - let text = await ContentTask.spawn( + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT); + + ContentTask.spawn( gBrowser.selectedBrowser, TESTROOT + "enabled.html", function(url) { @@ -23,8 +25,9 @@ add_task(async function test() { content.location.href = url; }); } - ); - - is(text, "true", "installTrigger should have been enabled"); - gBrowser.removeCurrentTab(); -}); + ).then(text => { + is(text, "true", "installTrigger should have been enabled"); + gBrowser.removeCurrentTab(); + finish(); + }); +} diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled2.js b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled2.js index ed1b7ff18f04..ce37f68e8bd1 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled2.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled2.js @@ -1,13 +1,11 @@ // ---------------------------------------------------------------------------- // Test whether an InstallTrigger.enabled is working -async function test() { +function test() { waitForExplicitFinish(); Services.prefs.setBoolPref("xpinstall.enabled", false); - let tab = BrowserTestUtils.addTab(gBrowser, TESTROOT); - gBrowser.selectedTab = tab; - await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, TESTROOT); + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT); ContentTask.spawn( gBrowser.selectedBrowser, diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled3.js b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled3.js index e86a4ef031a6..f207739c49b9 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled3.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled3.js @@ -1,6 +1,6 @@ // ---------------------------------------------------------------------------- // Test whether an InstallTrigger.install call fails when xpinstall is disabled -async function test() { +function test() { Harness.installDisabledCallback = install_disabled; Harness.installBlockedCallback = allow_blocked; Harness.installConfirmCallback = confirm_install; @@ -13,9 +13,7 @@ async function test() { "Unsigned XPI": TESTROOT + "amosigned.xpi", }) ); - let tab = BrowserTestUtils.addTab(gBrowser, TESTROOT); - gBrowser.selectedTab = tab; - await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, TESTROOT); + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT); ContentTask.spawn( gBrowser.selectedBrowser, diff --git a/uriloader/prefetch/OfflineCacheUpdateParent.cpp b/uriloader/prefetch/OfflineCacheUpdateParent.cpp index 08111aba6e72..fa8e62a1316d 100644 --- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp +++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp @@ -208,6 +208,11 @@ OfflineCacheUpdateParent::GetTopFrameElement(dom::Element** aElement) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +OfflineCacheUpdateParent::GetNestedFrameId(uint64_t* aId) { + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP OfflineCacheUpdateParent::GetIsContent(bool* aIsContent) { return NS_ERROR_NOT_IMPLEMENTED;