<!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>[206771] 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/206771">206771</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2016-10-04 08:35:30 -0700 (Tue, 04 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Media controls are displayed in the incorrect state momentarily after switching between tabs playing media
https://bugs.webkit.org/show_bug.cgi?id=162766
&lt;rdar://problem/28533523&gt;

Reviewed by Jer Noble.

Source/WebCore:

When showing Now Playing controls for a media session, we should first set up the Now Playing info and
playback state before telling MediaRemote to make the session visible. This is WebKit work in ensuring that
when switching Now Playing sessions by switching tabs, we do not first display an invalid Now Playing state
before updating to the expected state.

Adds 2 new WebKit API tests in NowPlayingControlsTests: NowPlayingControlsHideAfterShowingClearsInfo and
NowPlayingControlsClearInfoAfterSessionIsNoLongerValid.

* platform/audio/PlatformMediaSessionManager.h:
(WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingTitle):
(WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingDuration):
(WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingElapsedTime):
(WebCore::PlatformMediaSessionManager::hasActiveNowPlayingSession): Deleted.
* platform/audio/mac/MediaSessionManagerMac.h:
* platform/audio/mac/MediaSessionManagerMac.mm:
(WebCore::MediaSessionManagerMac::updateNowPlayingInfo):

Source/WebKit2:

Plumbs some more Now Playing information from the web process to the UI process for testing purposes. See
WebCore ChangeLog for more details.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _handleActiveNowPlayingSessionInfoResponse:title:duration:elapsedTime:]):
(-[WKWebView _handleActiveNowPlayingSessionInfoResponse:]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleActiveNowPlayingSessionInfoResponse):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::handleActiveNowPlayingSessionInfoResponse):
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::requestActiveNowPlayingSessionInfo):

Tools:

Adds new tests and tweaks existing tests to verify last updated Now Playing information.

* TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm:
(-[NowPlayingTestWebView _handleActiveNowPlayingSessionInfoResponse:title:duration:elapsedTime:]):
(TestWebKitAPI::TEST):
(-[NowPlayingTestWebView _handleActiveNowPlayingSessionInfoResponse:]): Deleted.
* TestWebKitAPI/Tests/WebKit2Cocoa/large-video-test-now-playing.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioPlatformMediaSessionManagerh">trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudiomacMediaSessionManagerMach">trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudiomacMediaSessionManagerMacmm">trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewPrivateh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPageClienth">trunk/Source/WebKit2/UIProcess/PageClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacPageClientImplh">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacPageClientImplmm">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm">trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaNowPlayingControlsTestsmm">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2Cocoalargevideotestnowplayinghtml">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-video-test-now-playing.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebCore/ChangeLog        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2016-10-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Media controls are displayed in the incorrect state momentarily after switching between tabs playing media
+        https://bugs.webkit.org/show_bug.cgi?id=162766
+        &lt;rdar://problem/28533523&gt;
+
+        Reviewed by Jer Noble.
+
+        When showing Now Playing controls for a media session, we should first set up the Now Playing info and
+        playback state before telling MediaRemote to make the session visible. This is WebKit work in ensuring that
+        when switching Now Playing sessions by switching tabs, we do not first display an invalid Now Playing state
+        before updating to the expected state.
+
+        Adds 2 new WebKit API tests in NowPlayingControlsTests: NowPlayingControlsHideAfterShowingClearsInfo and
+        NowPlayingControlsClearInfoAfterSessionIsNoLongerValid.
+
+        * platform/audio/PlatformMediaSessionManager.h:
+        (WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingTitle):
+        (WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingDuration):
+        (WebCore::PlatformMediaSessionManager::lastUpdatedNowPlayingElapsedTime):
+        (WebCore::PlatformMediaSessionManager::hasActiveNowPlayingSession): Deleted.
+        * platform/audio/mac/MediaSessionManagerMac.h:
+        * platform/audio/mac/MediaSessionManagerMac.mm:
+        (WebCore::MediaSessionManagerMac::updateNowPlayingInfo):
+
</ins><span class="cx"> 2016-10-04  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Fetch API] ReadableStream should be errored with TypeError values
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessionManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -58,6 +58,9 @@
</span><span class="cx">     bool canProduceAudio() const;
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT virtual bool hasActiveNowPlayingSession() const { return false; }
</span><ins>+    WEBCORE_EXPORT virtual String lastUpdatedNowPlayingTitle() const { return emptyString(); }
+    WEBCORE_EXPORT virtual double lastUpdatedNowPlayingDuration() const { return NAN; }
+    WEBCORE_EXPORT virtual double lastUpdatedNowPlayingElapsedTime() const { return NAN; }
</ins><span class="cx"> 
</span><span class="cx">     bool willIgnoreSystemInterruptions() const { return m_willIgnoreSystemInterruptions; }
</span><span class="cx">     void setWillIgnoreSystemInterruptions(bool ignore) { m_willIgnoreSystemInterruptions = ignore; }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudiomacMediaSessionManagerMach"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.h        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -37,6 +37,9 @@
</span><span class="cx">     virtual ~MediaSessionManagerMac();
</span><span class="cx"> 
</span><span class="cx">     bool hasActiveNowPlayingSession() const override { return m_nowPlayingActive; }
</span><ins>+    String lastUpdatedNowPlayingTitle() const override { return m_lastUpdatedNowPlayingTitle; }
+    double lastUpdatedNowPlayingDuration() const override { return m_lastUpdatedNowPlayingDuration; }
+    double lastUpdatedNowPlayingElapsedTime() const override { return m_lastUpdatedNowPlayingElapsedTime; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class PlatformMediaSessionManager;
</span><span class="lines">@@ -57,6 +60,12 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_nowPlayingActive { false };
</span><span class="cx">     bool m_isInBackground { false };
</span><ins>+
+    // For testing purposes only.
+    String m_lastUpdatedNowPlayingTitle;
+    double m_lastUpdatedNowPlayingDuration { NAN };
+    double m_lastUpdatedNowPlayingElapsedTime { NAN };
+
</ins><span class="cx">     GenericTaskQueue&lt;Timer&gt; m_nowPlayingUpdateTaskQueue;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudiomacMediaSessionManagerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -136,6 +136,9 @@
</span><span class="cx">             LOG(Media, &quot;MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info&quot;);
</span><span class="cx">             MRMediaRemoteSetNowPlayingInfo(nullptr);
</span><span class="cx">             m_nowPlayingActive = false;
</span><ins>+            m_lastUpdatedNowPlayingTitle = emptyString();
+            m_lastUpdatedNowPlayingDuration = NAN;
+            m_lastUpdatedNowPlayingElapsedTime = NAN;
</ins><span class="cx">             MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
</span><span class="cx"> #if LOG_DISABLED
</span><span class="cx">                 UNUSED_PARAM(error);
</span><span class="lines">@@ -153,20 +156,20 @@
</span><span class="cx">         MRMediaRemoteSetCanBeNowPlayingApplication(true);
</span><span class="cx">     });
</span><span class="cx"> 
</span><del>-    if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
-        MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityAlwaysVisible);
-
</del><span class="cx">     String title = currentSession-&gt;title();
</span><span class="cx">     double duration = currentSession-&gt;duration();
</span><span class="cx">     double rate = currentSession-&gt;state() == PlatformMediaSession::Playing ? 1 : 0;
</span><span class="cx">     auto info = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</span><span class="cx"> 
</span><del>-    if (!title.isEmpty())
</del><ins>+    if (!title.isEmpty()) {
</ins><span class="cx">         CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoTitle, title.createCFString().get());
</span><ins>+        m_lastUpdatedNowPlayingTitle = title;
+    }
</ins><span class="cx"> 
</span><span class="cx">     if (std::isfinite(duration) &amp;&amp; duration != MediaPlayer::invalidTime()) {
</span><span class="cx">         auto cfDuration = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &amp;duration));
</span><span class="cx">         CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoDuration, cfDuration.get());
</span><ins>+        m_lastUpdatedNowPlayingDuration = duration;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     auto cfRate = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &amp;rate);
</span><span class="lines">@@ -176,6 +179,7 @@
</span><span class="cx">     if (std::isfinite(currentTime) &amp;&amp; currentTime != MediaPlayer::invalidTime()) {
</span><span class="cx">         auto cfCurrentTime = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &amp;currentTime));
</span><span class="cx">         CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoElapsedTime, cfCurrentTime.get());
</span><ins>+        m_lastUpdatedNowPlayingElapsedTime = currentTime;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     LOG(Media, &quot;MediaSessionManagerMac::updateNowPlayingInfo - title = \&quot;%s\&quot;, rate = %f, duration = %f, now = %f&quot;,
</span><span class="lines">@@ -195,6 +199,9 @@
</span><span class="cx"> #endif
</span><span class="cx">     });
</span><span class="cx">     MRMediaRemoteSetNowPlayingInfo(info.get());
</span><ins>+
+    if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
+        MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityAlwaysVisible);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/ChangeLog        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2016-10-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Media controls are displayed in the incorrect state momentarily after switching between tabs playing media
+        https://bugs.webkit.org/show_bug.cgi?id=162766
+        &lt;rdar://problem/28533523&gt;
+
+        Reviewed by Jer Noble.
+
+        Plumbs some more Now Playing information from the web process to the UI process for testing purposes. See
+        WebCore ChangeLog for more details.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _handleActiveNowPlayingSessionInfoResponse:title:duration:elapsedTime:]):
+        (-[WKWebView _handleActiveNowPlayingSessionInfoResponse:]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::handleActiveNowPlayingSessionInfoResponse):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::handleActiveNowPlayingSessionInfoResponse):
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::requestActiveNowPlayingSessionInfo):
+
</ins><span class="cx"> 2016-10-04  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed GTK+ build fix.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -4591,7 +4591,7 @@
</span><span class="cx">         _page-&gt;requestActiveNowPlayingSessionInfo();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession
</del><ins>+- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime
</ins><span class="cx"> {
</span><span class="cx">     // Overridden by subclasses.
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -282,7 +282,7 @@
</span><span class="cx"> - (void)_didUpdateCandidateListVisibility:(BOOL)visible WK_API_AVAILABLE(macosx(WK_MAC_TBA));
</span><span class="cx"> @property (nonatomic, readonly) BOOL _shouldRequestCandidates WK_API_AVAILABLE(macosx(WK_MAC_TBA));
</span><span class="cx"> - (void)_requestActiveNowPlayingSessionInfo WK_API_AVAILABLE(macosx(WK_MAC_TBA));
</span><del>-- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession WK_API_AVAILABLE(macosx(WK_MAC_TBA));
</del><ins>+- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime WK_API_AVAILABLE(macosx(WK_MAC_TBA));
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> - (void)_doAfterNextPresentationUpdate:(void (^)(void))updateBlock WK_API_AVAILABLE(macosx(10.12), ios(10.0));
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/PageClient.h        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -248,7 +248,7 @@
</span><span class="cx">     virtual void recommendedScrollbarStyleDidChange(WebCore::ScrollbarStyle) = 0;
</span><span class="cx">     virtual void removeNavigationGestureSnapshot() = 0;
</span><span class="cx">     virtual void handleControlledElementIDResponse(const String&amp;) = 0;
</span><del>-    virtual void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession) = 0;
</del><ins>+    virtual void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String&amp; title, double duration, double elapsedTime) = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual CGRect boundsOfLayerInLayerBackedWindowCoordinates(CALayer *) const = 0;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -6387,9 +6387,9 @@
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::RequestActiveNowPlayingSessionInfo(), m_pageID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession) const
</del><ins>+void WebPageProxy::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String&amp; title, double duration, double elapsedTime) const
</ins><span class="cx"> {
</span><del>-    m_pageClient.handleActiveNowPlayingSessionInfoResponse(hasActiveSession);
</del><ins>+    m_pageClient.handleActiveNowPlayingSessionInfoResponse(hasActiveSession, title, duration, elapsedTime);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::handleControlledElementIDResponse(const String&amp; identifier) const
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -1036,7 +1036,7 @@
</span><span class="cx">     void requestControlledElementID() const;
</span><span class="cx">     void handleControlledElementIDResponse(const String&amp;) const;
</span><span class="cx">     void requestActiveNowPlayingSessionInfo();
</span><del>-    void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession) const;
</del><ins>+    void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String&amp; title, double duration, double elapsedTime) const;
</ins><span class="cx">     bool isPlayingVideoInEnhancedFullscreen() const;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -470,6 +470,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     DidHandleAcceptedCandidate()
</span><del>-    HandleActiveNowPlayingSessionInfoResponse(bool hasActiveSession)
</del><ins>+    HandleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, String title, double duration, double elapsedTime)
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -207,7 +207,7 @@
</span><span class="cx">     void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) override;
</span><span class="cx">     void removeNavigationGestureSnapshot() override;
</span><span class="cx">     void handleControlledElementIDResponse(const String&amp;) override;
</span><del>-    void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession) override;
</del><ins>+    void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String&amp; title, double duration, double elapsedTime) override;
</ins><span class="cx"> 
</span><span class="cx">     void didPerformImmediateActionHitTest(const WebHitTestResultData&amp;, bool contentPreventsDefault, API::Object*) override;
</span><span class="cx">     void* immediateActionAnimationControllerForHitTestResult(RefPtr&lt;API::HitTestResult&gt;, uint64_t, RefPtr&lt;API::Object&gt;) override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -759,10 +759,10 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PageClientImpl::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession)
</del><ins>+void PageClientImpl::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String&amp; title, double duration, double elapsedTime)
</ins><span class="cx"> {
</span><span class="cx"> #if WK_API_ENABLED
</span><del>-    [m_webView _handleActiveNowPlayingSessionInfoResponse:hasActiveSession];
</del><ins>+    [m_webView _handleActiveNowPlayingSessionInfoResponse:hasActiveSession title:nsStringFromWebCoreString(title) duration:duration elapsedTime:elapsedTime];
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacWebPageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -164,10 +164,17 @@
</span><span class="cx"> void WebPage::requestActiveNowPlayingSessionInfo()
</span><span class="cx"> {
</span><span class="cx">     bool hasActiveSession = false;
</span><del>-    if (auto* sharedManager = WebCore::PlatformMediaSessionManager::sharedManagerIfExists())
</del><ins>+    String title = emptyString();
+    double duration = NAN;
+    double elapsedTime = NAN;
+    if (auto* sharedManager = WebCore::PlatformMediaSessionManager::sharedManagerIfExists()) {
</ins><span class="cx">         hasActiveSession = sharedManager-&gt;hasActiveNowPlayingSession();
</span><ins>+        title = sharedManager-&gt;lastUpdatedNowPlayingTitle();
+        duration = sharedManager-&gt;lastUpdatedNowPlayingDuration();
+        elapsedTime = sharedManager-&gt;lastUpdatedNowPlayingElapsedTime();
+    }
</ins><span class="cx"> 
</span><del>-    send(Messages::WebPageProxy::HandleActiveNowPlayingSessionInfoResponse(hasActiveSession));
</del><ins>+    send(Messages::WebPageProxy::HandleActiveNowPlayingSessionInfoResponse(hasActiveSession, title, duration, elapsedTime));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NSObject *WebPage::accessibilityObjectForMainFramePlugin()
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Tools/ChangeLog        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-10-04  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        Media controls are displayed in the incorrect state momentarily after switching between tabs playing media
+        https://bugs.webkit.org/show_bug.cgi?id=162766
+        &lt;rdar://problem/28533523&gt;
+
+        Reviewed by Jer Noble.
+
+        Adds new tests and tweaks existing tests to verify last updated Now Playing information.
+
+        * TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm:
+        (-[NowPlayingTestWebView _handleActiveNowPlayingSessionInfoResponse:title:duration:elapsedTime:]):
+        (TestWebKitAPI::TEST):
+        (-[NowPlayingTestWebView _handleActiveNowPlayingSessionInfoResponse:]): Deleted.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/large-video-test-now-playing.html:
+
</ins><span class="cx"> 2016-10-03  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         URLParser should ignore tabs at all locations
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaNowPlayingControlsTestsmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -35,6 +35,9 @@
</span><span class="cx"> 
</span><span class="cx"> @interface NowPlayingTestWebView : TestWKWebView
</span><span class="cx"> @property (nonatomic, readonly) BOOL hasActiveNowPlayingSession;
</span><ins>+@property (readonly) NSString *lastUpdatedTitle;
+@property (readonly) double lastUpdatedDuration;
+@property (readonly) double lastUpdatedElapsedTime;
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> @implementation NowPlayingTestWebView {
</span><span class="lines">@@ -59,9 +62,13 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession
</del><ins>+- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime
</ins><span class="cx"> {
</span><span class="cx">     _hasActiveNowPlayingSession = hasActiveSession;
</span><ins>+    _lastUpdatedTitle = [title copy];
+    _lastUpdatedDuration = duration;
+    _lastUpdatedElapsedTime = elapsedTime;
+
</ins><span class="cx">     _receivedNowPlayingInfoResponse = true;
</span><span class="cx"> }
</span><span class="cx"> @end
</span><span class="lines">@@ -79,6 +86,10 @@
</span><span class="cx">     [webView.window setIsVisible:YES];
</span><span class="cx">     [webView.window makeKeyWindow];
</span><span class="cx">     [webView expectHasActiveNowPlayingSession:NO];
</span><ins>+
+    ASSERT_STREQ(&quot;&quot;, webView.lastUpdatedTitle.UTF8String);
+    ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
+    ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TEST(NowPlayingControlsTests, NowPlayingControlsShowForBackgroundPage)
</span><span class="lines">@@ -92,8 +103,54 @@
</span><span class="cx">     [webView.window setIsVisible:NO];
</span><span class="cx">     [webView.window resignKeyWindow];
</span><span class="cx">     [webView expectHasActiveNowPlayingSession:YES];
</span><ins>+
+    ASSERT_STREQ(&quot;foo&quot;, webView.lastUpdatedTitle.UTF8String);
+    ASSERT_EQ(10, webView.lastUpdatedDuration);
+    ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(NowPlayingControlsTests, NowPlayingControlsHideAfterShowingClearsInfo)
+{
+    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
+    configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
+    NowPlayingTestWebView *webView = [[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration];
+    [webView loadTestPageNamed:@&quot;large-video-test-now-playing&quot;];
+    [webView waitForMessage:@&quot;playing&quot;];
+
+    [webView.window setIsVisible:NO];
+    [webView.window resignKeyWindow];
+
+    [webView expectHasActiveNowPlayingSession:YES];
+
+    [webView.window setIsVisible:YES];
+    [webView.window makeKeyWindow];
+
+    [webView expectHasActiveNowPlayingSession:NO];
+
+    ASSERT_STREQ(&quot;&quot;, webView.lastUpdatedTitle.UTF8String);
+    ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
+    ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
+}
+
+TEST(NowPlayingControlsTests, NowPlayingControlsClearInfoAfterSessionIsNoLongerValid)
+{
+    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
+    configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
+    NowPlayingTestWebView *webView = [[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 480, 320) configuration:configuration];
+    [webView loadTestPageNamed:@&quot;large-video-test-now-playing&quot;];
+    [webView waitForMessage:@&quot;playing&quot;];
+
+    [webView mouseDownAtPoint:NSMakePoint(240, 160) simulatePressure:YES];
+    [webView.window setIsVisible:NO];
+    [webView.window resignKeyWindow];
+
+    [webView expectHasActiveNowPlayingSession:NO];
+
+    ASSERT_STREQ(&quot;&quot;, webView.lastUpdatedTitle.UTF8String);
+    ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
+    ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span><span class="cx"> 
</span><span class="cx"> #endif // WK_API_ENABLED &amp;&amp; PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MAX_ALLOWED &gt;= 101201
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2Cocoalargevideotestnowplayinghtml"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-video-test-now-playing.html (206770 => 206771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-video-test-now-playing.html        2016-10-04 15:17:34 UTC (rev 206770)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/large-video-test-now-playing.html        2016-10-04 15:35:30 UTC (rev 206771)
</span><span class="lines">@@ -7,6 +7,10 @@
</span><span class="cx">             height: 320px;
</span><span class="cx">             position: absolute;
</span><span class="cx">         }
</span><ins>+
+        body {
+            margin: 0;
+        }
</ins><span class="cx">     &lt;/style&gt;
</span><span class="cx">     &lt;script&gt;
</span><span class="cx">         function playing() {
</span><span class="lines">@@ -17,9 +21,13 @@
</span><span class="cx">                 }
</span><span class="cx">             }, 0);
</span><span class="cx">         }
</span><ins>+
+        function mousedown() {
+            document.querySelector(&quot;video&quot;).muted = true;
+        }
</ins><span class="cx">     &lt;/script&gt;
</span><span class="cx"> &lt;/head&gt;
</span><span class="cx"> &lt;body&gt;
</span><del>-    &lt;video autoplay onplaying=playing()&gt;&lt;source src=&quot;large-video-with-audio.mp4&quot;&gt;&lt;/video&gt;
</del><ins>+    &lt;video autoplay title=&quot;foo&quot; onmousedown=mousedown() onplaying=playing()&gt;&lt;source src=&quot;large-video-with-audio.mp4&quot;&gt;&lt;/video&gt;
</ins><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;html&gt;
</span></span></pre>
</div>
</div>

</body>
</html>