<!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>[280330] 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/280330">280330</a></dd>
<dt>Author</dt> <dd>jya@apple.com</dd>
<dt>Date</dt> <dd>2021-07-26 17:25:42 -0700 (Mon, 26 Jul 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Video pauses after scrubbing with Touch Bar
https://bugs.webkit.org/show_bug.cgi?id=228277
rdar://80606886

Reviewed by Jer Noble.

Source/WebCore:

In https://trac.webkit.org/<a href="http://trac.webkit.org/projects/webkit/changeset/206487">r206487</a> ; in order to ensure that the playback state
was properly reflected following a seek using the touch bar, the element was paused.
It's unclear if that workaround is still required, but for now we will record if the
element was playing before the seek and if so, resume playback once the seek completes.
Now that the touch bar and Now Playing are hooked to the Media Session action handlers
the behaviour change will occur for all those components.

Test: media/media-session/play-after-seek.html

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement): Initialize new member in constructor.
(WebCore::HTMLMediaElement::clearSeeking):
(WebCore::HTMLMediaElement::finishSeek): Call play() once seek completes if the element
was playing before.
(WebCore::HTMLMediaElement::pause): Ensure that if pause() is called before the seek
completes, the element stays paused.
(WebCore::HTMLMediaElement::handleSeekToPlaybackPosition): Record playing state before
pausing the element.
* html/HTMLMediaElement.h: Add new boolean member.

LayoutTests:

* media/media-session/play-after-seek-expected.txt: Added.
* media/media-session/play-after-seek.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>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediamediasessionplayafterseekexpectedtxt">trunk/LayoutTests/media/media-session/play-after-seek-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediamediasessionplayafterseekhtml">trunk/LayoutTests/media/media-session/play-after-seek.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (280329 => 280330)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2021-07-27 00:15:05 UTC (rev 280329)
+++ trunk/LayoutTests/ChangeLog 2021-07-27 00:25:42 UTC (rev 280330)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2021-07-26  Jean-Yves Avenard  <jya@apple.com>
+
+        Video pauses after scrubbing with Touch Bar
+        https://bugs.webkit.org/show_bug.cgi?id=228277
+        rdar://80606886
+
+        Reviewed by Jer Noble.
+
+        * media/media-session/play-after-seek-expected.txt: Added.
+        * media/media-session/play-after-seek.html: Added.
+
</ins><span class="cx"> 2021-07-26  Eric Hutchison  <ehutchison@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Update test expectations for inspector/canvas/recording-bitmaprenderer-memoryLimit.html.
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasessionplayafterseekexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-session/play-after-seek-expected.txt (0 => 280330)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-session/play-after-seek-expected.txt                               (rev 0)
+++ trunk/LayoutTests/media/media-session/play-after-seek-expected.txt  2021-07-27 00:25:42 UTC (rev 280330)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+
+RUN(video.src = findMediaFile("video", "../content/test"))
+EVENT(loadeddata)
+Test that playback will resume following a seek through media session.
+RUN(video.play())
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1}))
+EXPECTED (video.currentTime == '1') OK
+EVENT(seeked)
+EXPECTED (video.paused == 'false') OK
+Test that playback will stay paused if pause() got called before seek completed.
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1}))
+EXPECTED (video.currentTime == '1') OK
+RUN(video.pause())
+EVENT(seeked)
+EXPECTED (video.paused == 'true') OK
+Test that playback will stay paused after a seek.
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1}))
+EXPECTED (video.currentTime == '1') OK
+EVENT(seeked)
+EXPECTED (video.paused == 'true') OK
+END OF TEST
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediamediasessionplayafterseekhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-session/play-after-seek.html (0 => 280330)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/media/media-session/play-after-seek.html                               (rev 0)
+++ trunk/LayoutTests/media/media-session/play-after-seek.html  2021-07-27 00:25:42 UTC (rev 280330)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+    <title>default-actionHandlers</title>
+    <script src="../video-test.js"></script>
+    <script src="../media-file.js"></script>
+    <script>
+
+    async function runTest() {
+        if (!window.internals) {
+            failTest('This test requires Internals');
+            return;
+        }
+
+        findMediaElement();
+        run('video.src = findMediaFile("video", "../content/test")');
+        await waitFor(video, 'loadeddata');
+
+        consoleWrite('Test that playback will resume following a seek through media session.');
+
+        run("video.play()");
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1})');
+        testExpected("video.currentTime", 1);
+        await waitFor(video, 'seeked');
+        testExpected("video.paused", false);
+
+        consoleWrite('Test that playback will stay paused if pause() got called before seek completed.');
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1})');
+        testExpected("video.currentTime", 1);
+        run("video.pause()");
+        await waitFor(video, 'seeked');
+        testExpected("video.paused", true);
+
+        consoleWrite('Test that playback will stay paused after a seek.');
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1})');
+        testExpected("video.currentTime", 1);
+        await waitFor(video, 'seeked');
+        testExpected("video.paused", true);
+
+        endTest();
+    }
+    </script>
+</head>
+<body onload="runTest()">
+    <video controls preload='auto'></video>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (280329 => 280330)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-07-27 00:15:05 UTC (rev 280329)
+++ trunk/Source/WebCore/ChangeLog      2021-07-27 00:25:42 UTC (rev 280330)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2021-07-26  Jean-Yves Avenard  <jya@apple.com>
+
+        Video pauses after scrubbing with Touch Bar
+        https://bugs.webkit.org/show_bug.cgi?id=228277
+        rdar://80606886
+
+        Reviewed by Jer Noble.
+
+        In https://trac.webkit.org/r206487 ; in order to ensure that the playback state
+        was properly reflected following a seek using the touch bar, the element was paused.
+        It's unclear if that workaround is still required, but for now we will record if the
+        element was playing before the seek and if so, resume playback once the seek completes.
+        Now that the touch bar and Now Playing are hooked to the Media Session action handlers
+        the behaviour change will occur for all those components.
+
+        Test: media/media-session/play-after-seek.html
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize new member in constructor.
+        (WebCore::HTMLMediaElement::clearSeeking):
+        (WebCore::HTMLMediaElement::finishSeek): Call play() once seek completes if the element
+        was playing before.
+        (WebCore::HTMLMediaElement::pause): Ensure that if pause() is called before the seek
+        completes, the element stays paused.
+        (WebCore::HTMLMediaElement::handleSeekToPlaybackPosition): Record playing state before
+        pausing the element.
+        * html/HTMLMediaElement.h: Add new boolean member.
+
</ins><span class="cx"> 2021-07-26  Ryosuke Niwa  <rniwa@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Deploy smart pointers in ApplyBlockElementCommand, IndentOutdentCommand and InsertListCommand
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (280329 => 280330)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp   2021-07-27 00:15:05 UTC (rev 280329)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp      2021-07-27 00:25:42 UTC (rev 280330)
</span><span class="lines">@@ -414,6 +414,7 @@
</span><span class="cx">     , m_paused(true)
</span><span class="cx">     , m_seeking(false)
</span><span class="cx">     , m_seekRequested(false)
</span><ins>+    , m_wasPlayingBeforeSeeking(false)
</ins><span class="cx">     , m_sentStalledEvent(false)
</span><span class="cx">     , m_sentEndEvent(false)
</span><span class="cx">     , m_pausedInternal(false)
</span><span class="lines">@@ -3081,11 +3082,13 @@
</span><span class="cx">     m_seeking = false;
</span><span class="cx">     m_seekRequested = false;
</span><span class="cx">     m_pendingSeekType = NoSeek;
</span><ins>+    m_wasPlayingBeforeSeeking = false;
</ins><span class="cx">     invalidateCachedTime();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::finishSeek()
</span><span class="cx"> {
</span><ins>+    bool wasPlayingBeforeSeeking = m_wasPlayingBeforeSeeking;
</ins><span class="cx">     // 4.8.10.9 Seeking
</span><span class="cx">     // 14 - Set the seeking IDL attribute to false.
</span><span class="cx">     clearSeeking();
</span><span class="lines">@@ -3111,6 +3114,8 @@
</span><span class="cx">     if (m_mediaSource)
</span><span class="cx">         m_mediaSource->monitorSourceBuffers();
</span><span class="cx"> #endif
</span><ins>+    if (wasPlayingBeforeSeeking)
+        playInternal();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
</span><span class="lines">@@ -3565,6 +3570,8 @@
</span><span class="cx">         removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::RequireUserGestureToControlControlsManager);
</span><span class="cx"> 
</span><span class="cx">     pauseInternal();
</span><ins>+    // If we have a pending seek, ensure playback doesn't resume.
+    m_wasPlayingBeforeSeeking = false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::pauseInternal()
</span><span class="lines">@@ -4854,7 +4861,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (!m_isScrubbingRemotely) {
</span><span class="cx">         m_isScrubbingRemotely = true;
</span><del>-        if (!paused())
</del><ins>+        if ((m_wasPlayingBeforeSeeking = !paused()))
</ins><span class="cx">             pauseInternal();
</span><span class="cx">     }
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (280329 => 280330)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h     2021-07-27 00:15:05 UTC (rev 280329)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2021-07-27 00:25:42 UTC (rev 280330)
</span><span class="lines">@@ -1071,6 +1071,7 @@
</span><span class="cx">     bool m_paused : 1;
</span><span class="cx">     bool m_seeking : 1;
</span><span class="cx">     bool m_seekRequested : 1;
</span><ins>+    bool m_wasPlayingBeforeSeeking : 1;
</ins><span class="cx"> 
</span><span class="cx">     // data has not been loaded since sending a "stalled" event
</span><span class="cx">     bool m_sentStalledEvent : 1;
</span></span></pre>
</div>
</div>

</body>
</html>