зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1572798 - Should call MaybeActiveMediaComponents from SetScriptGlobalObject if becoming visible. r=bzbarsky,farre
Windows start blocking media by default (see the media.block-autoplay-until-in-foreground pref). If the document becomes visible from GetScriptHandlingObject(), we hand-rolled our own UpdateVisibilityState and didn't call MaybeActiveMediaComponents (which unblocks media playback). It couldn't call it there before since given content docshells used start as active, but now that they don't we can do that and fix the bug. Differential Revision: https://phabricator.services.mozilla.com/D41438
This commit is contained in:
Родитель
4a8ec774c7
Коммит
80755ed700
|
@ -7250,8 +7250,7 @@ void Document::SetScriptGlobalObject(
|
|||
// still test false at this point and no state change will happen) or we're
|
||||
// doing the initial document load and don't want to fire the event for this
|
||||
// change.
|
||||
dom::VisibilityState oldState = mVisibilityState;
|
||||
mVisibilityState = ComputeVisibilityState();
|
||||
//
|
||||
// When the visibility is changed, notify it to observers.
|
||||
// Some observers need the notification, for example HTMLMediaElement uses
|
||||
// it to update internal media resource allocation.
|
||||
|
@ -7264,9 +7263,7 @@ void Document::SetScriptGlobalObject(
|
|||
// not yet necessary. But soon after Document::SetScriptGlobalObject()
|
||||
// call, the document becomes not hidden. At the time, MediaDecoder needs
|
||||
// to know it and needs to start updating decoding.
|
||||
if (oldState != mVisibilityState) {
|
||||
EnumerateActivityObservers(NotifyActivityChanged);
|
||||
}
|
||||
UpdateVisibilityState(DispatchVisibilityChange::No);
|
||||
|
||||
// The global in the template contents owner document should be the same.
|
||||
if (mTemplateContentsOwner && mTemplateContentsOwner != this) {
|
||||
|
@ -14879,13 +14876,15 @@ void Document::UnlockPointer(Document* aDoc) {
|
|||
asyncDispatcher->RunDOMEventWhenSafe();
|
||||
}
|
||||
|
||||
void Document::UpdateVisibilityState() {
|
||||
void Document::UpdateVisibilityState(DispatchVisibilityChange aDispatchEvent) {
|
||||
dom::VisibilityState oldState = mVisibilityState;
|
||||
mVisibilityState = ComputeVisibilityState();
|
||||
if (oldState != mVisibilityState) {
|
||||
nsContentUtils::DispatchTrustedEvent(this, ToSupports(this),
|
||||
u"visibilitychange"_ns,
|
||||
CanBubble::eYes, Cancelable::eNo);
|
||||
if (aDispatchEvent == DispatchVisibilityChange::Yes) {
|
||||
nsContentUtils::DispatchTrustedEvent(this, ToSupports(this),
|
||||
u"visibilitychange"_ns,
|
||||
CanBubble::eYes, Cancelable::eNo);
|
||||
}
|
||||
EnumerateActivityObservers(NotifyActivityChanged);
|
||||
}
|
||||
|
||||
|
@ -14911,9 +14910,9 @@ VisibilityState Document::ComputeVisibilityState() const {
|
|||
}
|
||||
|
||||
void Document::PostVisibilityUpdateEvent() {
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NewRunnableMethod("Document::UpdateVisibilityState", this,
|
||||
&Document::UpdateVisibilityState);
|
||||
nsCOMPtr<nsIRunnable> event = NewRunnableMethod<DispatchVisibilityChange>(
|
||||
"Document::UpdateVisibilityState", this, &Document::UpdateVisibilityState,
|
||||
DispatchVisibilityChange::Yes);
|
||||
Dispatch(TaskCategory::Other, event.forget());
|
||||
}
|
||||
|
||||
|
|
|
@ -3205,7 +3205,11 @@ class Document : public nsINode,
|
|||
|
||||
// This method may fire a DOM event; if it does so it will happen
|
||||
// synchronously.
|
||||
void UpdateVisibilityState();
|
||||
//
|
||||
// Whether the event fires is controlled by the argument.
|
||||
enum class DispatchVisibilityChange { No, Yes };
|
||||
void UpdateVisibilityState(
|
||||
DispatchVisibilityChange = DispatchVisibilityChange::Yes);
|
||||
|
||||
// Posts an event to call UpdateVisibilityState.
|
||||
void PostVisibilityUpdateEvent();
|
||||
|
|
|
@ -47,6 +47,10 @@ skip-if = (os == "win" && processor == "aarch64") || (os == "mac") || (os == "li
|
|||
[browser_delay_autoplay_webAudio.js]
|
||||
tags = audiochannel
|
||||
skip-if = (os == "win" && processor == "aarch64") # aarch64 due to 1536573
|
||||
[browser_bug1572798.js]
|
||||
tags = audiochannel
|
||||
skip-if = (os == "win" && processor == "aarch64") # aarch64 due to 1536573
|
||||
support-files = file_document_open_audio.html
|
||||
[browser_bug1170531.js]
|
||||
skip-if =
|
||||
os == "linux" && !debug && !ccov # Bug 1647973
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
add_task(async function test_bug_1572798() {
|
||||
let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
|
||||
BrowserTestUtils.loadURI(
|
||||
tab.linkedBrowser,
|
||||
"https://example.com/browser/toolkit/content/tests/browser/file_document_open_audio.html"
|
||||
);
|
||||
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
let windowLoaded = BrowserTestUtils.waitForNewWindow();
|
||||
info("- clicking button to spawn a new window -");
|
||||
await ContentTask.spawn(tab.linkedBrowser, null, function() {
|
||||
content.document.querySelector("button").click();
|
||||
});
|
||||
info("- waiting for the new window -");
|
||||
let newWin = await windowLoaded;
|
||||
info("- checking that the new window plays the audio -");
|
||||
let documentOpenedBrowser = newWin.gBrowser.selectedBrowser;
|
||||
await ContentTask.spawn(documentOpenedBrowser, null, async function() {
|
||||
try {
|
||||
await content.document.querySelector("audio").play();
|
||||
ok(true, "Could play the audio");
|
||||
} catch (e) {
|
||||
ok(false, "Rejected audio promise" + e);
|
||||
}
|
||||
});
|
||||
|
||||
info("- Cleaning up -");
|
||||
await BrowserTestUtils.closeWindow(newWin);
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
<!doctype html>
|
||||
<title>Test for bug 1572798</title>
|
||||
<script>
|
||||
function openVideo() {
|
||||
var w = window.open('', '', 'width = 640, height = 480, scrollbars=yes, menubar=no, toolbar=no, resizable=yes');
|
||||
w.document.open();
|
||||
w.document.write('<!DOCTYPE html><title>test popup</title><audio controls src="audio.ogg"></audio>');
|
||||
w.document.close();
|
||||
}
|
||||
</script>
|
||||
<button onclick="openVideo()">Open video</button>
|
Загрузка…
Ссылка в новой задаче