Skip to content

Commit

Permalink
Bug 1478208 - Implement HTMLMediaElement.allowedToPlay. r=alwu,bz
Browse files Browse the repository at this point in the history
Various web authors have expressed desire to know in advance whether autoplay
will work.

They want this in order to avoid paying the price for downloading media that
won't play. Or they want to take other action such as showing a poster image
instead.

This is of particular interest to Firefox, as we're planning on showing a
prompt to ask the user whether they would like a site to play. If sites want to
determine whether they can autoplay but avoid the prompt showing, they won't be
able to just call play() in Firefox and see whether it works, as that would
likely show the prompt if the user doesn't already have a stored permission.

We've been working out a spec here:
whatwg/html#3617 (comment)

This implements what is the consensus to date there;
HTMLMediaElement.allowedToPlay, which returns true when a play() call would not
be blocked with NotAllowedError by autoplay blocking policies.

MozReview-Commit-ID: AkBu0G7uCJ0

UltraBlame original commit: f5f55e363d318effdfd504061c50f87e06301c6f
  • Loading branch information
marco-c committed Oct 3, 2019
1 parent 856ef4e commit ad41f63
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 5 deletions.
6 changes: 6 additions & 0 deletions dom/html/HTMLMediaElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2522,6 +2522,12 @@ HTMLMediaElement::ResumeLoad(PreloadAction aAction)
}
}

bool
HTMLMediaElement::AllowedToPlay() const
{
return AutoplayPolicy::IsAllowedToPlay(*this) == nsIAutoplay::ALLOWED;
}

void
HTMLMediaElement::UpdatePreloadAction()
{
Expand Down
6 changes: 6 additions & 0 deletions dom/html/HTMLMediaElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,12 @@ class HTMLMediaElement : public nsGenericHTMLElement,
mIsCasting = aShow;
}





bool AllowedToPlay() const;

already_AddRefed<MediaSource> GetMozMediaSourceObject() const;


Expand Down
6 changes: 3 additions & 3 deletions dom/media/test/AutoplayTestUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ function playAndPostResult(muted, parent_window) {
element.src = "short.mp4";
element.id = "video";
document.body.appendChild(element);

let allowedToPlay = element.allowedToPlay;
element.play().then(
() => {
parent_window.postMessage({played: true}, "*");
parent_window.postMessage({played: true, allowedToPlay}, "*");
},
() => {
parent_window.postMessage({played: false}, "*");
parent_window.postMessage({played: false, allowedToPlay}, "*");
}
);
}
Expand Down
3 changes: 2 additions & 1 deletion dom/media/test/test_autoplay_policy_activation.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@
await once(child, "load");
child.postMessage(test_case, window.origin);
let result = await nextWindowMessage();
SimpleTest.is(result.data.played, test_case.should_play, test_case.name);
SimpleTest.is(result.data.allowedToPlay, test_case.should_play, "allowed - " + test_case.name);
SimpleTest.is(result.data.played, test_case.should_play, "played - " + test_case.name);
child.close();
}
SimpleTest.finish();
Expand Down
3 changes: 2 additions & 1 deletion dom/media/test/test_autoplay_policy_permission.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
child.postMessage("play-audible", testCase.origin);
// Wait for the window to tell us whether it could play video.
let result = await nextWindowMessage();
is(result.data.played, testCase.shouldPlay, testCase.message);
is(result.data.allowedToPlay, testCase.shouldPlay, "allowedToPlay - " + testCase.message);
is(result.data.played, testCase.shouldPlay, "played - " + testCase.message);
child.close();
}

Expand Down
10 changes: 10 additions & 0 deletions dom/webidl/HTMLMediaElement.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,13 @@ partial interface HTMLMediaElement {
[Pref="media.test.video-suspend"]
boolean hasSuspendTaint();
};

/*
* API that exposes whether a call to HTMLMediaElement.play() would be
* blocked by autoplay policies; whether the promise returned by play()
* would be rejected with NotAllowedError.
*/
partial interface HTMLMediaElement {
[Pref="media.allowed-to-play.enabled"]
readonly attribute boolean allowedToPlay;
};
8 changes: 8 additions & 0 deletions modules/libpref/init/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,14 @@ pref("media.autoplay.enabled.user-gestures-needed", false);



#ifdef NIGHTLY_BUILD
pref("media.allowed-to-play.enabled", true);
#else
pref("media.allowed-to-play.enabled", false);
#endif



pref("media.video-queue.default-size", 10);


Expand Down
1 change: 1 addition & 0 deletions testing/profiles/common/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ user_pref("media.autoplay.default", 0);
user_pref("media.autoplay.enabled.user-gestures-needed", true);
user_pref("media.autoplay.ask-permission", false);
user_pref("media.autoplay.block-webaudio", false);
user_pref("media.allowed-to-play.enabled", true);

0 comments on commit ad41f63

Please sign in to comment.