Bug 1635914 - Move active flag handling explicitly to BrowsingContext. r=nika

And have it mirror in the parent process more automatically.

The docShellIsActive setter in the browser-custom-element side needs to
be there rather than in the usual DidSet() calls because the
AsyncTabSwitcher code relies on getting an exact amount of notifications
as response to that specific setter. Not pretty, but...

BrowserChild no longer sets IsActive() on the docshell itself for OOP
iframes. This fixes bug 1679521. PresShell activeness is used to
throttle rAF as well, which handles OOP iframes nicely as well.

Differential Revision: https://phabricator.services.mozilla.com/D96072
This commit is contained in:
Emilio Cobos Álvarez
2020-12-11 15:43:19 +00:00
parent 2bd69db15d
commit 136e604164
60 changed files with 298 additions and 460 deletions

View File

@@ -351,7 +351,7 @@ static bool IsUrgentStart(BrowsingContext* aBrowsingContext,
return true;
}
return aBrowsingContext->GetIsActive();
return aBrowsingContext->IsActive();
}
nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
@@ -1218,7 +1218,7 @@ bool nsDocShell::MaybeInitTiming() {
}
mTiming->NotifyNavigationStart(
mBrowsingContext->GetIsActive()
mBrowsingContext->IsActive()
? nsDOMNavigationTiming::DocShellState::eActive
: nsDOMNavigationTiming::DocShellState::eInactive);
@@ -2587,9 +2587,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
NS_SUCCEEDED(parentAsDocShell->GetAllowWindowControl(&value))) {
SetAllowWindowControl(value);
}
if (NS_SUCCEEDED(parentAsDocShell->GetIsActive(&value))) {
SetIsActive(value);
}
if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
value = false;
}
@@ -4776,28 +4773,21 @@ nsDocShell::GetIsOffScreenBrowser(bool* aIsOffScreen) {
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsActive(bool aIsActive) {
// Keep track ourselves.
// Changing the activeness on a discarded browsing context has no effect.
Unused << mBrowsingContext->SetIsActive(aIsActive);
// Tell the PresShell about it.
void nsDocShell::ActivenessMaybeChanged() {
bool isActive = mBrowsingContext->IsActive();
if (RefPtr<PresShell> presShell = GetPresShell()) {
presShell->SetIsActive(aIsActive);
presShell->SetIsActive(isActive);
}
// Tell the window about it
if (mScriptGlobal) {
mScriptGlobal->SetIsBackground(!aIsActive);
mScriptGlobal->SetIsBackground(!isActive);
if (RefPtr<Document> doc = mScriptGlobal->GetExtantDoc()) {
// Update orientation when the top-level browsing context becomes active.
if (aIsActive) {
if (mBrowsingContext->IsTop()) {
// We only care about the top-level browsing context.
uint16_t orientation = mBrowsingContext->GetOrientationLock();
ScreenOrientation::UpdateActiveOrientationLock(orientation);
}
if (isActive && mBrowsingContext->IsTop()) {
// We only care about the top-level browsing context.
uint16_t orientation = mBrowsingContext->GetOrientationLock();
ScreenOrientation::UpdateActiveOrientationLock(orientation);
}
doc->PostVisibilityUpdateEvent();
@@ -4813,37 +4803,18 @@ nsDocShell::SetIsActive(bool aIsActive) {
}
if (timing) {
timing->NotifyDocShellStateChanged(
aIsActive ? nsDOMNavigationTiming::DocShellState::eActive
: nsDOMNavigationTiming::DocShellState::eInactive);
}
// Recursively tell all of our children, but don't tell <iframe mozbrowser>
// children; they handle their state separately.
for (auto* child : mChildList.ForwardRange()) {
nsCOMPtr<nsIDocShell> docshell = do_QueryObject(child);
if (!docshell) {
continue;
}
docshell->SetIsActive(aIsActive);
isActive ? nsDOMNavigationTiming::DocShellState::eActive
: nsDOMNavigationTiming::DocShellState::eInactive);
}
// Restart or stop meta refresh timers if necessary
if (mDisableMetaRefreshWhenInactive) {
if (mBrowsingContext->GetIsActive()) {
if (isActive) {
ResumeRefreshURIs();
} else {
SuspendRefreshURIs();
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetIsActive(bool* aIsActive) {
*aIsActive = mBrowsingContext->GetIsActive();
return NS_OK;
}
NS_IMETHODIMP
@@ -5110,7 +5081,7 @@ nsDocShell::RefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, int32_t aDelay,
}
if (busyFlags & BUSY_FLAGS_BUSY ||
(!mBrowsingContext->GetIsActive() && mDisableMetaRefreshWhenInactive)) {
(!mBrowsingContext->IsActive() && mDisableMetaRefreshWhenInactive)) {
// We don't want to create the timer right now. Instead queue up the
// request and trigger the timer in EndPageLoad() or whenever we become
// active.
@@ -6451,7 +6422,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
// if there's a refresh header in the channel, this method
// will set it up for us.
if (mBrowsingContext->GetIsActive() || !mDisableMetaRefreshWhenInactive)
if (mBrowsingContext->IsActive() || !mDisableMetaRefreshWhenInactive)
RefreshURIFromQueue();
// Test whether this is the top frame or a subframe
@@ -9266,7 +9237,7 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
MOZ_ASSERT(mBrowsingContext->IsTop());
MOZ_ALWAYS_SUCCEEDS(
mBrowsingContext->SetOrientationLock(hal::eScreenOrientation_None));
if (mBrowsingContext->GetIsActive()) {
if (mBrowsingContext->IsActive()) {
ScreenOrientation::UpdateActiveOrientationLock(
hal::eScreenOrientation_None);
}
@@ -9939,7 +9910,7 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
mBrowsingContext->GetParentWindowContext();
MOZ_ASSERT(parentContext);
const bool popupBlocked = [&] {
const bool active = mBrowsingContext->GetIsActive();
const bool active = mBrowsingContext->IsActive();
// For same-origin-with-top windows, we grant a single free popup
// without user activation, see bug 1680721.