HTMLMediaElement::UpdateWakeLock() is responsible for creating and releasing audio wakelock.
HTMLVideoElement::UpdateWakeLock() is responsible for creating and releasing video wakelock.
In addition, each platform would handle system wakelock properly depending on different requests.
Differential Revision: https://phabricator.services.mozilla.com/D7214
Various places in dom/ use the pattern:
already_AddRefed<NodeInfo> ni = ...;
which is supposed to be disallowed by our static analysis code, but
isn't, for whatever reason. To fix our static analysis code, we need to
eliminate instances of the above pattern.
Unfortunately, eliminating this pattern requires restructuring how Nodes
are created. Most Node subclasses take `already_AddRefed<NodeInfo>&` in
their constructors, and a few accept `already_AddRefed<NodeInfo>&&`. We
need to enforce the latter pattern consistently, which requires changing
dozens of source files.
Everything that goes in a PLDHashtable (and its derivatives, like
nsTHashtable) needs to inherit from PLDHashEntryHdr. But through a lack
of enforcement, copy constructors for these derived classes didn't
explicitly invoke the copy constructor for PLDHashEntryHdr (and the
compiler didn't invoke the copy constructor for us). Instead,
PLDHashTable explicitly copied around the bits that the copy constructor
would have.
The current setup has two problems:
1) Derived classes should be using move construction, not copy
construction, since anything that's shuffling hash table keys/entries
around will be using move construction.
2) Derived classes should take responsibility for transferring bits of
superclass state around, and not rely on something else to handle that.
The second point is not a huge problem for PLDHashTable (PLDHashTable
only has to copy PLDHashEntryHdr's bits in a single place), but future
hash table implementations that might move entries around more
aggressively would have to insert compensation code all over the
place. Additionally, if moving entries is implemented via memcpy (which
is quite common), PLDHashTable copying around bits *again* is
inefficient.
Let's fix all these problems in one go, by:
1) Explicitly declaring the set of constructors that PLDHashEntryHdr
implements (and does not implement). In particular, the copy
constructor is deleted, so any derived classes that attempt to make
themselves copyable will be detected at compile time: the compiler
will complain that the superclass type is not copyable.
This change on its own will result in many compiler errors, so...
2) Change any derived classes to implement move constructors instead of
copy constructors. Note that some of these move constructors are,
strictly speaking, unnecessary, since the relevant classes are moved
via memcpy in nsTHashtable and its derivatives.
The reason we hit this assertion is that we still connected to Then() and waited for its result when the resolve or reject
runnable which dispatched by ThenValue can't be executed because the target thread had been shutdown.
Therefore, when XPCOM is going to shutdown, we should disconnect the Then() because it might not have a chance to execute
its resolve/reject method.
Differential Revision: https://phabricator.services.mozilla.com/D5893
The MozAutoplayMediaBlocked event should have its target set to the video
element, not the document.
Also, MozNoControlsBlockedVideo event has to initialized from the CustomEvent
constructor of the right window for the XBL binding to access it. I don't know
when it stopped working.
Test is added to ensure the entire UI won't break.
Differential Revision: https://phabricator.services.mozilla.com/D5801
"blocked" event is used for testing.
"MozAutoplayMediaBlocked" event is used for changing the control UI on Fennec.
Differential Revision: https://phabricator.services.mozilla.com/D4267
Since we don't block media without audio track anymore, the original telemetry scalar becomes useless.
We need to change its meaning in order to know the number of allowed autoplay without audio track.
Differential Revision: https://phabricator.services.mozilla.com/D3673
Add two telemetry scarlar,
"MEDIA_BLOCKED_NO_METADATA" records how many media which was blocked because it hadn't loaded metadata yet.
"MEDIA_BLOCKED_NO_METADATA_ENDUP_NO_AUDIO_TRACK" records how many media which was blocked because it hadn't loaded metadata and ended up for being no audio track.
By collecting those data, we can know the proportion of media which should be autoplay but was blocked because of lacking metadata.
Differential Revision: https://phabricator.services.mozilla.com/D3671
The DOM elements within the UA Widget Shadow DOM should have its reflectors in
the UA Widget Scope. This is done by calling nsINode::IsInUAWidget() which
would check its containing shadow and its UA Widget bit.
To prevent JS access of the DOM element before it is in the
UA Widget Shadom DOM tree, various DOM methods are set to inaccessible to
UA Widget script. It would need to use the two special methods in ShadowRoot
instead to insert the DOM directly into the shadow tree.
MozReview-Commit-ID: Jz9iCaVIoij
This prevents XBL binding from being attached, and create the Shadow Root to
host controls to be created by the script.
Shadow Root and the JS controls are lazily constructed when the controls
attribute is set.
Set nsVideoFrame as dynamic-leaf so it will ignore content child frames when
the controls are XBL anonymous content, and handles child frames from controls
in the Shadow DOM. The content nodes are still ignored since there is no
<slot>s in our Shadow DOM.
MozReview-Commit-ID: 3hk41iMa07n
Use new telemetry histogram ID 'AUDIO_TRACK_SILENCE_PROPORTION' to know the proportion of
silent part in the whole audio track.
Differential Revision: https://phabricator.services.mozilla.com/D3066
Since sed on multiple lines ended up being such a pain and I didn't end up
writing a script for this because I didn't think it'd end up being so boring, I
may have made a couple cleanups here and there as well...
Differential Revision: https://phabricator.services.mozilla.com/D2887
This is used to count the potiential number of the blocked autoplay media element without audio track
even if user was enable autoplay.
It might happen on three cases,
1. play -> loadedmetadata
2. loadedmetadata -> play
3. loadedmetadata -> has 'autoplay' keyword
In first case we need to check whether the play invocation has been called, and check other other cases
before the media starts playing.
In addition, the scalar name isn't consist with other names is because of the 40 maximum limitation of
the ping name.
MozReview-Commit-ID: 6Qm6TD4ME8I
This is used to count the potiential number of the blocked autoplay media element without audio track
even if user was enable autoplay.
It might happen on three cases,
1. play -> loadedmetadata
2. loadedmetadata -> play
3. loadedmetadata -> has 'autoplay' keyword
In first case we need to check whether the play invocation has been called, and check other other cases
before the media starts playing.
In addition, the scalar name isn't consist with other names is because of the 40 maximum limitation of
the ping name.
MozReview-Commit-ID: 6Qm6TD4ME8I
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:
https://github.com/whatwg/html/issues/3617#issuecomment-398613484
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
Mostly automatic via sed. Only parts which I touched manually (apart from a
couple ones where I fixed indentation or which had mispelled arguments) are the
callers. I may have removed a couple redundant `virtual` keywords as well when
I started to do it manually, I can revert those if wanted.
Most of them are just removing the argument, but in Element.cpp I also added an
assertion for GetBindingParent when binding the ShadowRoot's kids (the binding
parent is set from the ShadowRoot constructor, and I don't think we bind a
shadow tree during unlink or what not which could cause a behavior difference).
Differential Revision: https://phabricator.services.mozilla.com/D2574
MozReview-Commit-ID: 2oIgatty2HU
In our autoplay shield-study, we want to collect the information which could tell us how many website
contains audible autoplay media, but there is no way to get this information on current API desigin.
Therefore, I would like to send a new notification when autoplay occurred.
The extension code could get the information by following way,
```
Services.obs.addObserver((subject, topic, data) => {
// DO SOMETHING
}, "AudibleAutoplayMediaOccurred");
```
MozReview-Commit-ID: 4bSYcxDZOGK
We'd like to add telemetry to help inform the decision as to how enabling
block autoplay will affect video playback in the wild.
Our data science team would also like some input to help them estimate the
rate at which our shield study would receive pings, and the telemetry
collected here will help them estimate that.
We'd like to collect the following, on a per session basis:
* Count of the number of top level content documents loaded, as denominator for
other stats collected here.
* Count of the number of top level content documents which contained (directly
or in a descendant document) playback of an audible media element.
* Count of the number of top level content documents which contained (directly
or in a descendant document) a muted media element that was paused by the
autoplay policy because it tried to unmute and it wasn't allowed to autoplay
audibly.
* Count of the total number of audible autoplay videos that would have not been
allowed to play if block autoplay was enabled. We'd either prompt for
permission on these videos, or block outright depending on user's settings.
* Count of the total number of audible autoplay videos that would have been
allowed to play if block autoplay was enabled.
MozReview-Commit-ID: vHWJPyqHjT
Everything that goes in a PLDHashtable (and its derivatives, like
nsTHashtable) needs to inherit from PLDHashEntryHdr. But through a lack
of enforcement, copy constructors for these derived classes didn't
explicitly invoke the copy constructor for PLDHashEntryHdr (and the
compiler didn't invoke the copy constructor for us). Instead,
PLDHashTable explicitly copied around the bits that the copy constructor
would have.
The current setup has two problems:
1) Derived classes should be using move construction, not copy
construction, since anything that's shuffling hash table keys/entries
around will be using move construction.
2) Derived classes should take responsibility for transferring bits of
superclass state around, and not rely on something else to handle
that.
The second point is not a huge problem for PLDHashTable (PLDHashTable
only has to copy PLDHashEntryHdr's bits in a single place), but future
hash table implementations that might move entries around more
aggressively would have to insert compensation code all over the place.
Additionally, if moving entries is implemented via memcpy (which is
quite common), PLDHashTable copying around bits *again* is inefficient.
Let's fix all these problems in one go, by:
1) Explicitly declaring the set of constructors that PLDHashEntryHdr
implements (and does not implement). In particular, the copy
constructor is deleted, so any derived classes that attempt to make
themselves copyable will be detected at compile time: the compiler
will complain that the superclass type is not copyable.
This change on its own will result in many compiler errors, so...
2) Change any derived classes to implement move constructors instead
of copy constructors. Note that some of these move constructors are,
strictly speaking, unnecessary, since the relevant classes are moved
via memcpy in nsTHashtable and its derivatives.
We can start playing while we're awaiting a response to an autoplay-media
permission prompt, for example if the user clicks on a play button. In such
cases, it doesn't make sense to keep the autoplay permission request promise
connected in HTMLMediaElement, as since we're playing we'll be resolving the
play() promises and thus we won't be taking action on the autoplay request
promise's result. So we should just disconnect the autoplay permission request
promise if it's connected when we start playing.
MozReview-Commit-ID: 1aiCLXV7Ja9
The front end code can't always guarantee to give us an allow/cancel response
to a permission request. In particular in these cases:
* if we close a tab while showing a doorhanger, or
* if we navigate a tab while showing a doorhanger, or
* if the permission prompt requested in a background tab and never shown.
Handling all of these cases is problematic; we don't get events for all of
these where it's easy and cheap to determine that we should cancel the
permission request.
Canceling the permission request is important in the autoplay-media permission
request case as there's objects waiting on the resolution of the permission
request, and they leak in ASan builds while running chrome tests if the Gecko
size of the permission request doesn't get a notification telling it to stop
waiting.
But we can however rely on the doorhanger code to drop its reference to the
nsIContentPermissionRequest object that we pass to it when the doorhanger goes
away. So we can cancel the permission request in our
nsIContentPermissionRequest's implementation's destructor in order to easily
catch all the above cases.
In order to do that, we need to split AutoplayRequest into two; one part being
the implementation of nsIContentPermissionRequest (AutoplayPermissionRequest),
and the other part being the code to own the PromiseHolder and manage the
permission request (AutoplayPermissionManager).
AutoplayPermissionRequest keeps a weak reference to AutoplayPermissionManager,
so that it can tell the AutoplayPermissionManager to reject the request promise
when it's destroyed.
This fixes the ASan leak for which I got backed out from earlier in this bug,
and also fixes the cases above.
MozReview-Commit-ID: KoVkgIqDleW
Test that a video which tries to autoplay via either a play() call or via
an autoplay attribute:
* Plays when it has a pre-existing "allow" autoplay-media permission.
* Is blocked when it has a pre-existing "block" autoplay-media permission.
* Plays when it doesn't have a pre-existing autoplay-media permission and
"allow" is pressed on the door hanger.
* Is blocked when it doesn't have a pre-existing autoplay-media permission and
"block" is pressed on the door hanger.
MozReview-Commit-ID: CpftV6RQbtU
When autoplay is requested by setting the "autoplay" attribute, we should
check whether autoplay is allowed in HTMLMediaElement::CheckAutoplayDataReady()
and if not we should prompt for user consent.
This ensures that <video ... autoplay/> will prompt for consent when used on
a page without a pre-existing allow/block permission.
MozReview-Commit-ID: 77pJR2Ybn2i
It's possible that if the HTMLMediaElement is loading while we're loading a new
document into a docshell, that the HTMLMediaElement can reach readyState
HAVE_FUTURE_DATA just after its OwnerDoc is removed from the docshell. If the
HTMLMediaElement wasn't paused, then it may start playing due to the readyState
change in HTMLMediaElement::ChangeReadyState().
For years we've had hard to reproduce issues where media started playing after
we've closed the tab; I bet this was the cause!
When we detect that the document has been removed from its DocShell,
HTMLMediaElement::NotifyOwnerDocumentActivityChanged() is called, and that
suspends the MediaDecoder just in case we need to resurrect the media element,
for example if the tab comes out of the BF cache. When we suspend we set
mPausedForInactiveDocumentOrChannel=true, and all other calls to
MediaDecoder::Play() are guarded by checks on
mPausedForInactiveDocumentOrChannel.
So we should also guard the MediaDecoder::Play() call in ChangeReadyState()
with a check on mPausedForInactiveDocumentOrChannel too.
MozReview-Commit-ID: GfmZasT9jdr