<!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>[245467] 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/245467">245467</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2019-05-17 09:39:09 -0700 (Fri, 17 May 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Allow sequential playback of media files when initial playback started with a user gesture
https://bugs.webkit.org/show_bug.cgi?id=197959
<rdar://problem/50655207>

Reviewed by Youenn Fablet.

Source/WebCore:

Test: media/playlist-inherits-user-gesture.html

* dom/Document.cpp:
(WebCore::Document::processingUserGestureForMedia const): Return true if it is within
one second of the last HTMLMediaElement 'ended' event.
* dom/Document.h:
(WebCore::Document::mediaFinishedPlaying):

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::parseAttribute): removeBehaviorsRestrictionsAfterFirstUserGesture ->
removeBehaviorRestrictionsAfterFirstUserGesture.
(WebCore::HTMLMediaElement::load): Ditto. Don't call removeBehaviorsRestrictionsAfterFirstUserGesture,
it will be done in prepareForLoad.
(WebCore::HTMLMediaElement::prepareForLoad): removeBehaviorsRestrictionsAfterFirstUserGesture ->
removeBehaviorRestrictionsAfterFirstUserGesture.
(WebCore::HTMLMediaElement::audioTrackEnabledChanged): Ditto.
(WebCore::HTMLMediaElement::play): Ditto.
(WebCore::HTMLMediaElement::pause): Ditto.
(WebCore::HTMLMediaElement::setVolume): Ditto.
(WebCore::HTMLMediaElement::setMuted): Ditto.
(WebCore::HTMLMediaElement::webkitShowPlaybackTargetPicker): Ditto.
(WebCore::HTMLMediaElement::dispatchEvent): Call document().mediaFinishedPlaying()
when dispatching the 'ended' event.
(WebCore::HTMLMediaElement::removeBehaviorRestrictionsAfterFirstUserGesture): Rename. Set
m_removedBehaviorRestrictionsAfterFirstUserGesture.
(WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture): Deleted.
* html/HTMLMediaElement.h:

* html/HTMLVideoElement.cpp:
(WebCore:HTMLVideoElement::nativeImageForCurrentTime): Convert to runtime logging.
(WebCore:HTMLVideoElement::webkitEnterFullscreen): Ditto.
(WebCore:HTMLVideoElement::webkitSetPresentationMode): Ditto.
(WebCore:HTMLVideoElement::fullscreenModeChanged): Ditto.

* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::removeBehaviorRestriction): Update log message.

LayoutTests:

* media/media-fullscreen.js: Insert a pause between tests to clear the user gesture
used in the first test.
* media/playlist-inherits-user-gesture-expected.txt: Added.
* media/playlist-inherits-user-gesture.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsmediamediafullscreenjs">trunk/LayoutTests/media/media-fullscreen.js</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</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="#trunkSourceWebCorehtmlHTMLVideoElementcpp">trunk/Source/WebCore/html/HTMLVideoElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlMediaElementSessioncpp">trunk/Source/WebCore/html/MediaElementSession.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediaplaylistinheritsusergestureexpectedtxt">trunk/LayoutTests/media/playlist-inherits-user-gesture-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediaplaylistinheritsusergesturehtml">trunk/LayoutTests/media/playlist-inherits-user-gesture.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/LayoutTests/ChangeLog 2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2019-05-17  Eric Carlson  <eric.carlson@apple.com>
+
+        Allow sequential playback of media files when initial playback started with a user gesture
+        https://bugs.webkit.org/show_bug.cgi?id=197959
+        <rdar://problem/50655207>
+
+        Reviewed by Youenn Fablet.
+
+        * media/media-fullscreen.js: Insert a pause between tests to clear the user gesture
+        used in the first test.
+        * media/playlist-inherits-user-gesture-expected.txt: Added.
+        * media/playlist-inherits-user-gesture.html: Added.
+
</ins><span class="cx"> 2019-05-17  Truitt Savell  <tsavell@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Unmark several skipped tests in wk2
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediafullscreenjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/media/media-fullscreen.js (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-fullscreen.js      2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/LayoutTests/media/media-fullscreen.js 2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -14,7 +14,10 @@
</span><span class="cx">     else {
</span><span class="cx">         if (movie.type == 'video')
</span><span class="cx">             testDOMException("mediaElement.webkitEnterFullScreen()", "DOMException.INVALID_STATE_ERR");
</span><del>-        openNextMovie();
</del><ins>+
+        // A user gesture will transfer across setTimeout for 1 second, so pause to let that 
+        // expire before opening the next movie.
+        setTimeout(openNextMovie, 1010);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -62,7 +65,6 @@
</span><span class="cx">     var movie = movieInfo.movies[movieInfo.current];
</span><span class="cx"> 
</span><span class="cx">     consoleWrite("* event handler NOT triggered by a user gesture");
</span><del>-
</del><span class="cx">     if (movie.type == 'video') {
</span><span class="cx">         testExpected("mediaElement.webkitSupportsFullscreen", movie.supportsFS);
</span><span class="cx">         if (mediaElement.webkitSupportsPresentationMode)
</span><span class="lines">@@ -80,10 +82,7 @@
</span><span class="cx">         testDOMException("mediaElement.webkitEnterFullScreen()", "DOMException.INVALID_STATE_ERR");
</span><span class="cx"> 
</span><span class="cx">     // Click on the button
</span><del>-    if (window.testRunner)
-        setTimeout(clickEnterFullscreenButton, 10);
-    else
-        openNextMovie();
</del><ins>+    runWithKeyDown(clickEnterFullscreenButton);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function openNextMovie()
</span></span></pre></div>
<a id="trunkLayoutTestsmediaplaylistinheritsusergestureexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/playlist-inherits-user-gesture-expected.txt (0 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/playlist-inherits-user-gesture-expected.txt                              (rev 0)
+++ trunk/LayoutTests/media/playlist-inherits-user-gesture-expected.txt 2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+** Start first video with user gesture.
+RUN(window.internals.settings.setVideoPlaybackRequiresUserGesture(true);)
+RUN(video1 = document.createElement("video"))
+RUN(video1.src = findMediaFile("video", "content/test"))
+RUN(document.body.appendChild(video1))
+EXPECTED (window.internals.pageMediaState().includes('HasUserInteractedWithMediaElement') == 'false') OK
+RUN(video1.play())
+EXPECTED (window.internals.pageMediaState().includes('HasUserInteractedWithMediaElement') == 'true') OK
+EVENT(playing)
+RUN(video1.currentTime = video1.duration - 0.2)
+EVENT(ended)
+
+** Start second video without user gesture but within inheritance window, should succeed.
+RUN(video2 = document.createElement("video"))
+RUN(video2.src = findMediaFile("video", "content/test"))
+RUN(document.body.appendChild(video2))
+Promise resolved OK
+RUN(video2.currentTime = video2.duration - 0.2)
+EVENT(ended)
+
+** Start third video without user gesture but after inheritance window, should fail.
+RUN(video3 = document.createElement("video"))
+RUN(video3.src = findMediaFile("video", "content/test"))
+RUN(document.body.appendChild(video3))
+Promise rejected correctly OK
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediaplaylistinheritsusergesturehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/playlist-inherits-user-gesture.html (0 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/playlist-inherits-user-gesture.html                              (rev 0)
+++ trunk/LayoutTests/media/playlist-inherits-user-gesture.html 2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+    <title>playlist-inherits-user-gesture</title>
+    <script src=media-file.js></script>
+    <script src=video-test.js></script>
+    <script>
+    async function runTest() {
+        consoleWrite("** Start first video with user gesture.")
+        if (window.internals)
+            run('window.internals.settings.setVideoPlaybackRequiresUserGesture(true);');
+        run('video1 = document.createElement("video")');
+        run('video1.src = findMediaFile("video", "content/test")');
+        video1.controls = 1;
+        run('document.body.appendChild(video1)');
+
+        if (window.internals)
+            testExpected("window.internals.pageMediaState().includes('HasUserInteractedWithMediaElement')", false);
+        runWithKeyDown(() => {
+            run('video1.play()');
+        });
+        if (window.internals)
+            testExpected("window.internals.pageMediaState().includes('HasUserInteractedWithMediaElement')", true)
+
+        await waitFor(video1, 'playing');
+        run('video1.currentTime = video1.duration - 0.2');
+        await waitFor(video1, 'ended');
+
+        consoleWrite("<br>** Start second video without user gesture but within inheritance window, should succeed.")
+        run('video2 = document.createElement("video")');
+        run('video2.src = findMediaFile("video", "content/test")');
+        video2.controls = 1;
+        run('document.body.appendChild(video2)');
+
+        await shouldResolve(video2.play());
+        run('video2.currentTime = video2.duration - 0.2');
+        await waitFor(video2, 'ended');
+
+        consoleWrite("<br>** Start third video without user gesture but after inheritance window, should fail.")
+        await sleepFor(1200);
+        run('video3 = document.createElement("video")');
+        run('video3.src = findMediaFile("video", "content/test")');
+        video3.controls = 1;
+        run('document.body.appendChild(video3)');
+
+        await shouldReject(video3.play());
+
+        endTest();
+    }
+    </script>
+</head>
+<body onload="runTest()">
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/Source/WebCore/ChangeLog      2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2019-05-17  Eric Carlson  <eric.carlson@apple.com>
+
+        Allow sequential playback of media files when initial playback started with a user gesture
+        https://bugs.webkit.org/show_bug.cgi?id=197959
+        <rdar://problem/50655207>
+
+        Reviewed by Youenn Fablet.
+
+        Test: media/playlist-inherits-user-gesture.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::processingUserGestureForMedia const): Return true if it is within
+        one second of the last HTMLMediaElement 'ended' event.
+        * dom/Document.h:
+        (WebCore::Document::mediaFinishedPlaying):
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::parseAttribute): removeBehaviorsRestrictionsAfterFirstUserGesture -> 
+        removeBehaviorRestrictionsAfterFirstUserGesture.
+        (WebCore::HTMLMediaElement::load): Ditto. Don't call removeBehaviorsRestrictionsAfterFirstUserGesture,
+        it will be done in prepareForLoad.
+        (WebCore::HTMLMediaElement::prepareForLoad): removeBehaviorsRestrictionsAfterFirstUserGesture -> 
+        removeBehaviorRestrictionsAfterFirstUserGesture.
+        (WebCore::HTMLMediaElement::audioTrackEnabledChanged): Ditto.
+        (WebCore::HTMLMediaElement::play): Ditto.
+        (WebCore::HTMLMediaElement::pause): Ditto.
+        (WebCore::HTMLMediaElement::setVolume): Ditto.
+        (WebCore::HTMLMediaElement::setMuted): Ditto.
+        (WebCore::HTMLMediaElement::webkitShowPlaybackTargetPicker): Ditto.
+        (WebCore::HTMLMediaElement::dispatchEvent): Call document().mediaFinishedPlaying()
+        when dispatching the 'ended' event.
+        (WebCore::HTMLMediaElement::removeBehaviorRestrictionsAfterFirstUserGesture): Rename. Set
+        m_removedBehaviorRestrictionsAfterFirstUserGesture.
+        (WebCore::HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture): Deleted.
+        * html/HTMLMediaElement.h:
+        
+        * html/HTMLVideoElement.cpp:
+        (WebCore:HTMLVideoElement::nativeImageForCurrentTime): Convert to runtime logging.
+        (WebCore:HTMLVideoElement::webkitEnterFullscreen): Ditto.
+        (WebCore:HTMLVideoElement::webkitSetPresentationMode): Ditto.
+        (WebCore:HTMLVideoElement::fullscreenModeChanged): Ditto.
+
+        * html/MediaElementSession.cpp:
+        (WebCore::MediaElementSession::removeBehaviorRestriction): Update log message.
+
</ins><span class="cx"> 2019-05-17  Brent Fulgham  <bfulgham@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Hardening: Prevent FrameLoader crash due to SetForScope
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp    2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/Source/WebCore/dom/Document.cpp       2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -328,6 +328,7 @@
</span><span class="cx"> 
</span><span class="cx"> static const unsigned cMaxWriteRecursionDepth = 21;
</span><span class="cx"> bool Document::hasEverCreatedAnAXObjectCache = false;
</span><ins>+static const Seconds maxIntervalForUserGestureForwardingAfterMediaFinishesPlaying { 1_s };
</ins><span class="cx"> 
</span><span class="cx"> // DOM Level 2 says (letters added):
</span><span class="cx"> //
</span><span class="lines">@@ -6576,6 +6577,9 @@
</span><span class="cx">     if (UserGestureIndicator::processingUserGestureForMedia())
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><ins>+    if (m_userActivatedMediaFinishedPlayingTimestamp + maxIntervalForUserGestureForwardingAfterMediaFinishesPlaying >= MonotonicTime::now())
+        return true;
+
</ins><span class="cx">     if (settings().mediaUserGestureInheritsFromDocument())
</span><span class="cx">         return topDocument().hasHadUserInteraction();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h      2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/Source/WebCore/dom/Document.h 2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -1221,6 +1221,7 @@
</span><span class="cx">     bool hasHadUserInteraction() const { return static_cast<bool>(m_lastHandledUserGestureTimestamp); }
</span><span class="cx">     void updateLastHandledUserGestureTimestamp(MonotonicTime);
</span><span class="cx">     bool processingUserGestureForMedia() const;
</span><ins>+    void userActivatedMediaFinishedPlaying() { m_userActivatedMediaFinishedPlayingTimestamp = MonotonicTime::now(); }
</ins><span class="cx"> 
</span><span class="cx">     void setUserDidInteractWithPage(bool userDidInteractWithPage) { ASSERT(&topDocument() == this); m_userDidInteractWithPage = userDidInteractWithPage; }
</span><span class="cx">     bool userDidInteractWithPage() const { ASSERT(&topDocument() == this); return m_userDidInteractWithPage; }
</span><span class="lines">@@ -1835,6 +1836,7 @@
</span><span class="cx">     std::unique_ptr<EventTargetSet> m_wheelEventTargets;
</span><span class="cx"> 
</span><span class="cx">     MonotonicTime m_lastHandledUserGestureTimestamp;
</span><ins>+    MonotonicTime m_userActivatedMediaFinishedPlayingTimestamp;
</ins><span class="cx"> 
</span><span class="cx">     void clearScriptedAnimationController();
</span><span class="cx">     RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp   2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp      2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -839,7 +839,7 @@
</span><span class="cx">         setMediaGroup(value);
</span><span class="cx">     else if (name == autoplayAttr) {
</span><span class="cx">         if (processingUserGestureForMedia())
</span><del>-            removeBehaviorsRestrictionsAfterFirstUserGesture();
</del><ins>+            removeBehaviorRestrictionsAfterFirstUserGesture();
</ins><span class="cx">     } else if (name == titleAttr) {
</span><span class="cx">         if (m_mediaSession)
</span><span class="cx">             m_mediaSession->clientCharacteristicsChanged();
</span><span class="lines">@@ -1178,9 +1178,6 @@
</span><span class="cx"> 
</span><span class="cx">     INFO_LOG(LOGIDENTIFIER);
</span><span class="cx"> 
</span><del>-    if (processingUserGestureForMedia())
-        removeBehaviorsRestrictionsAfterFirstUserGesture();
-
</del><span class="cx">     prepareForLoad();
</span><span class="cx">     m_resourceSelectionTaskQueue.enqueueTask([this] {
</span><span class="cx">         prepareToPlay();
</span><span class="lines">@@ -1193,8 +1190,11 @@
</span><span class="cx">     // The Media Element Load Algorithm
</span><span class="cx">     // 12 February 2017
</span><span class="cx"> 
</span><del>-    INFO_LOG(LOGIDENTIFIER);
</del><ins>+    ALWAYS_LOG(LOGIDENTIFIER, "gesture = ", processingUserGestureForMedia());
</ins><span class="cx"> 
</span><ins>+    if (processingUserGestureForMedia())
+        removeBehaviorRestrictionsAfterFirstUserGesture();
+
</ins><span class="cx">     // 1 - Abort any already-running instance of the resource selection algorithm for this element.
</span><span class="cx">     // Perform the cleanup required for the resource load algorithm to run.
</span><span class="cx">     stopPeriodicTimers();
</span><span class="lines">@@ -1951,7 +1951,7 @@
</span><span class="cx">     if (m_audioTracks && m_audioTracks->contains(track))
</span><span class="cx">         m_audioTracks->scheduleChangeEvent();
</span><span class="cx">     if (processingUserGestureForMedia())
</span><del>-        removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
</del><ins>+        removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::textTrackModeChanged(TextTrack& track)
</span><span class="lines">@@ -3515,7 +3515,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (processingUserGestureForMedia())
</span><del>-        removeBehaviorsRestrictionsAfterFirstUserGesture();
</del><ins>+        removeBehaviorRestrictionsAfterFirstUserGesture();
</ins><span class="cx"> 
</span><span class="cx">     m_pendingPlayPromises.append(WTFMove(promise));
</span><span class="cx">     playInternal();
</span><span class="lines">@@ -3532,7 +3532,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     if (processingUserGestureForMedia())
</span><del>-        removeBehaviorsRestrictionsAfterFirstUserGesture();
</del><ins>+        removeBehaviorRestrictionsAfterFirstUserGesture();
</ins><span class="cx"> 
</span><span class="cx">     playInternal();
</span><span class="cx"> }
</span><span class="lines">@@ -3633,7 +3633,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (processingUserGestureForMedia())
</span><del>-        removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::RequireUserGestureToControlControlsManager);
</del><ins>+        removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::RequireUserGestureToControlControlsManager);
</ins><span class="cx"> 
</span><span class="cx">     pauseInternal();
</span><span class="cx"> }
</span><span class="lines">@@ -3744,7 +3744,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS_FAMILY)
</span><span class="cx">     if (volume && processingUserGestureForMedia())
</span><del>-        removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
</del><ins>+        removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
</ins><span class="cx"> 
</span><span class="cx">     m_volume = volume;
</span><span class="cx">     m_volumeInitialized = true;
</span><span class="lines">@@ -3783,7 +3783,7 @@
</span><span class="cx">     bool mutedStateChanged = m_muted != muted;
</span><span class="cx">     if (mutedStateChanged || !m_explicitlyMuted) {
</span><span class="cx">         if (processingUserGestureForMedia()) {
</span><del>-            removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
</del><ins>+            removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::AllRestrictions & ~MediaElementSession::RequireUserGestureToControlControlsManager);
</ins><span class="cx"> 
</span><span class="cx">             if (hasAudio() && muted)
</span><span class="cx">                 userDidInterfereWithAutoplay();
</span><span class="lines">@@ -5878,7 +5878,7 @@
</span><span class="cx"> {
</span><span class="cx">     ALWAYS_LOG(LOGIDENTIFIER);
</span><span class="cx">     if (processingUserGestureForMedia())
</span><del>-        removeBehaviorsRestrictionsAfterFirstUserGesture();
</del><ins>+        removeBehaviorRestrictionsAfterFirstUserGesture();
</ins><span class="cx">     m_mediaSession->showPlaybackTargetPicker();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -5917,6 +5917,9 @@
</span><span class="cx"> {
</span><span class="cx">     DEBUG_LOG(LOGIDENTIFIER, event.type());
</span><span class="cx"> 
</span><ins>+    if (m_removedBehaviorRestrictionsAfterFirstUserGesture && event.type() == eventNames().endedEvent)
+        document().userActivatedMediaFinishedPlaying();
+
</ins><span class="cx">     HTMLElement::dispatchEvent(event);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -7207,7 +7210,7 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask)
</del><ins>+void HTMLMediaElement::removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask)
</ins><span class="cx"> {
</span><span class="cx">     MediaElementSession::BehaviorRestrictions restrictionsToRemove = mask &
</span><span class="cx">         (MediaElementSession::RequireUserGestureForLoad
</span><span class="lines">@@ -7222,6 +7225,8 @@
</span><span class="cx">         | MediaElementSession::InvisibleAutoplayNotPermitted
</span><span class="cx">         | MediaElementSession::RequireUserGestureToControlControlsManager);
</span><span class="cx"> 
</span><ins>+    m_removedBehaviorRestrictionsAfterFirstUserGesture = true;
+
</ins><span class="cx">     m_mediaSession->removeBehaviorRestriction(restrictionsToRemove);
</span><span class="cx">     document().topDocument().noteUserInteractionWithMediaElement();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h     2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -562,6 +562,7 @@
</span><span class="cx"> #if !RELEASE_LOG_DISABLED
</span><span class="cx">     const Logger& logger() const final { return *m_logger.get(); }
</span><span class="cx">     const void* logIdentifier() const final { return m_logIdentifier; }
</span><ins>+    const char* logClassName() const final { return "HTMLMediaElement"; }
</ins><span class="cx">     WTFLogChannel& logChannel() const final;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -851,7 +852,7 @@
</span><span class="cx"> 
</span><span class="cx">     void changeNetworkStateFromLoadingToIdle();
</span><span class="cx"> 
</span><del>-    void removeBehaviorsRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
</del><ins>+    void removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
</ins><span class="cx"> 
</span><span class="cx">     void updateMediaController();
</span><span class="cx">     bool isBlocked() const;
</span><span class="lines">@@ -942,8 +943,6 @@
</span><span class="cx">     void setInActiveDocument(bool);
</span><span class="cx"> 
</span><span class="cx"> #if !RELEASE_LOG_DISABLED
</span><del>-    const char* logClassName() const final { return "HTMLMediaElement"; }
-
</del><span class="cx">     const void* mediaPlayerLogIdentifier() final { return logIdentifier(); }
</span><span class="cx">     const Logger& mediaPlayerLogger() final { return logger(); }
</span><span class="cx"> #endif
</span><span class="lines">@@ -1201,6 +1200,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_isPlayingToWirelessTarget { false };
</span><span class="cx">     bool m_playingOnSecondScreen { false };
</span><ins>+    bool m_removedBehaviorRestrictionsAfterFirstUserGesture { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> String convertEnumerationToString(HTMLMediaElement::AutoplayEventPlaybackState);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLVideoElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLVideoElement.cpp (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLVideoElement.cpp   2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/Source/WebCore/html/HTMLVideoElement.cpp      2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -318,7 +318,7 @@
</span><span class="cx"> 
</span><span class="cx"> ExceptionOr<void> HTMLVideoElement::webkitEnterFullscreen()
</span><span class="cx"> {
</span><del>-    LOG(Media, "HTMLVideoElement::webkitEnterFullscreen(%p)", this);
</del><ins>+    ALWAYS_LOG(LOGIDENTIFIER);
</ins><span class="cx">     if (isFullscreen())
</span><span class="cx">         return { };
</span><span class="cx"> 
</span><span class="lines">@@ -333,7 +333,7 @@
</span><span class="cx"> 
</span><span class="cx"> void HTMLVideoElement::webkitExitFullscreen()
</span><span class="cx"> {
</span><del>-    LOG(Media, "HTMLVideoElement::webkitExitFullscreen(%p)", this);
</del><ins>+    ALWAYS_LOG(LOGIDENTIFIER);
</ins><span class="cx">     if (isFullscreen())
</span><span class="cx">         exitFullscreen();
</span><span class="cx"> }
</span><span class="lines">@@ -443,7 +443,7 @@
</span><span class="cx"> 
</span><span class="cx"> void HTMLVideoElement::webkitSetPresentationMode(VideoPresentationMode mode)
</span><span class="cx"> {
</span><del>-    LOG(Media, "HTMLVideoElement::webkitSetPresentationMode(%p) - %d", this, mode);
</del><ins>+    ALWAYS_LOG(LOGIDENTIFIER, mode);
</ins><span class="cx">     setFullscreenMode(toFullscreenMode(mode));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -483,7 +483,7 @@
</span><span class="cx"> void HTMLVideoElement::fullscreenModeChanged(VideoFullscreenMode mode)
</span><span class="cx"> {
</span><span class="cx">     if (mode != fullscreenMode()) {
</span><del>-        LOG(Media, "HTMLVideoElement::fullscreenModeChanged(%p) - mode changed from %i to %i", this, fullscreenMode(), mode);
</del><ins>+        ALWAYS_LOG(LOGIDENTIFIER, "changed from ", fullscreenMode(), ", to ", mode);
</ins><span class="cx">         scheduleEvent(eventNames().webkitpresentationmodechangedEvent);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlMediaElementSessioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (245466 => 245467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/MediaElementSession.cpp        2019-05-17 16:27:34 UTC (rev 245466)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp   2019-05-17 16:39:09 UTC (rev 245467)
</span><span class="lines">@@ -242,7 +242,7 @@
</span><span class="cx">     if (!(m_restrictions & restriction))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    INFO_LOG(LOGIDENTIFIER, "removing ", restrictionNames(m_restrictions & restriction));
</del><ins>+    INFO_LOG(LOGIDENTIFIER, "removed ", restrictionNames(m_restrictions & restriction));
</ins><span class="cx">     m_restrictions &= ~restriction;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>