<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[198211] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/198211">198211</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2016-03-15 08:20:40 -0700 (Tue, 15 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.

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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementh">trunk/Source/WebCore/html/HTMLMediaElement.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioPlatformMediaSessioncpp">trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediavideorestrictedinvisibleautoplayallowedwhenvisibleexpectedtxt">trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediavideorestrictedinvisibleautoplayallowedwhenvisiblehtml">trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (198210 => 198211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-03-15 15:10:07 UTC (rev 198210)
+++ trunk/LayoutTests/ChangeLog        2016-03-15 15:20:40 UTC (rev 198211)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-03-14  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        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.
+
</ins><span class="cx"> 2016-03-15  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         URL Parsing should signal failure for illegal IDN
</span></span></pre></div>
<a id="trunkLayoutTestsmediavideorestrictedinvisibleautoplayallowedwhenvisibleexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt (0 => 198211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt                                (rev 0)
+++ trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible-expected.txt        2016-03-15 15:20:40 UTC (rev 198211)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+Test that &quot;invisible autoplay not allowed restriction&quot; plays media when scrolled into view.
+
+RUN(internals.setMediaElementRestrictions(video, &quot;InvisibleAutoplayNotPermitted&quot;))
+** setting video.src
+RUN(document.body.appendChild(video))
+EVENT(play)
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediavideorestrictedinvisibleautoplayallowedwhenvisiblehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible.html (0 => 198211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible.html                                (rev 0)
+++ trunk/LayoutTests/media/video-restricted-invisible-autoplay-allowed-when-visible.html        2016-03-15 15:20:40 UTC (rev 198211)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+&lt;html&gt;
+    &lt;head&gt;
+        &lt;script src=&quot;media-file.js&quot;&gt;&lt;/script&gt;
+        &lt;script src=&quot;video-test.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+            function start()
+            {
+                video = document.createElement('video');
+                run('internals.setMediaElementRestrictions(video, &quot;InvisibleAutoplayNotPermitted&quot;)');
+                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();
+            }
+        &lt;/script&gt;
+    &lt;/head&gt;
+
+    &lt;body onload=&quot;start()&quot;&gt;
+        &lt;p&gt;Test that &quot;invisible autoplay not allowed restriction&quot; plays media when scrolled into view.&lt;/p&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (198210 => 198211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-15 15:10:07 UTC (rev 198210)
+++ trunk/Source/WebCore/ChangeLog        2016-03-15 15:20:40 UTC (rev 198211)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2016-03-14  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        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):
+
</ins><span class="cx"> 2016-03-15  Manuel Rego Casasnovas  &lt;rego@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [css-grid] Rename GridCoordinate to GridArea
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (198210 => 198211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-03-15 15:10:07 UTC (rev 198210)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-03-15 15:20:40 UTC (rev 198211)
</span><span class="lines">@@ -1069,6 +1069,7 @@
</span><span class="cx">     // 6 - Set the error attribute to null and the autoplaying flag to true.
</span><span class="cx">     m_error = nullptr;
</span><span class="cx">     m_autoplaying = true;
</span><ins>+    mediaSession().clientWillBeginAutoplaying();
</ins><span class="cx"> 
</span><span class="cx">     // 7 - Invoke the media element's resource selection algorithm.
</span><span class="cx"> 
</span><span class="lines">@@ -2090,13 +2091,14 @@
</span><span class="cx">     endProcessingMediaPlayerCallback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool elementCanTransitionFromAutoplayToPlay(HTMLMediaElement&amp; element)
</del><ins>+bool HTMLMediaElement::canTransitionFromAutoplayToPlay() const
</ins><span class="cx"> {
</span><del>-    return element.isAutoplaying()
-        &amp;&amp; element.paused()
-        &amp;&amp; element.autoplay()
-        &amp;&amp; !element.document().isSandboxed(SandboxAutomaticFeatures)
-        &amp;&amp; element.mediaSession().playbackPermitted(element);
</del><ins>+    return isAutoplaying()
+        &amp;&amp; paused()
+        &amp;&amp; autoplay()
+        &amp;&amp; !pausedForUserInteraction()
+        &amp;&amp; !document().isSandboxed(SandboxAutomaticFeatures)
+        &amp;&amp; mediaSession().playbackPermitted(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
</span><span class="lines">@@ -2209,7 +2211,7 @@
</span><span class="cx">         if (isPotentiallyPlaying &amp;&amp; oldState &lt;= HAVE_CURRENT_DATA)
</span><span class="cx">             scheduleEvent(eventNames().playingEvent);
</span><span class="cx"> 
</span><del>-        if (elementCanTransitionFromAutoplayToPlay(*this)) {
</del><ins>+        if (canTransitionFromAutoplayToPlay()) {
</ins><span class="cx">             m_paused = false;
</span><span class="cx">             invalidateCachedTime();
</span><span class="cx">             scheduleEvent(eventNames().playEvent);
</span><span class="lines">@@ -6536,7 +6538,7 @@
</span><span class="cx">     LOG(Media, &quot;HTMLMediaElement::resumeAutoplaying(%p) - paused = %s&quot;, this, boolString(paused()));
</span><span class="cx">     m_autoplaying = true;
</span><span class="cx"> 
</span><del>-    if (elementCanTransitionFromAutoplayToPlay(*this))
</del><ins>+    if (canTransitionFromAutoplayToPlay())
</ins><span class="cx">         play();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -6831,7 +6833,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (isPlaying() &amp;&amp; !m_mediaSession-&gt;playbackPermitted(*this))
</span><span class="cx">         pauseInternal();
</span><del>-    else if (elementCanTransitionFromAutoplayToPlay(*this))
</del><ins>+    else if (canTransitionFromAutoplayToPlay())
</ins><span class="cx">         play();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (198210 => 198211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h        2016-03-15 15:10:07 UTC (rev 198210)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2016-03-15 15:20:40 UTC (rev 198211)
</span><span class="lines">@@ -690,6 +690,7 @@
</span><span class="cx">     bool stoppedDueToErrors() const;
</span><span class="cx">     bool pausedForUserInteraction() const;
</span><span class="cx">     bool couldPlayIfEnoughData() const;
</span><ins>+    bool canTransitionFromAutoplayToPlay() const;
</ins><span class="cx"> 
</span><span class="cx">     MediaTime minTimeSeekable() const;
</span><span class="cx">     MediaTime maxTimeSeekable() const;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp (198210 => 198211)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp        2016-03-15 15:10:07 UTC (rev 198210)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp        2016-03-15 15:20:40 UTC (rev 198211)
</span><span class="lines">@@ -129,7 +129,7 @@
</span><span class="cx">     State stateToRestore = m_stateToRestore;
</span><span class="cx">     m_stateToRestore = Idle;
</span><span class="cx">     m_interruptionType = NoInterruption;
</span><del>-    setState(Paused);
</del><ins>+    setState(stateToRestore);
</ins><span class="cx"> 
</span><span class="cx">     if (stateToRestore == Autoplaying)
</span><span class="cx">         client().resumeAutoplaying();
</span></span></pre>
</div>
</div>

</body>
</html>