Title: [271862] branches/safari-611-branch
Revision
271862
Author
alanc...@apple.com
Date
2021-01-25 14:57:02 -0800 (Mon, 25 Jan 2021)

Log Message

Cherry-pick r271531. rdar://problem/73586664

    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.

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271531 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-611-branch/LayoutTests/ChangeLog (271861 => 271862)


--- branches/safari-611-branch/LayoutTests/ChangeLog	2021-01-25 22:51:56 UTC (rev 271861)
+++ branches/safari-611-branch/LayoutTests/ChangeLog	2021-01-25 22:57:02 UTC (rev 271862)
@@ -1,5 +1,58 @@
 2021-01-25  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r271531. rdar://problem/73586664
+
+    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.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271531 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    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-25  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r271799. rdar://problem/73581832
 
     PCM: Use different well-known locations for triggering and reporting attribution

Added: branches/safari-611-branch/LayoutTests/media/media-play-promise-reject-play-notallowed-audio-expected.txt (0 => 271862)


--- branches/safari-611-branch/LayoutTests/media/media-play-promise-reject-play-notallowed-audio-expected.txt	                        (rev 0)
+++ branches/safari-611-branch/LayoutTests/media/media-play-promise-reject-play-notallowed-audio-expected.txt	2021-01-25 22:57:02 UTC (rev 271862)
@@ -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: branches/safari-611-branch/LayoutTests/media/media-play-promise-reject-play-notallowed-audio.html (0 => 271862)


--- branches/safari-611-branch/LayoutTests/media/media-play-promise-reject-play-notallowed-audio.html	                        (rev 0)
+++ branches/safari-611-branch/LayoutTests/media/media-play-promise-reject-play-notallowed-audio.html	2021-01-25 22:57:02 UTC (rev 271862)
@@ -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: branches/safari-611-branch/Source/WebCore/ChangeLog (271861 => 271862)


--- branches/safari-611-branch/Source/WebCore/ChangeLog	2021-01-25 22:51:56 UTC (rev 271861)
+++ branches/safari-611-branch/Source/WebCore/ChangeLog	2021-01-25 22:57:02 UTC (rev 271862)
@@ -1,5 +1,78 @@
 2021-01-25  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r271531. rdar://problem/73586664
+
+    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.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271531 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    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-25  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r271799. rdar://problem/73581832
 
     PCM: Use different well-known locations for triggering and reporting attribution

Modified: branches/safari-611-branch/Source/WebCore/html/HTMLMediaElement.cpp (271861 => 271862)


--- branches/safari-611-branch/Source/WebCore/html/HTMLMediaElement.cpp	2021-01-25 22:51:56 UTC (rev 271861)
+++ branches/safari-611-branch/Source/WebCore/html/HTMLMediaElement.cpp	2021-01-25 22:57:02 UTC (rev 271862)
@@ -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