Video elements with autoplay do not begin playing when scrolling into view if Invisib...
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Mar 2016 15:20:40 +0000 (15:20 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Mar 2016 15:20:40 +0000 (15:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=155468

Reviewed by Eric Carlson.

Source/WebCore:

Test: media/video-restricted-invisible-autoplay-allowed-when-visible.html

A few bugs came together to cause this behavior. We were not telling the media session that we were going to begin
the autoplaying state, we were not restoring the correct state when the interruption ended, and we were not checking
to see if we could actually play correctly when the interruption ended.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::prepareForLoad):
(WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay):
(WebCore::HTMLMediaElement::setReadyState):
(WebCore::HTMLMediaElement::resumeAutoplaying):
(WebCore::HTMLMediaElement::updateShouldPlay):
(WebCore::elementCanTransitionFromAutoplayToPlay): Deleted.
* html/HTMLMediaElement.h:
* platform/audio/PlatformMediaSession.cpp:
(WebCore::PlatformMediaSession::endInterruption):

LayoutTests:

* media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt: Added.
* media/video-restricted-invisible-autoplay-allowed-when-visible.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt [new file with mode: 0644]
LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/platform/audio/PlatformMediaSession.cpp

index 0a852d2..7fbccd3 100644 (file)
@@ -1,3 +1,13 @@
+2016-03-14  Jer Noble  <jer.noble@apple.com>
+
+        Video elements with autoplay do not begin playing when scrolling into view if InvisibleAutoplayNotPermitted is set.
+        https://bugs.webkit.org/show_bug.cgi?id=155468
+
+        Reviewed by Eric Carlson.
+
+        * media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt: Added.
+        * media/video-restricted-invisible-autoplay-allowed-when-visible.html: Added.
+
 2016-03-15  Jiewen Tan  <jiewen_tan@apple.com>
 
         URL Parsing should signal failure for illegal IDN
diff --git a/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt b/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt
new file mode 100644 (file)
index 0000000..30f0085
--- /dev/null
@@ -0,0 +1,8 @@
+Test that "invisible autoplay not allowed restriction" plays media when scrolled into view.
+
+RUN(internals.setMediaElementRestrictions(video, "InvisibleAutoplayNotPermitted"))
+** setting video.src
+RUN(document.body.appendChild(video))
+EVENT(play)
+END OF TEST
+
diff --git a/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible.html b/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible.html
new file mode 100644 (file)
index 0000000..d7a1273
--- /dev/null
@@ -0,0 +1,36 @@
+<html>
+    <head>
+        <script src="media-file.js"></script>
+        <script src="video-test.js"></script>
+        <script>
+            function start()
+            {
+                video = document.createElement('video');
+                run('internals.setMediaElementRestrictions(video, "InvisibleAutoplayNotPermitted")');
+                video.autoplay = true;
+                consoleWrite('** setting video.src');
+                video.src = findMediaFile('video', 'content/test');
+
+                waitForEvent('play', play)
+                setTimeout(putInDOM, 250);
+            }
+
+            function putInDOM()
+            {
+                run('document.body.appendChild(video)');
+                failTestIn(250);
+            }
+
+            function play()
+            {
+                if (!video.parentNode)
+                    failTest('play event fired before element was put in DOM');
+                endTest();
+            }
+        </script>
+    </head>
+
+    <body onload="start()">
+        <p>Test that "invisible autoplay not allowed restriction" plays media when scrolled into view.</p>
+    </body>
+</html>
index 680593b..80bd43e 100644 (file)
@@ -1,3 +1,27 @@
+2016-03-14  Jer Noble  <jer.noble@apple.com>
+
+        Video elements with autoplay do not begin playing when scrolling into view if InvisibleAutoplayNotPermitted is set.
+        https://bugs.webkit.org/show_bug.cgi?id=155468
+
+        Reviewed by Eric Carlson.
+
+        Test: media/video-restricted-invisible-autoplay-allowed-when-visible.html
+
+        A few bugs came together to cause this behavior. We were not telling the media session that we were going to begin
+        the autoplaying state, we were not restoring the correct state when the interruption ended, and we were not checking
+        to see if we could actually play correctly when the interruption ended.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::prepareForLoad):
+        (WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay):
+        (WebCore::HTMLMediaElement::setReadyState):
+        (WebCore::HTMLMediaElement::resumeAutoplaying):
+        (WebCore::HTMLMediaElement::updateShouldPlay):
+        (WebCore::elementCanTransitionFromAutoplayToPlay): Deleted.
+        * html/HTMLMediaElement.h:
+        * platform/audio/PlatformMediaSession.cpp:
+        (WebCore::PlatformMediaSession::endInterruption):
+
 2016-03-15  Manuel Rego Casasnovas  <rego@igalia.com>
 
         [css-grid] Rename GridCoordinate to GridArea
index 16e90e0..6e26da9 100644 (file)
@@ -1069,6 +1069,7 @@ void HTMLMediaElement::prepareForLoad()
     // 6 - Set the error attribute to null and the autoplaying flag to true.
     m_error = nullptr;
     m_autoplaying = true;
+    mediaSession().clientWillBeginAutoplaying();
 
     // 7 - Invoke the media element's resource selection algorithm.
 
@@ -2090,13 +2091,14 @@ void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
     endProcessingMediaPlayerCallback();
 }
 
-static bool elementCanTransitionFromAutoplayToPlay(HTMLMediaElement& element)
+bool HTMLMediaElement::canTransitionFromAutoplayToPlay() const
 {
-    return element.isAutoplaying()
-        && element.paused()
-        && element.autoplay()
-        && !element.document().isSandboxed(SandboxAutomaticFeatures)
-        && element.mediaSession().playbackPermitted(element);
+    return isAutoplaying()
+        && paused()
+        && autoplay()
+        && !pausedForUserInteraction()
+        && !document().isSandboxed(SandboxAutomaticFeatures)
+        && mediaSession().playbackPermitted(*this);
 }
 
 void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
@@ -2209,7 +2211,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
         if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
             scheduleEvent(eventNames().playingEvent);
 
-        if (elementCanTransitionFromAutoplayToPlay(*this)) {
+        if (canTransitionFromAutoplayToPlay()) {
             m_paused = false;
             invalidateCachedTime();
             scheduleEvent(eventNames().playEvent);
@@ -6536,7 +6538,7 @@ void HTMLMediaElement::resumeAutoplaying()
     LOG(Media, "HTMLMediaElement::resumeAutoplaying(%p) - paused = %s", this, boolString(paused()));
     m_autoplaying = true;
 
-    if (elementCanTransitionFromAutoplayToPlay(*this))
+    if (canTransitionFromAutoplayToPlay())
         play();
 }
 
@@ -6831,7 +6833,7 @@ void HTMLMediaElement::updateShouldPlay()
 {
     if (isPlaying() && !m_mediaSession->playbackPermitted(*this))
         pauseInternal();
-    else if (elementCanTransitionFromAutoplayToPlay(*this))
+    else if (canTransitionFromAutoplayToPlay())
         play();
 }
 
index 4a4d0c5..461dfe8 100644 (file)
@@ -690,6 +690,7 @@ private:
     bool stoppedDueToErrors() const;
     bool pausedForUserInteraction() const;
     bool couldPlayIfEnoughData() const;
+    bool canTransitionFromAutoplayToPlay() const;
 
     MediaTime minTimeSeekable() const;
     MediaTime maxTimeSeekable() const;
index 820738e..5c43f1f 100644 (file)
@@ -129,7 +129,7 @@ void PlatformMediaSession::endInterruption(EndInterruptionFlags flags)
     State stateToRestore = m_stateToRestore;
     m_stateToRestore = Idle;
     m_interruptionType = NoInterruption;
-    setState(Paused);
+    setState(stateToRestore);
 
     if (stateToRestore == Autoplaying)
         client().resumeAutoplaying();