mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Backed out 3 changesets (bug 1415478) for frequently asserting in own test test_autoplay_policy.html at MediaDecoderStateMachine.cpp:989. r=backout
Backed out changeset 6ba103fe1caf (bug 1415478) Backed out changeset df6721a3584f (bug 1415478) Backed out changeset 8a802839959b (bug 1415478) --HG-- extra : rebase_source : be4296b1b36005195897de5544941b58895de661
This commit is contained in:
parent
14aa323f6f
commit
706ac3aea0
@ -670,6 +670,11 @@ void HTMLMediaElement::ReportLoadError(const char* aMsg,
|
||||
aParamCount);
|
||||
}
|
||||
|
||||
static bool IsAutoplayEnabled()
|
||||
{
|
||||
return Preferences::GetBool("media.autoplay.enabled");
|
||||
}
|
||||
|
||||
class HTMLMediaElement::AudioChannelAgentCallback final :
|
||||
public nsIAudioChannelAgentCallback
|
||||
{
|
||||
@ -2434,8 +2439,7 @@ void HTMLMediaElement::UpdatePreloadAction()
|
||||
PreloadAction nextAction = PRELOAD_UNDEFINED;
|
||||
// If autoplay is set, or we're playing, we should always preload data,
|
||||
// as we'll need it to play.
|
||||
if ((AutoplayPolicy::IsMediaElementAllowedToPlay(WrapNotNull(this)) &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) ||
|
||||
if ((IsAutoplayEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) ||
|
||||
!mPaused)
|
||||
{
|
||||
nextAction = HTMLMediaElement::PRELOAD_ENOUGH;
|
||||
@ -6186,7 +6190,7 @@ bool HTMLMediaElement::CanActivateAutoplay()
|
||||
// download is controlled by the script and there is no way to evaluate
|
||||
// MediaDecoder::CanPlayThrough().
|
||||
|
||||
if (!AutoplayPolicy::IsMediaElementAllowedToPlay(WrapNotNull(this))) {
|
||||
if (!IsAutoplayEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "AutoplayPolicy.h"
|
||||
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#include "nsIDocument.h"
|
||||
@ -17,6 +18,10 @@ namespace dom {
|
||||
/* static */ bool
|
||||
AutoplayPolicy::IsDocumentAllowedToPlay(nsIDocument* aDoc)
|
||||
{
|
||||
if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return aDoc ? aDoc->HasBeenUserActivated() : false;
|
||||
}
|
||||
|
||||
@ -27,28 +32,16 @@ AutoplayPolicy::IsMediaElementAllowedToPlay(NotNull<HTMLMediaElement*> aElement)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Preferences::GetBool("media.autoplay.enabled.user-gestures-needed")) {
|
||||
return AutoplayPolicy::IsDocumentAllowedToPlay(aElement->OwnerDoc());
|
||||
}
|
||||
|
||||
// TODO : this old way would be removed when user-gestures-needed becomes
|
||||
// as a default option to block autoplay.
|
||||
if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed", false)) {
|
||||
// If user triggers load() or seek() before play(), we would also allow the
|
||||
// following play().
|
||||
return aElement->GetAndClearHasUserInteractedLoadOrSeek() ||
|
||||
EventStateManager::IsHandlingUserInput();
|
||||
}
|
||||
|
||||
// Muted content
|
||||
if (aElement->Volume() == 0.0 || aElement->Muted()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Media has already loaded metadata and doesn't contain audio track
|
||||
if (aElement->IsVideo() &&
|
||||
aElement->ReadyState() >= nsIDOMHTMLMediaElement::HAVE_METADATA &&
|
||||
!aElement->HasAudio()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return AutoplayPolicy::IsDocumentAllowedToPlay(aElement->OwnerDoc());
|
||||
// If user triggers load() or seek() before play(), we would also allow the
|
||||
// following play().
|
||||
return aElement->GetAndClearHasUserInteractedLoadOrSeek() ||
|
||||
EventStateManager::IsHandlingUserInput();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -25,14 +25,13 @@ class HTMLMediaElement;
|
||||
* conditions is true.
|
||||
* 1) Owner document is activated by user gestures
|
||||
* We restrict user gestures to "mouse click", "keyboard press" and "touch".
|
||||
* 2) Muted media content or video without audio content
|
||||
* 2) TODO...
|
||||
*/
|
||||
class AutoplayPolicy
|
||||
{
|
||||
public:
|
||||
static bool IsMediaElementAllowedToPlay(NotNull<HTMLMediaElement*> aElement);
|
||||
private:
|
||||
static bool IsDocumentAllowedToPlay(nsIDocument* aDoc);
|
||||
static bool IsMediaElementAllowedToPlay(NotNull<HTMLMediaElement*> aElement);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -679,7 +679,6 @@ skip-if = true # bug 475110 - disabled since we don't play Wave files standalone
|
||||
[test_autoplay.html]
|
||||
[test_autoplay_contentEditable.html]
|
||||
skip-if = android_version == '15' || android_version == '17' || android_version == '22' # android(bug 1232305, bug 1232318, bug 1372457)
|
||||
[test_autoplay_policy.html]
|
||||
[test_buffered.html]
|
||||
skip-if = android_version == '15' || android_version == '22' # bug 1308388, android(bug 1232305)
|
||||
[test_bug448534.html]
|
||||
|
@ -1,182 +0,0 @@
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Autoplay policy test</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
||||
<script>
|
||||
|
||||
let manager = new MediaTestManager;
|
||||
|
||||
gTestPrefs.push(["media.autoplay.enabled", false],
|
||||
["media.autoplay.enabled.user-gestures-needed", true]);
|
||||
|
||||
window.info = function(msg, token) {
|
||||
SimpleTest.info(msg + ", token=" + token);
|
||||
}
|
||||
|
||||
window.is = function(valA, valB, msg, token) {
|
||||
SimpleTest.is(valA, valB, msg + ", token=" + token);
|
||||
}
|
||||
|
||||
window.ok = function(val, msg, token) {
|
||||
SimpleTest.ok(val, msg + ", token=" + token);
|
||||
}
|
||||
|
||||
/**
|
||||
* test files and paremeters
|
||||
*/
|
||||
var autoplayTests = [
|
||||
/* video */
|
||||
{ name:"gizmo.mp4", type:"video/mp4", hasAudio:true },
|
||||
{ name:"gizmo-noaudio.mp4", type:"video/mp4", hasAudio:false },
|
||||
{ name:"gizmo.webm", type:'video/webm', hasAudio:true },
|
||||
{ name:"gizmo-noaudio.webm", type:'video/webm', hasAudio:false },
|
||||
/* audio */
|
||||
{ name:"small-shot.ogg", type:"audio/ogg", hasAudio:true },
|
||||
{ name:"small-shot.m4a", type:"audio/mp4", hasAudio:true },
|
||||
{ name:"small-shot.mp3", type:"audio/mpeg", hasAudio:true },
|
||||
{ name:"small-shot.flac", type:"audio/flac", hasAudio:true }
|
||||
];
|
||||
|
||||
var autoplayParams = [
|
||||
{ volume: 1.0, muted: false, preload: "none" },
|
||||
{ volume: 1.0, muted: false, preload: "metadata" },
|
||||
{ volume: 0.0, muted: false, preload: "none" },
|
||||
{ volume: 0.0, muted: false, preload: "metadata" },
|
||||
{ volume: 1.0, muted: true, preload: "none"},
|
||||
{ volume: 1.0, muted: true, preload: "metadata" },
|
||||
{ volume: 0.0, muted: true, preload: "none"},
|
||||
{ volume: 0.0, muted: true, preload: "metadata" }
|
||||
];
|
||||
|
||||
function createTestArray()
|
||||
{
|
||||
var tests = [];
|
||||
for (let testIdx = 0; testIdx < autoplayTests.length; testIdx++) {
|
||||
for (let paramIdx = 0; paramIdx < autoplayParams.length; paramIdx++) {
|
||||
let test = autoplayTests[testIdx];
|
||||
let param = autoplayParams[paramIdx];
|
||||
let obj = new Object;
|
||||
obj.name = test.name;
|
||||
obj.type = test.type;
|
||||
obj.hasAudio = test.hasAudio;
|
||||
obj.volume = param.volume;
|
||||
obj.muted = param.muted;
|
||||
obj.preload = param.preload;
|
||||
tests.push(obj);
|
||||
}
|
||||
}
|
||||
return tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main test function for different autoplay cases without user interaction.
|
||||
*
|
||||
* When the pref "media.autoplay.enabled" is false and the pref
|
||||
* "media.autoplay.enabled.user-gestures-needed" is true, we would only allow
|
||||
* audible media to autoplay after the website has been activated by specific
|
||||
* user gestures. However, non-audible media won't be restricted.
|
||||
*
|
||||
* Audible means the volume is not zero, or muted is not true for the video with
|
||||
* audio track. For media without loading metadata, we can't know whether it has
|
||||
* audio track or not, so we would also regard it as audible media.
|
||||
*
|
||||
* Non-audible means the volume is zero, the muted is true, or the video without
|
||||
* audio track.
|
||||
*/
|
||||
async function runTest(test, token) {
|
||||
manager.started(token);
|
||||
|
||||
await testPlay(test, token);
|
||||
await testAutoplayKeyword(test, token);
|
||||
|
||||
manager.finished(token);
|
||||
}
|
||||
|
||||
manager.runTests(createTestArray(), runTest);
|
||||
|
||||
/**
|
||||
* Different test scenarios
|
||||
*/
|
||||
async function testPlay(test, token) {
|
||||
info("### start testPlay", token);
|
||||
info(`volume=${test.volume}, muted=${test.muted}, ` +
|
||||
`preload=${test.preload}, hasAudio=${test.hasAudio}`, token);
|
||||
|
||||
let element = document.createElement(getMajorMimeType(test.type));
|
||||
element.preload = test.preload;
|
||||
element.volume = test.volume;
|
||||
element.muted = test.muted;
|
||||
element.src = test.name;
|
||||
document.body.appendChild(element);
|
||||
|
||||
let preLoadNone = test.preload == "none";
|
||||
if (!preLoadNone) {
|
||||
info("### wait for loading metadata", token);
|
||||
await once(element, "loadedmetadata");
|
||||
}
|
||||
|
||||
let isAudible = (preLoadNone || test.hasAudio) &&
|
||||
test.volume != 0.0 &&
|
||||
!test.muted;
|
||||
let state = isAudible? "audible" : "non-audible";
|
||||
info(`### calling play() for ${state} media`, token);
|
||||
let promise = element.play();
|
||||
if (isAudible) {
|
||||
await promise.catch(function(error) {
|
||||
ok(element.paused, `${state} media fail to start via play()`, token);
|
||||
is(error.name, "NotAllowedError", "rejected play promise", token);
|
||||
});
|
||||
} else {
|
||||
// since we just want to check the value of 'paused', we don't need to wait
|
||||
// resolved play promise. (it's equal to wait for 'playing' event)
|
||||
await once(element, "play");
|
||||
ok(!element.paused, `${state} media start via play()`, token);
|
||||
}
|
||||
|
||||
removeNodeAndSource(element);
|
||||
}
|
||||
|
||||
async function testAutoplayKeyword(test, token) {
|
||||
info("### start testAutoplayKeyword", token);
|
||||
info(`volume=${test.volume}, muted=${test.muted}, ` +
|
||||
`preload=${test.preload}, hasAudio=${test.hasAudio}`, token);
|
||||
|
||||
let element = document.createElement(getMajorMimeType(test.type));
|
||||
element.autoplay = true;
|
||||
element.preload = test.preload;
|
||||
element.volume = test.volume;
|
||||
element.muted = test.muted;
|
||||
element.src = test.name;
|
||||
document.body.appendChild(element);
|
||||
|
||||
let preLoadNone = test.preload == "none";
|
||||
let isAudible = (preLoadNone || test.hasAudio) &&
|
||||
test.volume != 0.0 &&
|
||||
!test.muted;
|
||||
let state = isAudible? "audible" : "non-audible";
|
||||
info(`### wait to autoplay for ${state} media`, token);
|
||||
if (isAudible) {
|
||||
if (preLoadNone) {
|
||||
await once(element, "suspend");
|
||||
is(element.readyState, 0 /* HAVE_NOTHING */, "media won't start loading", token);
|
||||
} else {
|
||||
await once(element, "canplay");
|
||||
}
|
||||
ok(element.paused, `can not start with 'autoplay' keyword for ${state} media`, token);
|
||||
} else {
|
||||
await once(element, "play");
|
||||
ok(!element.paused, `start with 'autoplay' keyword for ${state} media`, token);
|
||||
}
|
||||
|
||||
removeNodeAndSource(element);
|
||||
}
|
||||
|
||||
</script>
|
@ -593,13 +593,9 @@ pref("media.recorder.video.frame_drops", true);
|
||||
|
||||
// Whether to autostart a media element with an |autoplay| attribute
|
||||
pref("media.autoplay.enabled", true);
|
||||
|
||||
// If "media.autoplay.enabled" is false, and this pref is true, then audible media
|
||||
// would only be allowed to autoplay after website has been activated by specific
|
||||
// user gestures, but the non-audible media won't be restricted.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// If "media.autoplay.enabled" is off, and this pref is on, then autoplay could
|
||||
// be executed after website has been activated by specific user gestures.
|
||||
pref("media.autoplay.enabled.user-gestures-needed", false);
|
||||
#endif
|
||||
|
||||
// The default number of decoded video frames that are enqueued in
|
||||
// MediaDecoderReader's mVideoQueue.
|
||||
|
Loading…
Reference in New Issue
Block a user