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 { };
}