Bug 1662805 - Don't freeze a tab when it's playing back audio. r=geckoview-reviewers,agi

Differential Revision: https://phabricator.services.mozilla.com/D89390
This commit is contained in:
Paul Adenot 2020-09-15 09:00:05 +00:00
parent 29b9613021
commit 6abe53e8ff
2 changed files with 29 additions and 1 deletions

View File

@ -32,6 +32,8 @@ class GeckoViewContent extends GeckoViewModule {
"GeckoView:UpdateInitData",
"GeckoView:ZoomToInput",
]);
this.activeValueWhilePlayingAudio = null;
}
onEnable() {
@ -56,6 +58,7 @@ class GeckoViewContent extends GeckoViewModule {
this.window.addEventListener("DOMWindowClose", this);
this.window.addEventListener("pagetitlechanged", this);
this.window.addEventListener("DOMAudioPlaybackStopped", this);
Services.obs.addObserver(this, "oop-frameloader-crashed");
Services.obs.addObserver(this, "ipc:content-shutdown");
@ -80,6 +83,7 @@ class GeckoViewContent extends GeckoViewModule {
this.window.removeEventListener("DOMWindowClose", this);
this.window.removeEventListener("pagetitlechanged", this);
this.window.removeEventListener("DOMAudioPlaybackStopped", this);
Services.obs.removeObserver(this, "oop-frameloader-crashed");
Services.obs.removeObserver(this, "ipc:content-shutdown");
@ -149,7 +153,14 @@ class GeckoViewContent extends GeckoViewModule {
this.sendToAllChildren(aEvent, aData);
break;
case "GeckoView:SetActive":
this.browser.docShellIsActive = !!aData.active;
// When audio is playing, don't change the active status of the
// docshell. Instead, store the value that would have been set, and
// change the status of the docshell when audio playback stops.
if (this.browser.audioPlaying) {
this.activeValueWhilePlayingAudio = !!aData.active;
} else {
this.browser.docShellIsActive = !!aData.active;
}
break;
case "GeckoView:SetFocused":
if (aData.focused) {
@ -198,6 +209,15 @@ class GeckoViewContent extends GeckoViewModule {
title: this.browser.contentTitle,
});
break;
case "DOMAudioPlaybackStopped":
// Audio playback has stopped. If a SetActive call was delayed because
// audio was being backed back, it's now time to reevaluate whether the
// docshell should still be active.
if (this.activeValueWhilePlayingAudio !== null) {
this.browser.docShellIsActive = this.activeValueWhilePlayingAudio;
this.activeValueWhilePlayingAudio = null;
}
break;
case "DOMWindowClose":
// We need this because we want to allow the app
// to close the window itself. If we don't preventDefault()

View File

@ -251,6 +251,8 @@
this._audioMuted = false;
this._audioPlaying = false;
this._hasAnyPlayingMediaBeenBlocked = false;
this._unselectedTabHoverMessageListenerCount = 0;
@ -749,6 +751,10 @@
return this._audioMuted;
}
get audioPlaying() {
return this._audioPlaying;
}
get shouldHandleUnselectedTabHover() {
return this._unselectedTabHoverMessageListenerCount > 0;
}
@ -953,12 +959,14 @@
if (this._audioMuted) {
return;
}
this._audioPlaying = true;
let event = document.createEvent("Events");
event.initEvent("DOMAudioPlaybackStarted", true, false);
this.dispatchEvent(event);
}
audioPlaybackStopped() {
this._audioPlaying = false;
let event = document.createEvent("Events");
event.initEvent("DOMAudioPlaybackStopped", true, false);
this.dispatchEvent(event);