Title: [271531] trunk
Revision
271531
Author
jer.no...@apple.com
Date
2021-01-15 12:53:32 -0800 (Fri, 15 Jan 2021)

Log Message

Playback fails at marketwatch.com
https://bugs.webkit.org/show_bug.cgi?id=220646
<rdar://72950166>

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

Test: media/media-play-promise-reject-play-notallowed-audio.html

When audio playback is blocked by settings, the HTMLMediaElement must load its source
media's metadata in order to determine whether the media should be allowed to play without a
user gesture. If a play promise is pending, the expectation is that those promises will
reject with a NotAllowedError to indicate that a user gesture is needed. However, by calling
pauseInternal() to block (possibly) existing playback, this causes those promises to be
rejected with an AbortError, as if the pause() method had been called. Call
scheduleRejectPendingPlayPromises() with NotAllowedError to ensure the correct error is used
to reject.

Drive-by fix: no reason to dispatch and call rejectPendingPlayPromises() or
resolvePendingPlayPromises() if there are no promises to reject or resolve, and not calling
these methods makes the logs less noisy.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::scheduleResolvePendingPlayPromises):
(WebCore::HTMLMediaElement::scheduleRejectPendingPlayPromises):
(WebCore::HTMLMediaElement::setVolume):
(WebCore::HTMLMediaElement::mediaPlayerDidAddAudioTrack):
(WebCore::HTMLMediaElement::mediaPlayerCharacteristicChanged):
(WebCore::HTMLMediaElement::updateShouldPlay):

LayoutTests:

* media/media-play-promise-reject-play-notallowed-audio-expected.txt: Added.
* media/media-play-promise-reject-play-notallowed-audio.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (271530 => 271531)


--- trunk/LayoutTests/ChangeLog	2021-01-15 20:43:12 UTC (rev 271530)
+++ trunk/LayoutTests/ChangeLog	2021-01-15 20:53:32 UTC (rev 271531)
@@ -1,3 +1,14 @@
+2021-01-15  Jer Noble  <jer.no...@apple.com>
+
+        Playback fails at marketwatch.com
+        https://bugs.webkit.org/show_bug.cgi?id=220646
+        <rdar://72950166>
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        * media/media-play-promise-reject-play-notallowed-audio-expected.txt: Added.
+        * media/media-play-promise-reject-play-notallowed-audio.html: Added.
+
 2021-01-15  Antoine Quint  <grao...@webkit.org>
 
         Reversed transform animation not applied alongside other transform animations

Added: trunk/LayoutTests/media/media-play-promise-reject-play-notallowed-audio-expected.txt (0 => 271531)


--- trunk/LayoutTests/media/media-play-promise-reject-play-notallowed-audio-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/media-play-promise-reject-play-notallowed-audio-expected.txt	2021-01-15 20:53:32 UTC (rev 271531)
@@ -0,0 +1,8 @@
+
+RUN(internals.setMediaElementRestrictions(mediaElement, "RequireUserGestureForAudioRateChange"))
+RUN(mediaElement.src = "" "content/test-25fps"))
+RUN(promise = mediaElement.play())
+Promise rejected correctly OK
+EXPECTED (error.name == 'NotAllowedError') OK
+END OF TEST
+

Added: trunk/LayoutTests/media/media-play-promise-reject-play-notallowed-audio.html (0 => 271531)


--- trunk/LayoutTests/media/media-play-promise-reject-play-notallowed-audio.html	                        (rev 0)
+++ trunk/LayoutTests/media/media-play-promise-reject-play-notallowed-audio.html	2021-01-15 20:53:32 UTC (rev 271531)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script src=""
+        <script src=""
+
+        <script>
+        window.addEventListener('load', event => {
+            findMediaElement();
+            if (window.internals)
+                run('internals.setMediaElementRestrictions(mediaElement, "RequireUserGestureForAudioRateChange")');
+
+            run('mediaElement.src = "" "content/test-25fps")');
+            run('promise = mediaElement.play()');
+            shouldReject(promise).then(e => {
+                error = e;
+                testExpected('error.name', 'NotAllowedError');
+            }).finally(endTest);
+        })
+        </script>
+    </head>
+
+    <body>
+        <video></video>
+    </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (271530 => 271531)


--- trunk/Source/WebCore/ChangeLog	2021-01-15 20:43:12 UTC (rev 271530)
+++ trunk/Source/WebCore/ChangeLog	2021-01-15 20:53:32 UTC (rev 271531)
@@ -1,5 +1,36 @@
 2021-01-15  Jer Noble  <jer.no...@apple.com>
 
+        Playback fails at marketwatch.com
+        https://bugs.webkit.org/show_bug.cgi?id=220646
+        <rdar://72950166>
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        Test: media/media-play-promise-reject-play-notallowed-audio.html
+
+        When audio playback is blocked by settings, the HTMLMediaElement must load its source
+        media's metadata in order to determine whether the media should be allowed to play without a
+        user gesture. If a play promise is pending, the expectation is that those promises will
+        reject with a NotAllowedError to indicate that a user gesture is needed. However, by calling
+        pauseInternal() to block (possibly) existing playback, this causes those promises to be
+        rejected with an AbortError, as if the pause() method had been called. Call
+        scheduleRejectPendingPlayPromises() with NotAllowedError to ensure the correct error is used
+        to reject.
+
+        Drive-by fix: no reason to dispatch and call rejectPendingPlayPromises() or
+        resolvePendingPlayPromises() if there are no promises to reject or resolve, and not calling
+        these methods makes the logs less noisy.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::scheduleResolvePendingPlayPromises):
+        (WebCore::HTMLMediaElement::scheduleRejectPendingPlayPromises):
+        (WebCore::HTMLMediaElement::setVolume):
+        (WebCore::HTMLMediaElement::mediaPlayerDidAddAudioTrack):
+        (WebCore::HTMLMediaElement::mediaPlayerCharacteristicChanged):
+        (WebCore::HTMLMediaElement::updateShouldPlay):
+
+2021-01-15  Jer Noble  <jer.no...@apple.com>
+
         CRASH in MediaSourcePrivateAVFObjC::removeSourceBuffer()
         https://bugs.webkit.org/show_bug.cgi?id=220647
         <rdar://73173684>

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (271530 => 271531)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2021-01-15 20:43:12 UTC (rev 271530)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2021-01-15 20:53:32 UTC (rev 271531)
@@ -908,6 +908,9 @@
 
 void HTMLMediaElement::scheduleResolvePendingPlayPromises()
 {
+    if (m_pendingPlayPromises.isEmpty())
+        return;
+
     m_promiseTaskQueue.enqueueTask([this, pendingPlayPromises = WTFMove(m_pendingPlayPromises)] () mutable {
         resolvePendingPlayPromises(WTFMove(pendingPlayPromises));
     });
@@ -915,6 +918,9 @@
 
 void HTMLMediaElement::scheduleRejectPendingPlayPromises(Ref<DOMException>&& error)
 {
+    if (m_pendingPlayPromises.isEmpty())
+        return;
+
     m_promiseTaskQueue.enqueueTask([this, error = WTFMove(error), pendingPlayPromises = WTFMove(m_pendingPlayPromises)] () mutable {
         rejectPendingPlayPromises(WTFMove(pendingPlayPromises), WTFMove(error));
     });
@@ -3609,6 +3615,7 @@
     scheduleEvent(eventNames().volumechangeEvent);
 
     if (isPlaying() && !m_mediaSession->playbackPermitted()) {
+        scheduleRejectPendingPlayPromises(DOMException::create(NotAllowedError));
         pauseInternal();
         setAutoplayEventPlaybackState(AutoplayEventPlaybackState::PreventedAutoplay);
     }
@@ -3876,6 +3883,7 @@
 void HTMLMediaElement::mediaPlayerDidAddAudioTrack(AudioTrackPrivate& track)
 {
     if (isPlaying() && !m_mediaSession->playbackPermitted()) {
+        scheduleRejectPendingPlayPromises(DOMException::create(NotAllowedError));
         pauseInternal();
         setAutoplayEventPlaybackState(AutoplayEventPlaybackState::PreventedAutoplay);
     }
@@ -5050,6 +5058,7 @@
     updateRenderer();
 
     if (!paused() && !m_mediaSession->playbackPermitted()) {
+        scheduleRejectPendingPlayPromises(DOMException::create(NotAllowedError));
         pauseInternal();
         setAutoplayEventPlaybackState(AutoplayEventPlaybackState::PreventedAutoplay);
     }
@@ -7802,6 +7811,7 @@
 void HTMLMediaElement::updateShouldPlay()
 {
     if (!paused() && !m_mediaSession->playbackPermitted()) {
+        scheduleRejectPendingPlayPromises(DOMException::create(NotAllowedError));
         pauseInternal();
         setAutoplayEventPlaybackState(AutoplayEventPlaybackState::PreventedAutoplay);
     } else if (canTransitionFromAutoplayToPlay())
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to