Backed out 8 changesets (bug 1696158) for causing multiple failures. CLOSED TREE

Backed out changeset 09c598c8fd29 (bug 1696158)
Backed out changeset 02f956c26901 (bug 1696158)
Backed out changeset b61a3a324cce (bug 1696158)
Backed out changeset 95810ed7f1e5 (bug 1696158)
Backed out changeset 4f93a7b61496 (bug 1696158)
Backed out changeset c80c55b56f2a (bug 1696158)
Backed out changeset 11627c409882 (bug 1696158)
Backed out changeset b98b4316a510 (bug 1696158)
This commit is contained in:
smolnar 2021-04-19 17:04:08 +03:00
Родитель cd13a3bb4f
Коммит 84a0543987
29 изменённых файлов: 249 добавлений и 934 удалений

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

@ -25,7 +25,6 @@
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/net/DocumentLoadListener.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/StaticPrefs_docshell.h"
#include "mozilla/StaticPrefs_fission.h"
#include "nsIWebNavigation.h"
#include "mozilla/MozPromiseInlines.h"
@ -52,7 +51,6 @@ using namespace mozilla::ipc;
extern mozilla::LazyLogModule gAutoplayPermissionLog;
extern mozilla::LazyLogModule gSHLog;
extern mozilla::LazyLogModule gSHIPBFCacheLog;
#define AUTOPLAY_LOG(msg, ...) \
MOZ_LOG(gAutoplayPermissionLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
@ -2052,117 +2050,6 @@ void CanonicalBrowsingContext::ShowSubframeCrashedUI(
Unused << aBridge->SendSubFrameCrashed();
}
static void LogBFCacheBlockingForDoc(BrowsingContext* aBrowsingContext,
uint16_t aBFCacheCombo, bool aIsSubDoc) {
if (aIsSubDoc) {
nsAutoCString uri("[no uri]");
nsCOMPtr<nsIURI> currentURI =
aBrowsingContext->Canonical()->GetCurrentURI();
if (currentURI) {
uri = currentURI->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
(" ** Blocked for document %s", uri.get()));
}
if (aBFCacheCombo & BFCacheStatus::EVENT_HANDLING_SUPPRESSED) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
(" * event handling suppression"));
}
if (aBFCacheCombo & BFCacheStatus::SUSPENDED) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * suspended Window"));
}
if (aBFCacheCombo & BFCacheStatus::UNLOAD_LISTENER) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
(" * beforeunload or unload listener"));
}
if (aBFCacheCombo & BFCacheStatus::REQUEST) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * requests in the loadgroup"));
}
if (aBFCacheCombo & BFCacheStatus::ACTIVE_GET_USER_MEDIA) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * GetUserMedia"));
}
if (aBFCacheCombo & BFCacheStatus::ACTIVE_PEER_CONNECTION) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * PeerConnection"));
}
if (aBFCacheCombo & BFCacheStatus::CONTAINS_EME_CONTENT) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * EME content"));
}
if (aBFCacheCombo & BFCacheStatus::CONTAINS_MSE_CONTENT) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * MSE use"));
}
if (aBFCacheCombo & BFCacheStatus::HAS_ACTIVE_SPEECH_SYNTHESIS) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * Speech use"));
}
if (aBFCacheCombo & BFCacheStatus::HAS_USED_VR) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * used VR"));
}
}
bool CanonicalBrowsingContext::AllowedInBFCache(
const Maybe<uint64_t>& aChannelId) {
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug))) {
nsAutoCString uri("[no uri]");
nsCOMPtr<nsIURI> currentURI = GetCurrentURI();
if (currentURI) {
uri = currentURI->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, ("Checking %s", uri.get()));
}
if (IsInProcess()) {
return false;
}
uint16_t bfcacheCombo = 0;
if (Group()->Toplevels().Length() > 1) {
bfcacheCombo |= BFCacheStatus::NOT_ONLY_TOPLEVEL_IN_BCG;
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
(" * auxiliary BrowsingContexts"));
}
// For telemetry we're collecting all the flags for all the BCs hanging
// from this top-level BC.
PreOrderWalk([&](BrowsingContext* aBrowsingContext) {
WindowGlobalParent* wgp =
aBrowsingContext->Canonical()->GetCurrentWindowGlobal();
uint16_t subDocBFCacheCombo = wgp ? wgp->GetBFCacheStatus() : 0;
if (wgp) {
const Maybe<uint64_t>& singleChannelId = wgp->GetSingleChannelId();
if (singleChannelId.isSome()) {
if (singleChannelId.value() == 0 || aChannelId.isNothing() ||
singleChannelId.value() != aChannelId.value()) {
subDocBFCacheCombo |= BFCacheStatus::REQUEST;
}
}
}
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug))) {
LogBFCacheBlockingForDoc(aBrowsingContext, subDocBFCacheCombo,
aBrowsingContext != this);
}
bfcacheCombo |= subDocBFCacheCombo;
});
nsDocShell::ReportBFCacheComboTelemetry(bfcacheCombo);
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug))) {
nsAutoCString uri("[no uri]");
nsCOMPtr<nsIURI> currentURI = GetCurrentURI();
if (currentURI) {
uri = currentURI->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
(" +> %s %s be blocked from going into the BFCache", uri.get(),
bfcacheCombo == 0 ? "shouldn't" : "should"));
}
if (StaticPrefs::docshell_shistory_bfcache_allow_unload_listeners()) {
bfcacheCombo &= ~BFCacheStatus::UNLOAD_LISTENER;
}
return bfcacheCombo == 0;
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(CanonicalBrowsingContext, BrowsingContext,
mSessionHistory, mContainerFeaturePolicy,
mCurrentBrowserParent)

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

@ -297,8 +297,6 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void StartUnloadingHost(uint64_t aChildID);
void ClearUnloadingHost(uint64_t aChildID);
bool AllowedInBFCache(const Maybe<uint64_t>& aChannelId);
protected:
// Called when the browsing context is being discarded.
void CanonicalDiscard();

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

@ -36,7 +36,6 @@
#include "mozilla/SchedulerGroup.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/ScrollTypes.h"
#include "mozilla/SimpleEnumerator.h"
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_docshell.h"
#include "mozilla/StaticPrefs_dom.h"
@ -291,7 +290,6 @@ static mozilla::LazyLogModule gDocShellAndDOMWindowLeakLogging(
static mozilla::LazyLogModule gDocShellLeakLog("nsDocShellLeak");
extern mozilla::LazyLogModule gPageCacheLog;
mozilla::LazyLogModule gSHLog("SessionHistory");
extern mozilla::LazyLogModule gSHIPBFCacheLog;
const char kBrandBundleURL[] = "chrome://branding/locale/brand.properties";
const char kAppstringsBundleURL[] =
@ -367,7 +365,7 @@ static bool IsUrgentStart(BrowsingContext* aBrowsingContext,
nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
uint64_t aContentWindowID)
: nsDocLoader(true),
: nsDocLoader(),
mContentWindowID(aContentWindowID),
mBrowsingContext(aBrowsingContext),
mForcedCharset(nullptr),
@ -6992,7 +6990,6 @@ bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
return doc && canSavePresentation;
}
/* static */
void nsDocShell::ReportBFCacheComboTelemetry(uint16_t aCombo) {
// There are 11 possible reasons to make a request fails to use BFCache
// (see BFCacheStatus in dom/base/Document.h), and we'd like to record
@ -13592,102 +13589,3 @@ void nsDocShell::MoveLoadingToActiveEntry(bool aPersist) {
hadActiveEntry, aPersist, false);
}
}
void nsDocShell::RecordSingleChannelId() {
if (mLoadGroup && mBrowsingContext->GetCurrentWindowContext()) {
Maybe<uint64_t> singleChannelId;
nsCOMPtr<nsISimpleEnumerator> requests;
mLoadGroup->GetRequests(getter_AddRefs(requests));
for (const auto& request : SimpleEnumerator<nsIRequest>(requests)) {
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
// Ignore favicon loads, they don't need to block caching.
nsCOMPtr<nsILoadInfo> li;
if (channel && (li = channel->LoadInfo()) &&
li->InternalContentPolicyType() ==
nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
continue;
}
// If we already found a channel ID or this is not an nsIIdentChannel then
// we have more than one request in the loadgroup.
nsCOMPtr<nsIIdentChannel> identChannel;
if (singleChannelId.isSome() ||
!(identChannel = do_QueryInterface(channel))) {
// We really have three states: no request, one request with an id and
// eiher one request without an id or multiple requests. Nothing() is no
// request, Some(non-zero) is one request and Some(0) is one request
// without an id or multiple requests.
singleChannelId = Some(0);
break;
}
singleChannelId = Some(identChannel->ChannelId());
}
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Verbose))) {
nsAutoCString uri("[no uri]");
if (mCurrentURI) {
uri = mCurrentURI->GetSpecOrDefault();
}
if (singleChannelId.isNothing()) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
("Loadgroup for %s doesn't have any requests relevant for "
"blocking BFCache",
uri.get()));
} else if (singleChannelId.value() == 0) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
("Loadgroup for %s has multiple requests relevant for blocking "
"BFCache",
uri.get()));
} else {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
("Loadgroup for %s has one request with id %" PRIu64
" relevant for blocking BFCache",
uri.get(), singleChannelId.value()));
}
}
if (mSingleChannelId != singleChannelId) {
mSingleChannelId = singleChannelId;
WindowGlobalChild* wgc =
mBrowsingContext->GetCurrentWindowContext()->GetWindowGlobalChild();
if (wgc) {
wgc->SendSetSingleChannelId(singleChannelId);
}
}
}
}
NS_IMETHODIMP
nsDocShell::OnStartRequest(nsIRequest* aRequest) {
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Verbose))) {
nsAutoCString uri("[no uri]");
if (mCurrentURI) {
uri = mCurrentURI->GetSpecOrDefault();
}
nsAutoCString name;
aRequest->GetName(name);
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Verbose,
("Adding request %s to loadgroup for %s", name.get(), uri.get()));
}
RecordSingleChannelId();
return nsDocLoader::OnStartRequest(aRequest);
}
NS_IMETHODIMP
nsDocShell::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Verbose))) {
nsAutoCString uri("[no uri]");
if (mCurrentURI) {
uri = mCurrentURI->GetSpecOrDefault();
}
nsAutoCString name;
aRequest->GetName(name);
MOZ_LOG(
gSHIPBFCacheLog, LogLevel::Verbose,
("Removing request %s from loadgroup for %s", name.get(), uri.get()));
}
RecordSingleChannelId();
return nsDocLoader::OnStopRequest(aRequest, aStatusCode);
}

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

@ -511,10 +511,6 @@ class nsDocShell final : public nsDocLoader,
// This returns true only when using session history in parent.
bool IsLoadingFromSessionHistory();
NS_IMETHODIMP OnStartRequest(nsIRequest* aRequest) override;
NS_IMETHODIMP OnStopRequest(nsIRequest* aRequest,
nsresult aStatusCode) override;
private: // member functions
friend class nsDSURIContentListener;
friend class FramingChecker;
@ -863,7 +859,7 @@ class nsDocShell final : public nsDocLoader,
bool CanSavePresentation(uint32_t aLoadType, nsIRequest* aNewRequest,
mozilla::dom::Document* aNewDocument);
static void ReportBFCacheComboTelemetry(uint16_t aCombo);
void ReportBFCacheComboTelemetry(uint16_t aCombo);
// Captures the state of the supporting elements of the presentation
// (the "window" object, docshell tree, meta-refresh loads, and security
@ -1083,8 +1079,6 @@ class nsDocShell final : public nsDocLoader,
bool ShouldOpenInBlankTarget(const nsAString& aOriginalTarget,
nsIURI* aLinkURI, nsIContent* aContent);
void RecordSingleChannelId();
private: // data members
nsString mTitle;
nsCString mOriginalUriString;
@ -1221,9 +1215,6 @@ class nsDocShell final : public nsDocLoader,
// Possible values are defined as constants in nsIDocShell.idl.
MetaViewportOverride mMetaViewportOverride;
// See WindowGlobalParent::mSingleChannelId.
mozilla::Maybe<uint64_t> mSingleChannelId;
// The following two fields cannot be declared as bit fields
// because of uses with AutoRestore.
bool mCreatingDocument; // (should be) debugging only

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

@ -1182,61 +1182,6 @@ nsSHistory::EvictAllContentViewers() {
return NS_OK;
}
static void FinishRestore(CanonicalBrowsingContext* aBrowsingContext,
nsDocShellLoadState* aLoadState,
SessionHistoryEntry* aEntry,
nsFrameLoader* aFrameLoader, bool aCanSave) {
MOZ_ASSERT(aEntry);
MOZ_ASSERT(aFrameLoader);
aEntry->SetFrameLoader(nullptr);
nsCOMPtr<nsFrameLoaderOwner> frameLoaderOwner =
do_QueryInterface(aBrowsingContext->GetEmbedderElement());
if (frameLoaderOwner && aFrameLoader->GetMaybePendingBrowsingContext()) {
RefPtr<CanonicalBrowsingContext> loadingBC =
aFrameLoader->GetMaybePendingBrowsingContext()->Canonical();
RefPtr<nsFrameLoader> currentFrameLoader =
frameLoaderOwner->GetFrameLoader();
// The current page can be bfcached, store the
// nsFrameLoader in the current SessionHistoryEntry.
if (aCanSave && aBrowsingContext->GetActiveSessionHistoryEntry()) {
aBrowsingContext->GetActiveSessionHistoryEntry()->SetFrameLoader(
currentFrameLoader);
Unused << aBrowsingContext->SetIsInBFCache(true);
}
// ReplacedBy will swap the entry back.
aBrowsingContext->SetActiveSessionHistoryEntry(aEntry);
loadingBC->SetActiveSessionHistoryEntry(nullptr);
RemotenessChangeOptions options;
aBrowsingContext->ReplacedBy(loadingBC, options);
frameLoaderOwner->ReplaceFrameLoader(aFrameLoader);
// The old page can't be stored in the bfcache,
// destroy the nsFrameLoader.
if (!aCanSave && currentFrameLoader) {
currentFrameLoader->Destroy();
}
// Assuming we still have the session history, update the index.
if (loadingBC->GetSessionHistory()) {
loadingBC->GetSessionHistory()->UpdateIndex();
}
loadingBC->HistoryCommitIndexAndLength();
Unused << loadingBC->SetIsInBFCache(false);
// ResetSHEntryHasUserInteractionCache(); ?
// browser.navigation.requireUserInteraction is still
// disabled everywhere.
return;
}
aFrameLoader->Destroy();
// Fall back to do a normal load.
aBrowsingContext->LoadURI(aLoadState, false);
}
/* static */
void nsSHistory::LoadURIOrBFCache(LoadEntryResult& aLoadEntry) {
if (mozilla::BFCacheInParent() && aLoadEntry.mBrowsingContext->IsTop()) {
@ -1249,52 +1194,131 @@ void nsSHistory::LoadURIOrBFCache(LoadEntryResult& aLoadEntry) {
canonicalBC->GetActiveSessionHistoryEntry();
MOZ_ASSERT(she);
RefPtr<nsFrameLoader> frameLoader = she->GetFrameLoader();
if (frameLoader &&
if (canonicalBC->Group()->Toplevels().Length() == 1 && frameLoader &&
(!currentShe || she->SharedInfo() != currentShe->SharedInfo())) {
bool canSave = (!currentShe || currentShe->GetSaveLayoutStateFlag()) &&
canonicalBC->AllowedInBFCache(Nothing());
auto restoreInitialStep = [canonicalBC, loadState,
she](const nsTArray<bool> aCanSaves) {
bool canSave = !aCanSaves.Contains(false);
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsSHistory::LoadURIOrBFCache "
"saving presentation=%i",
canSave));
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsSHistory::LoadURIOrBFCache "
"saving presentation=%i",
canSave));
if (!canSave) {
nsCOMPtr<nsFrameLoaderOwner> frameLoaderOwner =
do_QueryInterface(canonicalBC->GetEmbedderElement());
if (frameLoaderOwner) {
RefPtr<nsFrameLoader> currentFrameLoader =
frameLoaderOwner->GetFrameLoader();
if (currentFrameLoader &&
currentFrameLoader->GetMaybePendingBrowsingContext()) {
WindowGlobalParent* wgp =
currentFrameLoader->GetMaybePendingBrowsingContext()
->Canonical()
->GetCurrentWindowGlobal();
if (wgp) {
wgp->PermitUnload([canonicalBC, loadState, she, frameLoader,
currentFrameLoader](bool aAllow) {
if (aAllow) {
FinishRestore(canonicalBC, loadState, she, frameLoader,
false);
} else if (currentFrameLoader
->GetMaybePendingBrowsingContext()) {
nsISHistory* shistory =
currentFrameLoader->GetMaybePendingBrowsingContext()
->Canonical()
->GetSessionHistory();
if (shistory) {
shistory->InternalSetRequestedIndex(-1);
}
auto restoreFinalStep = [canonicalBC, loadState, she](bool aCanSave) {
nsCOMPtr<nsFrameLoaderOwner> frameLoaderOwner =
do_QueryInterface(canonicalBC->GetEmbedderElement());
if (frameLoaderOwner) {
RefPtr<nsFrameLoader> fl = she->GetFrameLoader();
if (fl) {
she->SetFrameLoader(nullptr);
RefPtr<BrowsingContext> loadingBC =
fl->GetMaybePendingBrowsingContext();
if (loadingBC) {
RefPtr<nsFrameLoader> currentFrameLoader =
frameLoaderOwner->GetFrameLoader();
// The current page can be bfcached, store the
// nsFrameLoader in the current SessionHistoryEntry.
if (aCanSave && canonicalBC->GetActiveSessionHistoryEntry()) {
canonicalBC->GetActiveSessionHistoryEntry()->SetFrameLoader(
currentFrameLoader);
Unused << canonicalBC->SetIsInBFCache(true);
}
});
return;
// ReplacedBy will swap the entry back.
canonicalBC->SetActiveSessionHistoryEntry(she);
loadingBC->Canonical()->SetActiveSessionHistoryEntry(nullptr);
RemotenessChangeOptions options;
canonicalBC->ReplacedBy(loadingBC->Canonical(), options);
frameLoaderOwner->ReplaceFrameLoader(fl);
// The old page can't be stored in the bfcache,
// destroy the nsFrameLoader.
if (!aCanSave && currentFrameLoader) {
currentFrameLoader->Destroy();
}
// Assuming we still have the session history, update the index.
if (loadingBC->Canonical()->GetSessionHistory()) {
loadingBC->Canonical()->GetSessionHistory()->UpdateIndex();
}
loadingBC->Canonical()->HistoryCommitIndexAndLength();
Unused << loadingBC->SetIsInBFCache(false);
// ResetSHEntryHasUserInteractionCache(); ?
// browser.navigation.requireUserInteraction is still
// disabled everywhere.
return;
}
}
}
// Fall back to do a normal load.
canonicalBC->LoadURI(loadState, false);
};
if (!canSave) {
nsCOMPtr<nsFrameLoaderOwner> frameLoaderOwner =
do_QueryInterface(canonicalBC->GetEmbedderElement());
if (frameLoaderOwner) {
RefPtr<nsFrameLoader> currentFrameLoader =
frameLoaderOwner->GetFrameLoader();
if (currentFrameLoader &&
currentFrameLoader->GetMaybePendingBrowsingContext()) {
WindowGlobalParent* wgp =
currentFrameLoader->GetMaybePendingBrowsingContext()
->Canonical()
->GetCurrentWindowGlobal();
if (wgp) {
wgp->PermitUnload(
[restoreFinalStep, currentFrameLoader](bool aAllow) {
if (aAllow) {
restoreFinalStep(false);
} else if (currentFrameLoader
->GetMaybePendingBrowsingContext()) {
nsISHistory* shistory =
currentFrameLoader->GetMaybePendingBrowsingContext()
->Canonical()
->GetSessionHistory();
if (shistory) {
shistory->InternalSetRequestedIndex(-1);
}
}
});
return;
}
}
}
}
restoreFinalStep(canSave);
};
if (currentShe && !currentShe->GetSaveLayoutStateFlag()) {
// Current page can't enter bfcache because of
// SaveLayoutStateFlag, just run the restore immediately.
nsTArray<bool> canSaves;
canSaves.AppendElement(false);
restoreInitialStep(std::move(canSaves));
return;
}
FinishRestore(canonicalBC, loadState, she, frameLoader, canSave);
nsTArray<RefPtr<PContentParent::CanSavePresentationPromise>>
canSavePromises;
canonicalBC->Group()->EachParent([&](ContentParent* aParent) {
RefPtr<PContentParent::CanSavePresentationPromise> canSave =
aParent->SendCanSavePresentation(canonicalBC, Nothing());
canSavePromises.AppendElement(canSave);
});
// Check if the current page can enter bfcache.
PContentParent::CanSavePresentationPromise::All(
GetCurrentSerialEventTarget(), canSavePromises)
->Then(GetMainThreadSerialEventTarget(), __func__,
std::move(restoreInitialStep),
[canonicalBC, loadState](mozilla::ipc::ResponseRejectReason) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsSHistory::LoadURIOrBFCache "
"error in trying to save presentation"));
canonicalBC->LoadURI(loadState, false);
});
return;
}
if (frameLoader) {

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

@ -1,33 +0,0 @@
<script>
let keepAlive;
window.onpageshow = (pageShow) => {
let bc = new BroadcastChannel("bfcache_blocking");
bc.onmessage = async function(m) {
switch(m.data.message) {
case "load":
bc.close();
location.href = m.data.url;
break;
case "runScript":
let test = new Function(`return ${m.data.fun};`)();
keepAlive = await test.call(window);
bc.postMessage({ type: "runScriptDone" });
break;
case "back":
bc.close();
history.back();
break;
case "forward":
bc.close();
history.forward();
break;
case "close":
window.close();
break;
}
};
bc.postMessage({ type: pageShow.type, persisted: pageShow.persisted })
};
</script>

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

@ -99,10 +99,6 @@ skip-if = (os == "android") # Bug 1560378
[test_bug1375833.html]
[test_bug1536471.html]
support-files = file_bug1536471.html
[test_blockBFCache.html]
support-files =
file_blockBFCache.html
slow.sjs
[test_child.html]
[test_docshell_gotoindex.html]
support-files = file_docshell_gotoindex.html

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

@ -1,14 +0,0 @@
function handleRequest(request, response)
{
response.processAsync();
timer = Components.classes["@mozilla.org/timer;1"].
createInstance(Components.interfaces.nsITimer);
timer.init(function() {
response.finish();
}, 5000, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
response.setStatusLine(null, 200, "OK");
response.setHeader("Content-Type", "text/plain", false);
response.write("Start of the content.");
}

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

@ -1,208 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Blocking pages from entering BFCache</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="">
<script>
const getUserMediaPrefs = {
set: [
["media.devices.insecure.enabled", true],
["media.getusermedia.insecure.enabled", true],
["media.navigator.permission.disabled", true],
],
};
const msePrefs = {
set: [
["media.mediasource.enabled", true],
["media.audio-max-decode-error", 0],
["media.video-max-decode-error", 0],
]
};
const blockBFCacheTests = [
{
name: "Request",
test: () => {
return new Promise((resolve) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", "slow.sjs");
xhr.addEventListener("progress", () => { resolve(xhr); }, { once: true });
xhr.send();
});
},
},
{
name: "Background request",
test: () => {
return new Promise((resolve) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", "slow.sjs");
xhr.addEventListener("readystatechange", () => { if (xhr.readyState == xhr.HEADERS_RECEIVED) resolve(xhr); });
xhr.send();
});
},
},
{
name: "getUserMedia",
prefs: getUserMediaPrefs,
test: () => {
return navigator.mediaDevices.getUserMedia({ audio: true, fake: true });
},
},
{
name: "RTCPeerConnection",
test: () => {
let pc = new RTCPeerConnection();
return pc.createOffer();
},
},
{
name: "MSE",
prefs: msePrefs,
test: () => {
const ms = new MediaSource();
const el = document.createElement("video");
el.src = URL.createObjectURL(ms);
el.preload = "auto";
return el;
},
},
{
name: "WebSpeech",
test: () => {
return new Promise((resolve) => {
const utterance = new SpeechSynthesisUtterance('bfcache');
utterance.lang = 'it-IT-noend';
utterance.addEventListener('start', () => { resolve(utterance); })
speechSynthesis.speak(utterance);
});
},
},
{
name: "WebVR",
prefs: {
set: [
["dom.vr.test.enabled", true],
["dom.vr.puppet.enabled", true],
["dom.vr.require-gesture", false],
],
},
test: () => {
return navigator.requestVRServiceTest();
}
},
];
const dontBlockBFCacheTests = [
{
name: "getUserMedia",
prefs: getUserMediaPrefs,
test: () => {
return navigator.mediaDevices.getUserMedia({ video: true, fake: true }).then(stream => {
stream.getTracks().forEach(track => track.stop());
return stream;
});
},
},
/*
Disabled because MediaKeys rely on being destroyed by the CC before they
notify their window, so the test would intermittently fail depending on
when the CC runs.
{
name: "MSE",
prefs: msePrefs,
test: () => {
return new Promise((resolve) => {
const ms = new MediaSource();
const el = document.createElement("video");
ms.addEventListener("sourceopen", () => { resolve(el) }, { once: true });
el.src = URL.createObjectURL(ms);
el.preload = "auto";
}).then(el => {
el.src = "";
return el;
});
},
},
*/
];
let bc = new BroadcastChannel("bfcache_blocking");
function promiseMessage(type) {
return new Promise((resolve, reject) => {
bc.addEventListener("message", (e) => {
if (e.data.type == type) {
resolve(e.data);
}
}, { once: true });
});
}
function promisePageShow(shouldBePersisted) {
return promiseMessage("pageshow").then(data => data.persisted == shouldBePersisted);
}
function promisePageShowFromBFCache(e) {
return promisePageShow(true);
}
function promisePageShowNotFromBFCache(e) {
return promisePageShow(false);
}
function runTests(testArray, shouldBlockBFCache) {
for (const { name, prefs = {}, test } of testArray) {
add_task(async function() {
await SpecialPowers.pushPrefEnv(prefs, async function() {
// Load a mostly blank page that we can communicate with over
// BroadcastChannel (though it will close the BroadcastChannel after
// receiving the next "load" message, to avoid blocking BFCache).
let loaded = promisePageShowNotFromBFCache();
window.open("file_blockBFCache.html", "", "noopener");
await loaded;
// Load the same page with a different URL.
loaded = promisePageShowNotFromBFCache();
bc.postMessage({ message: "load", url: `file_blockBFCache.html?${name}_${shouldBlockBFCache}` });
await loaded;
// Run test script in the second page.
bc.postMessage({ message: "runScript", fun: test.toString() });
await promiseMessage("runScriptDone");
// Go back to the first page (this should just come from the BFCache).
let goneBack = promisePageShowFromBFCache();
bc.postMessage({ message: "back" });
await goneBack;
// Go forward again to the second page and check that it does/doesn't come
// from the BFCache.
let goneForward = promisePageShow(!shouldBlockBFCache);
bc.postMessage({ message: "forward" });
let result = await goneForward;
ok(result, `Page ${shouldBlockBFCache ? "should" : "should not"} have been blocked from going into the BFCache (${name})`);
bc.postMessage({ message: "close" });
SpecialPowers.popPrefEnv();
});
});
}
}
// If Fission is disabled, the pref is no-op.
SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => {
runTests(blockBFCacheTests, true);
runTests(dontBlockBFCacheTests, false);
});
</script>
</body>
</html>

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

@ -6783,17 +6783,6 @@ void Document::DeletePresShell() {
mDesignModeSheetAdded = false;
}
void Document::DisallowBFCaching() {
NS_ASSERTION(!mBFCacheEntry, "We're already in the bfcache!");
if (!mBFCacheDisallowed) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::NOT_ALLOWED);
}
}
mBFCacheDisallowed = true;
}
void Document::SetBFCacheEntry(nsIBFCacheEntry* aEntry) {
MOZ_ASSERT(IsBFCachingAllowed() || !aEntry, "You should have checked!");
@ -11868,12 +11857,6 @@ void Document::GetReadyState(nsAString& aReadyState) const {
void Document::SuppressEventHandling(uint32_t aIncrease) {
mEventsSuppressed += aIncrease;
if (mEventsSuppressed == aIncrease) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::EVENT_HANDLING_SUPPRESSED);
}
}
UpdateFrameRequestCallbackSchedulingState();
for (uint32_t i = 0; i < aIncrease; ++i) {
ScriptLoader()->AddExecuteBlocker();
@ -12272,11 +12255,6 @@ void Document::UnsuppressEventHandlingAndFireEvents(bool aFireEvents) {
}
if (!EventHandlingSuppressed()) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::EVENT_HANDLING_SUPPRESSED);
}
MOZ_ASSERT(NS_IsMainThread());
nsTArray<RefPtr<net::ChannelEventQueue>> queues =
std::move(mSuspendedQueues);
@ -17253,23 +17231,4 @@ void Document::DisableChildElementInPictureInPictureMode() {
MOZ_ASSERT(mPictureInPictureChildElementCount >= 0);
}
void Document::AddMediaElementWithMSE() {
if (mMediaElementWithMSECount++ == 0) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::CONTAINS_MSE_CONTENT);
}
}
}
void Document::RemoveMediaElementWithMSE() {
MOZ_ASSERT(mMediaElementWithMSECount > 0);
if (--mMediaElementWithMSECount == 0) {
WindowGlobalChild* wgc = GetWindowGlobalChild();
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::CONTAINS_MSE_CONTENT);
}
}
}
} // namespace mozilla::dom

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

@ -1201,7 +1201,10 @@ class Document : public nsINode,
// Instead using this method, what you probably want is
// RemoveFromBFCacheSync() as we do in MessagePort and BroadcastChannel.
void DisallowBFCaching();
void DisallowBFCaching() {
NS_ASSERTION(!mBFCacheEntry, "We're already in the bfcache!");
mBFCacheDisallowed = true;
}
bool IsBFCachingAllowed() const { return !mBFCacheDisallowed; }
@ -1517,9 +1520,6 @@ class Document : public nsINode,
bool ShouldIncludeInTelemetry(bool aAllowExtensionURIs);
void AddMediaElementWithMSE();
void RemoveMediaElementWithMSE();
protected:
friend class nsUnblockOnloadEvent;
@ -5233,8 +5233,6 @@ class Document : public nsINode,
int32_t mNextFormNumber;
int32_t mNextControlNumber;
uint32_t mMediaElementWithMSECount = 0;
// Scope preloads per document. This is used by speculative loading as well.
PreloadService mPreloadService;

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

@ -939,7 +939,8 @@ nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
mAreDialogsEnabled(true),
mObservingRefresh(false),
mIteratingDocumentFlushedResolvers(false),
mCanSkipCCGeneration(0) {
mCanSkipCCGeneration(0),
mBeforeUnloadListenerCount(0) {
mIsInnerWindow = true;
AssertIsOnMainThread();
@ -2612,49 +2613,33 @@ bool nsGlobalWindowInner::CrossOriginIsolated() const {
void nsPIDOMWindowInner::AddPeerConnection() {
MOZ_ASSERT(NS_IsMainThread());
mTopInnerWindow ? mTopInnerWindow->mTotalActivePeerConnections++
: mTotalActivePeerConnections++;
++mActivePeerConnections;
if (mActivePeerConnections == 1 && mWindowGlobalChild) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::ACTIVE_PEER_CONNECTION);
}
mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections++
: mActivePeerConnections++;
}
void nsPIDOMWindowInner::RemovePeerConnection() {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTopInnerWindow ? mTopInnerWindow->mTotalActivePeerConnections
: mTotalActivePeerConnections);
MOZ_ASSERT(mActivePeerConnections > 0);
MOZ_ASSERT(mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections
: mActivePeerConnections);
mTopInnerWindow ? mTopInnerWindow->mTotalActivePeerConnections--
: mTotalActivePeerConnections--;
--mActivePeerConnections;
if (mActivePeerConnections == 0 && mWindowGlobalChild) {
mWindowGlobalChild->UnblockBFCacheFor(
BFCacheStatus::ACTIVE_PEER_CONNECTION);
}
mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections--
: mActivePeerConnections--;
}
bool nsPIDOMWindowInner::HasActivePeerConnections() {
MOZ_ASSERT(NS_IsMainThread());
return mTopInnerWindow ? mTopInnerWindow->mTotalActivePeerConnections
: mTotalActivePeerConnections;
return mTopInnerWindow ? mTopInnerWindow->mActivePeerConnections
: mActivePeerConnections;
}
void nsPIDOMWindowInner::AddMediaKeysInstance(MediaKeys* aMediaKeys) {
MOZ_ASSERT(NS_IsMainThread());
mMediaKeysInstances.AppendElement(aMediaKeys);
if (mWindowGlobalChild && mMediaKeysInstances.Length() == 1) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
}
}
void nsPIDOMWindowInner::RemoveMediaKeysInstance(MediaKeys* aMediaKeys) {
MOZ_ASSERT(NS_IsMainThread());
mMediaKeysInstances.RemoveElement(aMediaKeys);
if (mWindowGlobalChild && mMediaKeysInstances.IsEmpty()) {
mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::CONTAINS_EME_CONTENT);
}
}
bool nsPIDOMWindowInner::HasActiveMediaKeysInstance() {
@ -5475,10 +5460,6 @@ void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) {
return;
}
if (mWindowGlobalChild) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::SUSPENDED);
}
nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
if (ac) {
for (uint32_t i = 0; i < mEnabledSensors.Length(); i++)
@ -5565,10 +5546,6 @@ void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) {
mSharedWorkers.ForwardRange()) {
pinnedWorker->Resume();
}
if (mWindowGlobalChild) {
mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::SUSPENDED);
}
}
bool nsGlobalWindowInner::IsSuspended() const {
@ -6485,16 +6462,10 @@ void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
mHasVRDisplayActivateEvents = true;
}
if ((aType == nsGkAtoms::onunload || aType == nsGkAtoms::onbeforeunload) &&
mWindowGlobalChild) {
if (++mUnloadOrBeforeUnloadListenerCount == 1) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
}
if (aType == nsGkAtoms::onbeforeunload &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) {
mWindowGlobalChild->BeforeUnloadAdded();
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() > 0);
}
if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) {
mWindowGlobalChild->BeforeUnloadAdded();
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() > 0);
}
// We need to initialize localStorage in order to receive notifications.
@ -6513,17 +6484,10 @@ void nsGlobalWindowInner::EventListenerAdded(nsAtom* aType) {
}
void nsGlobalWindowInner::EventListenerRemoved(nsAtom* aType) {
if ((aType == nsGkAtoms::onunload || aType == nsGkAtoms::onbeforeunload) &&
mWindowGlobalChild) {
MOZ_ASSERT(mUnloadOrBeforeUnloadListenerCount > 0);
if (--mUnloadOrBeforeUnloadListenerCount == 0) {
mWindowGlobalChild->UnblockBFCacheFor(BFCacheStatus::UNLOAD_LISTENER);
}
if (aType == nsGkAtoms::onbeforeunload &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) {
mWindowGlobalChild->BeforeUnloadRemoved();
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() >= 0);
}
if (aType == nsGkAtoms::onbeforeunload && mWindowGlobalChild &&
(!mDoc || !(mDoc->GetSandboxFlags() & SANDBOXED_MODALS))) {
mWindowGlobalChild->BeforeUnloadRemoved();
MOZ_ASSERT(mWindowGlobalChild->BeforeUnloadListeners() >= 0);
}
if (aType == nsGkAtoms::onstorage) {
@ -6547,9 +6511,6 @@ void nsGlobalWindowInner::NotifyHasXRSession() {
// has been called, including mVREventObserver.
return;
}
if (mWindowGlobalChild && !mHasXRSession) {
mWindowGlobalChild->BlockBFCacheFor(BFCacheStatus::HAS_USED_VR);
}
mHasXRSession = true;
EnableVRUpdates();
}
@ -7667,6 +7628,7 @@ bool nsPIDOMWindowInner::HasStorageAccessPermissionGranted() {
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
WindowGlobalChild* aActor)
: mMutationBits(0),
mActivePeerConnections(0),
mIsDocumentLoaded(false),
mIsHandlingResizeEvent(false),
mMayHavePaintEventListener(false),

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

@ -1473,9 +1473,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
RefPtr<mozilla::dom::VREventObserver> mVREventObserver;
// The number of unload and beforeunload even listeners registered on this
// window.
uint64_t mUnloadOrBeforeUnloadListenerCount = 0;
int64_t mBeforeUnloadListenerCount;
RefPtr<mozilla::dom::IntlUtils> mIntlUtils;

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

@ -638,11 +638,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
// These variables are only used on inner windows.
uint32_t mMutationBits;
uint32_t mActivePeerConnections = 0;
// This is the count for active peer connections for all the windows in the
// subtree rooted at this window (only set on the top window).
uint32_t mTotalActivePeerConnections = 0;
uint32_t mActivePeerConnections;
bool mIsDocumentLoaded;
bool mIsHandlingResizeEvent;

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

@ -86,7 +86,6 @@
#include "mozilla/dom/VideoTrack.h"
#include "mozilla/dom/VideoTrackList.h"
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "nsAttrValueInlines.h"
@ -2240,10 +2239,6 @@ void HTMLMediaElement::AbortExistingLoads() {
EndSrcMediaStreamPlayback();
}
if (mMediaSource) {
OwnerDoc()->RemoveMediaElementWithMSE();
}
RemoveMediaElementFromURITable();
mLoadingSrcTriggeringPrincipal = nullptr;
DDLOG(DDLogCategory::Property, "loading_src", "");
@ -2554,10 +2549,6 @@ void HTMLMediaElement::SelectResource() {
!mIsLoadingFromSourceChildren,
"Should think we're not loading from source children by default");
if (!mMediaSource) {
OwnerDoc()->AddMediaElementWithMSE();
}
RemoveMediaElementFromURITable();
if (!mSrcMediaSource) {
mLoadingSrc = uri;
@ -2821,10 +2812,6 @@ void HTMLMediaElement::LoadFromSourceChildren() {
return;
}
if (!mMediaSource) {
OwnerDoc()->AddMediaElementWithMSE();
}
RemoveMediaElementFromURITable();
mLoadingSrc = uri;
mLoadingSrcTriggeringPrincipal = childSrc->GetSrcTriggeringPrincipal();
@ -7665,15 +7652,6 @@ bool HTMLMediaElement::IsBeingUsedInPictureInPictureMode() const {
return static_cast<const HTMLVideoElement*>(this)->IsCloningElementVisually();
}
void HTMLMediaElement::NodeInfoChanged(Document* aOldDoc) {
if (mMediaSource) {
OwnerDoc()->AddMediaElementWithMSE();
aOldDoc->RemoveMediaElementWithMSE();
}
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
}
} // namespace mozilla::dom
#undef LOG

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

@ -192,8 +192,6 @@ class HTMLMediaElement : public nsGenericHTMLElement,
// EventTarget
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
void NodeInfoChanged(Document* aOldDoc) override;
virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,

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

@ -181,21 +181,6 @@ parent:
async ResetSessionStore(uint32_t aEpoch);
// Add the flags in aOnFlags to the current BFCache status and remove the
// flags in aOffFlags from the current BFCache status. See the BFCacheStatus
// enum for the valid flags.
async UpdateBFCacheStatus(uint16_t aOnFlags, uint16_t aOffFlags);
/**
* Used to notify the parent when there's a change in the number of requests
* in the loadgroup. If there are no requests this will be set to Nothing().
* If there is one request this will be set to the ID of that request, if it
* implements nsIIdentChannel. If there are more than one requests this will
* be set to 0.
* Note that some requests are ignored (eg. favicon loads).
*/
async SetSingleChannelId(uint64_t? singleChannelId);
async Destroy();
};

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

@ -671,14 +671,6 @@ bool WindowGlobalChild::SameOriginWithTop() {
return IsSameOriginWith(WindowContext()->TopWindowContext());
}
void WindowGlobalChild::UnblockBFCacheFor(BFCacheStatus aStatus) {
SendUpdateBFCacheStatus(0, aStatus);
}
void WindowGlobalChild::BlockBFCacheFor(BFCacheStatus aStatus) {
SendUpdateBFCacheStatus(aStatus, 0);
}
WindowGlobalChild::~WindowGlobalChild() = default;
JSObject* WindowGlobalChild::WrapObject(JSContext* aCx,

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

@ -12,7 +12,6 @@
#include "mozilla/dom/PWindowGlobalChild.h"
#include "nsRefPtrHashtable.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/WindowGlobalActor.h"
class nsGlobalWindowInner;
@ -133,9 +132,6 @@ class WindowGlobalChild final : public WindowGlobalActor,
void SetSessionStoreDataCollector(SessionStoreDataCollector* aCollector);
SessionStoreDataCollector* GetSessionStoreDataCollector() const;
void UnblockBFCacheFor(BFCacheStatus aStatus);
void BlockBFCacheFor(BFCacheStatus aStatus);
protected:
const nsACString& GetRemoteType() override;

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

@ -70,7 +70,6 @@
using namespace mozilla::ipc;
using namespace mozilla::dom::ipc;
extern mozilla::LazyLogModule gSHIPBFCacheLog;
extern mozilla::LazyLogModule gUseCountersLog;
namespace mozilla::dom {
@ -1316,65 +1315,6 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvRequestRestoreTabContent() {
return IPC_OK();
}
nsCString BFCacheStatusToString(uint16_t aFlags) {
if (aFlags == 0) {
return "0"_ns;
}
nsCString flags;
#define ADD_BFCACHESTATUS_TO_STRING(_flag) \
if (aFlags & BFCacheStatus::_flag) { \
if (!flags.IsEmpty()) { \
flags.Append('|'); \
} \
flags.AppendLiteral(#_flag); \
aFlags &= ~BFCacheStatus::_flag; \
}
ADD_BFCACHESTATUS_TO_STRING(NOT_ALLOWED);
ADD_BFCACHESTATUS_TO_STRING(EVENT_HANDLING_SUPPRESSED);
ADD_BFCACHESTATUS_TO_STRING(SUSPENDED);
ADD_BFCACHESTATUS_TO_STRING(UNLOAD_LISTENER);
ADD_BFCACHESTATUS_TO_STRING(REQUEST);
ADD_BFCACHESTATUS_TO_STRING(ACTIVE_GET_USER_MEDIA);
ADD_BFCACHESTATUS_TO_STRING(ACTIVE_PEER_CONNECTION);
ADD_BFCACHESTATUS_TO_STRING(CONTAINS_EME_CONTENT);
ADD_BFCACHESTATUS_TO_STRING(CONTAINS_MSE_CONTENT);
ADD_BFCACHESTATUS_TO_STRING(HAS_ACTIVE_SPEECH_SYNTHESIS);
ADD_BFCACHESTATUS_TO_STRING(HAS_USED_VR);
ADD_BFCACHESTATUS_TO_STRING(CONTAINS_REMOTE_SUBFRAMES);
ADD_BFCACHESTATUS_TO_STRING(NOT_ONLY_TOPLEVEL_IN_BCG);
#undef ADD_BFCACHESTATUS_TO_STRING
MOZ_ASSERT(aFlags == 0,
"Missing stringification for enum value in BFCacheStatus.");
return flags;
}
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateBFCacheStatus(
const uint16_t& aOnFlags, const uint16_t& aOffFlags) {
if (MOZ_UNLIKELY(MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug))) {
nsAutoCString uri("[no uri]");
if (mDocumentURI) {
uri = mDocumentURI->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("Setting BFCache flags for %s +(%s) -(%s)", uri.get(),
BFCacheStatusToString(aOnFlags).get(),
BFCacheStatusToString(aOffFlags).get()));
}
mBFCacheStatus |= aOnFlags;
mBFCacheStatus &= ~aOffFlags;
return IPC_OK();
}
mozilla::ipc::IPCResult WindowGlobalParent::RecvSetSingleChannelId(
const Maybe<uint64_t>& aSingleChannelId) {
mSingleChannelId = aSingleChannelId;
return IPC_OK();
}
void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
if (mPageUseCountersWindow) {
mPageUseCountersWindow->FinishAccumulatingPageUseCounters();

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

@ -213,10 +213,6 @@ class WindowGlobalParent final : public WindowContext,
const Maybe<nsPoint>& aScrollPosition,
uint32_t aEpoch);
Maybe<uint64_t> GetSingleChannelId() { return mSingleChannelId; }
uint16_t GetBFCacheStatus() { return mBFCacheStatus; }
protected:
already_AddRefed<JSActor> InitJSActor(JS::HandleObject aMaybeActor,
const nsACString& aName,
@ -284,13 +280,6 @@ class WindowGlobalParent final : public WindowContext,
mozilla::ipc::IPCResult RecvResetSessionStore(uint32_t aEpoch);
mozilla::ipc::IPCResult RecvUpdateBFCacheStatus(const uint16_t& aOnFlags,
const uint16_t& aOffFlags);
public:
mozilla::ipc::IPCResult RecvSetSingleChannelId(
const Maybe<uint64_t>& aSingleChannelId);
private:
WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext,
uint64_t aInnerWindowId, uint64_t aOuterWindowId,
@ -363,19 +352,6 @@ class WindowGlobalParent final : public WindowContext,
// Whether we have sent our page use counters, and so should ignore any
// subsequent ExpectPageUseCounters calls.
bool mSentPageUseCounters = false;
uint16_t mBFCacheStatus = 0;
// mSingleChannelId records whether the loadgroup contains a single request
// with an id. If there is one channel in the loadgroup and it has an id then
// mSingleChannelId is set to Some(id) (ids are non-zero). If there is one
// request in the loadgroup and it's not a channel or it doesn't have an id,
// or there are multiple requests in the loadgroup, then mSingleChannelId is
// set to Some(0). If there are no requests in the loadgroup then
// mSingleChannelId is set to Nothing().
// Note: We ignore favicon loads when considering the requests in the
// loadgroup.
Maybe<uint64_t> mSingleChannelId;
};
} // namespace dom

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

@ -38,7 +38,6 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/media/MediaChild.h"
#include "mozilla/media/MediaTaskUtils.h"
@ -165,7 +164,6 @@ class GetUserMediaStreamTask;
class LocalTrackSource;
class SelectAudioOutputTask;
using dom::BFCacheStatus;
using dom::CallerType;
using dom::ConstrainDOMStringParameters;
using dom::ConstrainDoubleRange;
@ -193,7 +191,6 @@ using dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters;
using dom::Promise;
using dom::Sequence;
using dom::UserActivation;
using dom::WindowGlobalChild;
using media::NewRunnableFrom;
using media::NewTaskFrom;
using media::Refcountable;
@ -3414,21 +3411,9 @@ void MediaManager::AddWindowID(uint64_t aWindowId,
aListener->MuteOrUnmuteCameras(mCamerasMuted);
aListener->MuteOrUnmuteMicrophones(mMicrophonesMuted);
GetActiveWindows()->InsertOrUpdate(aWindowId, std::move(aListener));
RefPtr<WindowGlobalChild> wgc =
WindowGlobalChild::GetByInnerWindowId(aWindowId);
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
}
}
void MediaManager::RemoveWindowID(uint64_t aWindowId) {
RefPtr<WindowGlobalChild> wgc =
WindowGlobalChild::GetByInnerWindowId(aWindowId);
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::ACTIVE_GET_USER_MEDIA);
}
mActiveWindows.Remove(aWindowId);
// get outer windowID

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

@ -11,7 +11,6 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/SpeechSynthesisBinding.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "SpeechSynthesis.h"
#include "nsContentUtils.h"
#include "nsSynthVoiceRegistry.h"
@ -119,18 +118,11 @@ void SpeechSynthesis::Speak(SpeechSynthesisUtterance& aUtterance) {
mSpeechQueue.AppendElement(&aUtterance);
if (mSpeechQueue.Length() == 1) {
RefPtr<WindowGlobalChild> wgc =
WindowGlobalChild::GetByInnerWindowId(mInnerID);
if (wgc) {
wgc->BlockBFCacheFor(BFCacheStatus::HAS_ACTIVE_SPEECH_SYNTHESIS);
}
// If we only have one item in the queue, we aren't pre-paused, and
// we have voices available, speak it.
if (!mCurrentTask && !mHoldQueue && HasVoices()) {
AdvanceQueue();
}
// If we only have one item in the queue, we aren't pre-paused, and
// we have voices available, speak it.
if (mSpeechQueue.Length() == 1 && !mCurrentTask && !mHoldQueue &&
HasVoices()) {
AdvanceQueue();
}
}
@ -209,13 +201,6 @@ void SpeechSynthesis::OnEnd(const nsSpeechTask* aTask) {
if (!mSpeechQueue.IsEmpty()) {
mSpeechQueue.RemoveElementAt(0);
if (mSpeechQueue.IsEmpty()) {
RefPtr<WindowGlobalChild> wgc =
WindowGlobalChild::GetByInnerWindowId(mInnerID);
if (wgc) {
wgc->UnblockBFCacheFor(BFCacheStatus::HAS_ACTIVE_SPEECH_SYNTHESIS);
}
}
}
mCurrentTask = nullptr;

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

@ -16,11 +16,21 @@ namespace mozilla {
using namespace gfx;
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(VRMockDisplay, DOMEventTargetHelper,
mVRServiceTest)
NS_IMPL_CYCLE_COLLECTION_CLASS(VRMockDisplay)
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(VRMockDisplay,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(VRMockDisplay,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(VRMockDisplay,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(VRMockDisplay)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(VRMockDisplay, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(VRMockDisplay, DOMEventTargetHelper)
namespace {
template <class T>
@ -336,11 +346,21 @@ void VRMockDisplay::SetPose(const Nullable<Float32Array>& aPosition,
}
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(VRMockController, DOMEventTargetHelper,
mVRServiceTest)
NS_IMPL_CYCLE_COLLECTION_CLASS(VRMockController)
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(VRMockController,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(VRMockController,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(VRMockController,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(VRMockController)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(VRMockController, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(VRMockController, DOMEventTargetHelper)
VRMockController::VRMockController(VRServiceTest* aVRServiceTest,
uint32_t aControllerIdx)
@ -536,11 +556,21 @@ void VRMockController::SetPose(
}
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(VRServiceTest, DOMEventTargetHelper,
mDisplay, mControllers, mWindow)
NS_IMPL_CYCLE_COLLECTION_CLASS(VRServiceTest)
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(VRServiceTest,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(VRServiceTest,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(VRServiceTest,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(VRServiceTest)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(VRServiceTest, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(VRServiceTest, DOMEventTargetHelper)
JSObject* VRServiceTest::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {

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

@ -465,13 +465,10 @@ nsLoadGroup::AddRequest(nsIRequest* request, nsISupports* ctxt) {
nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(request);
if (timedChannel) timedChannel->SetTimingEnabled(true);
bool foreground = !(flags & nsIRequest::LOAD_BACKGROUND);
if (foreground) {
if (!(flags & nsIRequest::LOAD_BACKGROUND)) {
// Update the count of foreground URIs..
mForegroundCount += 1;
}
if (foreground || mNotifyObserverAboutBackgroundRequests) {
//
// Fire the OnStartRequest notification out to the observer...
//
@ -498,14 +495,12 @@ nsLoadGroup::AddRequest(nsIRequest* request, nsISupports* ctxt) {
rv = NS_OK;
if (foreground) {
mForegroundCount -= 1;
}
mForegroundCount -= 1;
}
}
// Ensure that we're part of our loadgroup while pending
if (foreground && mForegroundCount == 1 && mLoadGroup) {
if (mForegroundCount == 1 && mLoadGroup) {
mLoadGroup->AddRequest(this, nullptr);
}
}
@ -606,13 +601,10 @@ nsresult nsLoadGroup::NotifyRemovalObservers(nsIRequest* request,
nsresult rv = request->GetLoadFlags(&flags);
if (NS_FAILED(rv)) return rv;
bool foreground = !(flags & nsIRequest::LOAD_BACKGROUND);
if (foreground) {
if (!(flags & nsIRequest::LOAD_BACKGROUND)) {
NS_ASSERTION(mForegroundCount > 0, "ForegroundCount messed up");
mForegroundCount -= 1;
}
if (foreground || mNotifyObserverAboutBackgroundRequests) {
// Fire the OnStopRequest out to the observer...
nsCOMPtr<nsIRequestObserver> observer = do_QueryReferent(mObserver);
if (observer) {
@ -630,7 +622,7 @@ nsresult nsLoadGroup::NotifyRemovalObservers(nsIRequest* request,
}
// If that was the last request -> remove ourselves from loadgroup
if (foreground && mForegroundCount == 0 && mLoadGroup) {
if (mForegroundCount == 0 && mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, aStatus);
}
}
@ -653,14 +645,8 @@ nsLoadGroup::GetRequests(nsISimpleEnumerator** aRequests) {
NS_IMETHODIMP
nsLoadGroup::SetGroupObserver(nsIRequestObserver* aObserver) {
SetGroupObserver(aObserver, false);
return NS_OK;
}
void nsLoadGroup::SetGroupObserver(nsIRequestObserver* aObserver,
bool aIncludeBackgroundRequests) {
mObserver = do_GetWeakReference(aObserver);
mNotifyObserverAboutBackgroundRequests = aIncludeBackgroundRequests;
return NS_OK;
}
NS_IMETHODIMP

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

@ -58,9 +58,6 @@ class nsLoadGroup : public nsILoadGroup,
nsresult Init();
nsresult InitWithRequestContextId(const uint64_t& aRequestContextId);
void SetGroupObserver(nsIRequestObserver* aObserver,
bool aIncludeBackgroundRequests);
protected:
virtual ~nsLoadGroup();
@ -97,7 +94,6 @@ class nsLoadGroup : public nsILoadGroup,
bool mDefaultLoadIsTimed;
bool mBrowsingContextDiscarded;
bool mExternalRequestContext;
bool mNotifyObserverAboutBackgroundRequests;
/* Telemetry */
mozilla::TimeStamp mDefaultRequestCreationTime;

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

@ -1709,6 +1709,7 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
if (mozilla::BFCacheInParent() && nsSHistory::GetMaxTotalViewers() > 0 &&
!parentWindow && !browsingContext->HadOriginalOpener() &&
browsingContext->Group()->Toplevels().Length() == 1 &&
!options.mRemoteType.IsEmpty() &&
browsingContext->GetHasLoadedNonInitialDocument() &&
(mLoadStateLoadType == LOAD_NORMAL ||
@ -1718,12 +1719,8 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
(!browsingContext->GetActiveSessionHistoryEntry() ||
browsingContext->GetActiveSessionHistoryEntry()
->GetSaveLayoutStateFlag())) {
MOZ_ASSERT(mIsDocumentLoad);
options.mTryUseBFCache =
browsingContext->AllowedInBFCache(mDocumentChannelId);
if (options.mTryUseBFCache) {
options.mReplaceBrowsingContext = true;
}
options.mReplaceBrowsingContext = true;
options.mTryUseBFCache = true;
}
LOG(("GetRemoteTypeForPrincipal -> current:%s remoteType:%s",
@ -1747,6 +1744,44 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
// If we're doing a document load, we can immediately perform a process
// switch.
if (mIsDocumentLoad) {
if (options.mTryUseBFCache && wgp) {
if (RefPtr<BrowserParent> browserParent = wgp->GetBrowserParent()) {
nsTArray<RefPtr<PContentParent::CanSavePresentationPromise>>
canSavePromises;
browsingContext->Group()->EachParent([&](ContentParent* aParent) {
RefPtr<PContentParent::CanSavePresentationPromise> canSave =
aParent->SendCanSavePresentation(browsingContext,
mDocumentChannelId);
canSavePromises.AppendElement(canSave);
});
PContentParent::CanSavePresentationPromise::All(
GetCurrentSerialEventTarget(), canSavePromises)
->Then(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this}, browsingContext,
options](const nsTArray<bool> aCanSaves) mutable {
bool canSave = !aCanSaves.Contains(false);
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("DocumentLoadListener::MaybeTriggerProcessSwitch "
"saving presentation=%i",
canSave));
options.mTryUseBFCache = canSave;
self->TriggerProcessSwitch(browsingContext, options);
},
[self = RefPtr{this}, browsingContext,
options](ipc::ResponseRejectReason) mutable {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("DocumentLoadListener::MaybeTriggerProcessSwitch "
"error in trying to save presentation"));
options.mTryUseBFCache = false;
self->TriggerProcessSwitch(browsingContext, options);
});
return true;
}
}
options.mTryUseBFCache = false;
TriggerProcessSwitch(browsingContext, options);
return true;
}

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

@ -103,7 +103,7 @@ class nsDefaultComparator<nsDocLoader::nsListenerInfo,
PLDHashTable::MoveEntryStub, nsDocLoader::RequestInfoHashClearEntry,
nsDocLoader::RequestInfoHashInitEntry};
nsDocLoader::nsDocLoader(bool aNotifyAboutBackgroundRequests)
nsDocLoader::nsDocLoader()
: mParent(nullptr),
mProgressStateFlags(0),
mCurrentSelfProgress(0),
@ -119,8 +119,7 @@ nsDocLoader::nsDocLoader(bool aNotifyAboutBackgroundRequests)
mTreatAsBackgroundLoad(false),
mHasFakeOnLoadDispatched(false),
mIsReadyToHandlePostMessage(false),
mDocumentOpenedButNotLoaded(false),
mNotifyAboutBackgroundRequests(aNotifyAboutBackgroundRequests) {
mDocumentOpenedButNotLoaded(false) {
ClearInternalProgress();
MOZ_LOG(gDocLoaderLog, LogLevel::Debug, ("DocLoader:%p: created.\n", this));
@ -132,14 +131,9 @@ nsresult nsDocLoader::SetDocLoaderParent(nsDocLoader* aParent) {
}
nsresult nsDocLoader::Init() {
RefPtr<net::nsLoadGroup> loadGroup = new net::nsLoadGroup();
nsresult rv = loadGroup->Init();
nsresult rv = NS_NewLoadGroup(getter_AddRefs(mLoadGroup), this);
if (NS_FAILED(rv)) return rv;
loadGroup->SetGroupObserver(this, mNotifyAboutBackgroundRequests);
mLoadGroup = loadGroup;
MOZ_LOG(gDocLoaderLog, LogLevel::Debug,
("DocLoader:%p: load group %p.\n", this, mLoadGroup.get()));
@ -156,7 +150,8 @@ nsresult nsDocLoader::InitWithBrowsingContext(
aBrowsingContext->GetRequestContextId());
if (NS_FAILED(rv)) return rv;
loadGroup->SetGroupObserver(this, mNotifyAboutBackgroundRequests);
rv = loadGroup->SetGroupObserver(this);
if (NS_FAILED(rv)) return rv;
mLoadGroup = loadGroup;
@ -409,14 +404,6 @@ NS_IMETHODIMP
nsDocLoader::OnStartRequest(nsIRequest* request) {
// called each time a request is added to the group.
// Some docloaders deal with background requests in their OnStartRequest
// override, but here we don't want to do anything with them, so return early.
nsLoadFlags loadFlags = 0;
request->GetLoadFlags(&loadFlags);
if (loadFlags & nsIRequest::LOAD_BACKGROUND) {
return NS_OK;
}
if (MOZ_LOG_TEST(gDocLoaderLog, LogLevel::Debug)) {
nsAutoCString name;
request->GetName(name);
@ -433,6 +420,9 @@ nsDocLoader::OnStartRequest(nsIRequest* request) {
bool justStartedLoading = false;
nsLoadFlags loadFlags = 0;
request->GetLoadFlags(&loadFlags);
if (!mIsLoadingDocument && (loadFlags & nsIChannel::LOAD_DOCUMENT_URI)) {
justStartedLoading = true;
mIsLoadingDocument = true;
@ -506,14 +496,6 @@ nsDocLoader::OnStartRequest(nsIRequest* request) {
NS_IMETHODIMP
nsDocLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
// Some docloaders deal with background requests in their OnStopRequest
// override, but here we don't want to do anything with them, so return early.
nsLoadFlags lf = 0;
aRequest->GetLoadFlags(&lf);
if (lf & nsIRequest::LOAD_BACKGROUND) {
return NS_OK;
}
nsresult rv = NS_OK;
if (MOZ_LOG_TEST(gDocLoaderLog, LogLevel::Debug)) {
@ -593,6 +575,8 @@ nsDocLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
//
// Only if the load has been targeted (see bug 268483)...
//
uint32_t lf;
channel->GetLoadFlags(&lf);
if (lf & nsIChannel::LOAD_TARGETED) {
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
if (httpChannel) {

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

@ -59,7 +59,7 @@ class nsDocLoader : public nsIDocumentLoader,
NS_DECLARE_STATIC_IID_ACCESSOR(NS_THIS_DOCLOADER_IMPL_CID)
nsDocLoader() : nsDocLoader(false) {}
nsDocLoader();
[[nodiscard]] virtual nsresult Init();
[[nodiscard]] nsresult InitWithBrowsingContext(
@ -159,7 +159,6 @@ class nsDocLoader : public nsIDocumentLoader,
uint32_t ChildCount() const { return mChildList.Length(); }
protected:
explicit nsDocLoader(bool aNotifyAboutBackgroundRequests);
virtual ~nsDocLoader();
[[nodiscard]] virtual nsresult SetDocLoaderParent(nsDocLoader* aLoader);
@ -364,8 +363,6 @@ class nsDocLoader : public nsIDocumentLoader,
*/
bool mDocumentOpenedButNotLoaded;
bool mNotifyAboutBackgroundRequests;
static const PLDHashTableOps sRequestInfoHashOps;
// A list of kids that are in the middle of their onload calls and will let