Title: [223144] trunk
Revision
223144
Author
mra...@apple.com
Date
2017-10-10 14:26:03 -0700 (Tue, 10 Oct 2017)

Log Message

Respect audio rate change restrictions in HTMLMediaElement::setVolume.
https://bugs.webkit.org/show_bug.cgi?id=178140

Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html
       media/audio-playback-volume-changes-with-restrictions.html

It's currently possible for a website to start auto-playing media with a zero volume and then
programmatically set the volume to a non-zero value without a user gesture. This code path didn't
have to be considered previously because volume changes are not supported on iOS.

We currently pause media when an audio track comes in after an element has already started playing silently
in mediaPlayerDidAddAudioTrack. This patch does the same when a non-zero volume is set after a media
element already began playing silently and there is an audio rate change restriction.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::setVolume):

LayoutTests:

* media/audio-playback-volume-changes-with-restrictions-and-user-gestures-expected.txt: Added.
* media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html: Added.
* media/audio-playback-volume-changes-with-restrictions-expected.txt: Added.
* media/audio-playback-volume-changes-with-restrictions.html: Added.
* platform/ios/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (223143 => 223144)


--- trunk/LayoutTests/ChangeLog	2017-10-10 21:24:15 UTC (rev 223143)
+++ trunk/LayoutTests/ChangeLog	2017-10-10 21:26:03 UTC (rev 223144)
@@ -1,3 +1,16 @@
+2017-10-10  Matt Rajca  <mra...@apple.com>
+
+        Respect audio rate change restrictions in HTMLMediaElement::setVolume.
+        https://bugs.webkit.org/show_bug.cgi?id=178140
+
+        Reviewed by Eric Carlson.
+
+        * media/audio-playback-volume-changes-with-restrictions-and-user-gestures-expected.txt: Added.
+        * media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html: Added.
+        * media/audio-playback-volume-changes-with-restrictions-expected.txt: Added.
+        * media/audio-playback-volume-changes-with-restrictions.html: Added.
+        * platform/ios/TestExpectations:
+
 2017-10-10  Ryosuke Niwa  <rn...@webkit.org>
 
         Loading should be disabled while constructing the fragment in WebContentReader::readWebArchive

Added: trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-and-user-gestures-expected.txt (0 => 223144)


--- trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-and-user-gestures-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-and-user-gestures-expected.txt	2017-10-10 21:26:03 UTC (rev 223144)
@@ -0,0 +1,13 @@
+
+RUN(internals.setMediaElementRestrictions(audio, "RequireUserGestureForAudioRateChange"))
+RUN(audio.src = "" "content/test"))
+RUN(audio.volume = 1)
+RUN(audio.play().then(failTest).catch(didPreventPlayback))
+Setting volume to 0 to allow playback
+RUN(audio.volume = 0)
+RUN(audio.play().then(didPlaySilentAudio).catch(failTest))
+Ensure setting volume to non-zero value with a user gesture does not pause media in the presence of audio rate change restrictions
+RUN(audio.volume = 0.2)
+EXPECTED (audio.paused == 'false') OK
+END OF TEST
+

Added: trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html (0 => 223144)


--- trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html	2017-10-10 21:26:03 UTC (rev 223144)
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>audio-playback-volume-changes-with-restrictions-and-user-gestures</title>
+    <script src=""
+    <script src=""
+
+    <script>
+    function runTest()
+    {
+        audio = document.getElementsByTagName('audio')[0];
+        run('internals.setMediaElementRestrictions(audio, "RequireUserGestureForAudioRateChange")');
+
+        run('audio.src = "" "content/test")');
+        run('audio.volume = 1');
+        run('audio.play().then(failTest).catch(didPreventPlayback)');
+    }
+
+    function didPreventPlayback()
+    {
+        consoleWrite("Setting volume to 0 to allow playback");
+        run('audio.volume = 0');
+        run('audio.play().then(didPlaySilentAudio).catch(failTest)');
+    }
+    
+    function didPlaySilentAudio()
+    {
+        consoleWrite("Ensure setting volume to non-zero value with a user gesture does not pause media in the presence of audio rate change restrictions");
+        runWithKeyDown(() => {
+            run('audio.volume = 0.2');
+        });
+        testExpected('audio.paused', false);
+        endTest();
+    }
+    </script>
+</head>
+
+<body _onload_="runTest()">
+    <audio controls></audio>
+</body>
+</html>

Added: trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-expected.txt (0 => 223144)


--- trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions-expected.txt	2017-10-10 21:26:03 UTC (rev 223144)
@@ -0,0 +1,13 @@
+
+RUN(internals.setMediaElementRestrictions(audio, "RequireUserGestureForAudioRateChange"))
+RUN(audio.src = "" "content/test"))
+RUN(audio.volume = 1)
+RUN(audio.play().then(failTest).catch(didPreventPlayback))
+Setting volume to 0 to allow playback
+RUN(audio.volume = 0)
+RUN(audio.play().then(didPlaySilentAudio).catch(failTest))
+Ensure setting volume to non-zero value pauses media in the presence of audio rate change restrictions
+RUN(audio.volume = 0.2)
+EXPECTED (audio.paused == 'true') OK
+END OF TEST
+

Added: trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions.html (0 => 223144)


--- trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions.html	                        (rev 0)
+++ trunk/LayoutTests/media/audio-playback-volume-changes-with-restrictions.html	2017-10-10 21:26:03 UTC (rev 223144)
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>audio-playback-volume-changes-with-restrictions</title>
+    <script src=""
+    <script src=""
+
+    <script>
+    function runTest()
+    {
+        audio = document.getElementsByTagName('audio')[0];
+        run('internals.setMediaElementRestrictions(audio, "RequireUserGestureForAudioRateChange")');
+
+        run('audio.src = "" "content/test")');
+        run('audio.volume = 1');
+        run('audio.play().then(failTest).catch(didPreventPlayback)');
+    }
+
+    function didPreventPlayback()
+    {
+        consoleWrite("Setting volume to 0 to allow playback");
+        run('audio.volume = 0');
+        run('audio.play().then(didPlaySilentAudio).catch(failTest)');
+    }
+    
+    function didPlaySilentAudio()
+    {
+        consoleWrite("Ensure setting volume to non-zero value pauses media in the presence of audio rate change restrictions");
+        run('audio.volume = 0.2');
+        testExpected('audio.paused', true);
+        endTest();
+    }
+    </script>
+</head>
+
+<body _onload_="runTest()">
+    <audio controls></audio>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/ios/TestExpectations (223143 => 223144)


--- trunk/LayoutTests/platform/ios/TestExpectations	2017-10-10 21:24:15 UTC (rev 223143)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2017-10-10 21:26:03 UTC (rev 223144)
@@ -381,6 +381,8 @@
 media/audio-dealloc-crash.html [ Skip ]
 media/restricted-audio-playback-with-document-gesture.html [ Skip ]
 media/restricted-audio-playback-with-multiple-settimeouts.html [ Skip ]
+media/audio-playback-volume-changes-with-restrictions.html [ Skip ]
+media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html [ Skip ]
 storage/domstorage/sessionstorage/set-item-synchronous-keydown.html [ Skip ]
 
 # Tests that use EventSender's mouseMoveTo, mouseUp and mouseDown

Modified: trunk/Source/WebCore/ChangeLog (223143 => 223144)


--- trunk/Source/WebCore/ChangeLog	2017-10-10 21:24:15 UTC (rev 223143)
+++ trunk/Source/WebCore/ChangeLog	2017-10-10 21:26:03 UTC (rev 223144)
@@ -1,3 +1,24 @@
+2017-10-10  Matt Rajca  <mra...@apple.com>
+
+        Respect audio rate change restrictions in HTMLMediaElement::setVolume.
+        https://bugs.webkit.org/show_bug.cgi?id=178140
+
+        Reviewed by Eric Carlson.
+
+        Tests: media/audio-playback-volume-changes-with-restrictions-and-user-gestures.html
+               media/audio-playback-volume-changes-with-restrictions.html
+
+        It's currently possible for a website to start auto-playing media with a zero volume and then
+        programmatically set the volume to a non-zero value without a user gesture. This code path didn't
+        have to be considered previously because volume changes are not supported on iOS.
+
+        We currently pause media when an audio track comes in after an element has already started playing silently
+        in mediaPlayerDidAddAudioTrack. This patch does the same when a non-zero volume is set after a media
+        element already began playing silently and there is an audio rate change restriction.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::setVolume):
+
 2017-10-10  Ryosuke Niwa  <rn...@webkit.org>
 
         Loading should be disabled while constructing the fragment in WebContentReader::readWebArchive

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (223143 => 223144)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2017-10-10 21:24:15 UTC (rev 223143)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2017-10-10 21:26:03 UTC (rev 223144)
@@ -3567,10 +3567,18 @@
     if (m_volume == volume)
         return { };
 
+    if (volume && processingUserGestureForMedia())
+        removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
+
     m_volume = volume;
     m_volumeInitialized = true;
     updateVolume();
     scheduleEvent(eventNames().volumechangeEvent);
+
+    if (isPlaying() && !m_mediaSession->playbackPermitted(*this)) {
+        pauseInternal();
+        setPlaybackWithoutUserGesture(PlaybackWithoutUserGesture::Prevented);
+    }
 #endif
     return { };
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to