<!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>[206315] trunk/Source/WebCore</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/206315">206315</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2016-09-23 11:45:53 -0700 (Fri, 23 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>MediaSessionManagerMac::nowPlayingEligibleSession() needs to honor the main content heuristic
https://bugs.webkit.org/show_bug.cgi?id=162480
&lt;rdar://problem/28430615&gt;

Reviewed by Jer Noble.

Changes the implementation of nowPlayingEligibleSession to use bestMediaElementForShowingPlaybackControlsManager
and also early return nullptr if the current tab the web process is hosted in is the active tab, and the window
it is hosted in is the main window. This information is derived from the viewState flags in the Page of each
tab -- whenever the (visible &amp;&amp; active) state changes, the Page tells the global media session manager to update
its Now Playing info. Then, when each MediaElementSession tries to determine whether it can show playback
controls for the purposes of Now Playing, each session consults its page's visible and active state. If a page
is both visible and active, no Now Playing controls are allowed for that media session.

Also adds some slight adjustments to MediaSessionManagerMac::updateNowPlayingInfo, so we reset the title, rate
and duration of the current active session when clearing out the now playing info. Likewise, when vending an
active video, if the video information matches that of the current session, we mark m_nowPlayingActive anyways.
These tweaks prevent us from getting in a bad state when switching between a tab with media and one without.

Unit tests to come in a future patch.

* html/HTMLMediaElement.cpp:
(WebCore::mediaElementSessionInfoForSession):
(WebCore::mediaSessionMayBeConfusedWithMainContent):
(WebCore::HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager):
(WebCore::HTMLMediaElement::updatePlaybackControlsManager):
(WebCore::bestMediaSessionForShowingPlaybackControlsManager): Deleted.
* html/HTMLMediaElement.h:
* html/MediaElementSession.cpp:
(WebCore::MediaElementSession::canShowControlsManager):
(WebCore::MediaElementSession::pageAllowsNowPlayingControls):
* html/MediaElementSession.h:
* page/Page.cpp:
(WebCore::Page::setViewState):
(WebCore::Page::isVisibleAndActive):
* page/Page.h:
* platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary):
* platform/audio/PlatformMediaSessionManager.h:
* platform/audio/mac/MediaSessionManagerMac.mm:
(WebCore::PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary):
(WebCore::MediaSessionManagerMac::nowPlayingEligibleSession):
(WebCore::MediaSessionManagerMac::updateNowPlayingInfo):</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceWebCorehtmlMediaElementSessioncpp">trunk/Source/WebCore/html/MediaElementSession.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlMediaElementSessionh">trunk/Source/WebCore/html/MediaElementSession.h</a></li>
<li><a href="#trunkSourceWebCorepagePagecpp">trunk/Source/WebCore/page/Page.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePageh">trunk/Source/WebCore/page/Page.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioPlatformMediaSessionManagercpp">trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioPlatformMediaSessionManagerh">trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudiomacMediaSessionManagerMacmm">trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/ChangeLog        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2016-09-23  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        MediaSessionManagerMac::nowPlayingEligibleSession() needs to honor the main content heuristic
+        https://bugs.webkit.org/show_bug.cgi?id=162480
+        &lt;rdar://problem/28430615&gt;
+
+        Reviewed by Jer Noble.
+
+        Changes the implementation of nowPlayingEligibleSession to use bestMediaElementForShowingPlaybackControlsManager
+        and also early return nullptr if the current tab the web process is hosted in is the active tab, and the window
+        it is hosted in is the main window. This information is derived from the viewState flags in the Page of each
+        tab -- whenever the (visible &amp;&amp; active) state changes, the Page tells the global media session manager to update
+        its Now Playing info. Then, when each MediaElementSession tries to determine whether it can show playback
+        controls for the purposes of Now Playing, each session consults its page's visible and active state. If a page
+        is both visible and active, no Now Playing controls are allowed for that media session.
+
+        Also adds some slight adjustments to MediaSessionManagerMac::updateNowPlayingInfo, so we reset the title, rate
+        and duration of the current active session when clearing out the now playing info. Likewise, when vending an
+        active video, if the video information matches that of the current session, we mark m_nowPlayingActive anyways.
+        These tweaks prevent us from getting in a bad state when switching between a tab with media and one without.
+
+        Unit tests to come in a future patch.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::mediaElementSessionInfoForSession):
+        (WebCore::mediaSessionMayBeConfusedWithMainContent):
+        (WebCore::HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager):
+        (WebCore::HTMLMediaElement::updatePlaybackControlsManager):
+        (WebCore::bestMediaSessionForShowingPlaybackControlsManager): Deleted.
+        * html/HTMLMediaElement.h:
+        * html/MediaElementSession.cpp:
+        (WebCore::MediaElementSession::canShowControlsManager):
+        (WebCore::MediaElementSession::pageAllowsNowPlayingControls):
+        * html/MediaElementSession.h:
+        * page/Page.cpp:
+        (WebCore::Page::setViewState):
+        (WebCore::Page::isVisibleAndActive):
+        * page/Page.h:
+        * platform/audio/PlatformMediaSessionManager.cpp:
+        (WebCore::PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary):
+        * platform/audio/PlatformMediaSessionManager.h:
+        * platform/audio/mac/MediaSessionManagerMac.mm:
+        (WebCore::PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary):
+        (WebCore::MediaSessionManagerMac::nowPlayingEligibleSession):
+        (WebCore::MediaSessionManagerMac::updateNowPlayingInfo):
+
</ins><span class="cx"> 2016-09-23  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r206311.
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -358,13 +358,13 @@
</span><span class="cx">     bool isPlayingAudio : 1;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-static MediaElementSessionInfo mediaElementSessionInfoForSession(const MediaElementSession&amp; session)
</del><ins>+static MediaElementSessionInfo mediaElementSessionInfoForSession(const MediaElementSession&amp; session, MediaElementSession::PlaybackControlsPurpose purpose)
</ins><span class="cx"> {
</span><span class="cx">     const HTMLMediaElement&amp; element = session.element();
</span><span class="cx">     return {
</span><span class="cx">         &amp;session,
</span><span class="cx">         session.mostRecentUserInteractionTime(),
</span><del>-        session.canShowControlsManager(),
</del><ins>+        session.canShowControlsManager(purpose),
</ins><span class="cx">         element.isFullscreen() || element.isVisibleInViewport(),
</span><span class="cx">         session.isLargeEnoughForMainContent(MediaSessionMainContentPurpose::MediaControls),
</span><span class="cx">         element.isPlaying() &amp;&amp; element.hasAudio() &amp;&amp; !element.muted()
</span><span class="lines">@@ -381,8 +381,11 @@
</span><span class="cx">     return session.timeOfLastUserInteraction &gt; otherSession.timeOfLastUserInteraction;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool mediaSessionMayBeConfusedWithMainContent(const MediaElementSessionInfo&amp; session)
</del><ins>+static bool mediaSessionMayBeConfusedWithMainContent(const MediaElementSessionInfo&amp; session, MediaElementSession::PlaybackControlsPurpose purpose)
</ins><span class="cx"> {
</span><ins>+    if (purpose == MediaElementSession::PlaybackControlsPurpose::NowPlaying)
+        return session.isPlayingAudio;
+
</ins><span class="cx">     if (!session.isVisibleInViewportOrFullscreen)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -394,33 +397,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const MediaElementSession* bestMediaSessionForShowingPlaybackControlsManager()
-{
-    auto allSessions = PlatformMediaSessionManager::sharedManager().currentSessionsMatching([] (const PlatformMediaSession&amp; session) {
-        return is&lt;MediaElementSession&gt;(session);
-    });
-
-    Vector&lt;MediaElementSessionInfo&gt; candidateSessions;
-    bool atLeastOneNonCandidateMayBeConfusedForMainContent = false;
-    for (auto&amp; session : allSessions) {
-        auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast&lt;MediaElementSession&gt;(*session));
-        if (mediaElementSessionInfo.canShowControlsManager)
-            candidateSessions.append(mediaElementSessionInfo);
-        else if (mediaSessionMayBeConfusedWithMainContent(mediaElementSessionInfo))
-            atLeastOneNonCandidateMayBeConfusedForMainContent = true;
-    }
-
-    if (!candidateSessions.size())
-        return nullptr;
-
-    std::sort(candidateSessions.begin(), candidateSessions.end(), preferMediaControlsForCandidateSessionOverOtherCandidateSession);
-    auto strongestSessionCandidate = candidateSessions.first();
-    if (!strongestSessionCandidate.isVisibleInViewportOrFullscreen &amp;&amp; !strongestSessionCandidate.isPlayingAudio &amp;&amp; atLeastOneNonCandidateMayBeConfusedForMainContent)
-        return nullptr;
-
-    return strongestSessionCandidate.session;
-}
-
</del><span class="cx"> HTMLMediaElement::HTMLMediaElement(const QualifiedName&amp; tagName, Document&amp; document, bool createdByParser)
</span><span class="cx">     : HTMLElement(tagName, document)
</span><span class="cx">     , ActiveDOMObject(&amp;document)
</span><span class="lines">@@ -643,6 +619,33 @@
</span><span class="cx">     updatePlaybackControlsManager();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+HTMLMediaElement* HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose purpose)
+{
+    auto allSessions = PlatformMediaSessionManager::sharedManager().currentSessionsMatching([] (const PlatformMediaSession&amp; session) {
+        return is&lt;MediaElementSession&gt;(session);
+    });
+
+    Vector&lt;MediaElementSessionInfo&gt; candidateSessions;
+    bool atLeastOneNonCandidateMayBeConfusedForMainContent = false;
+    for (auto&amp; session : allSessions) {
+        auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast&lt;MediaElementSession&gt;(*session), purpose);
+        if (mediaElementSessionInfo.canShowControlsManager)
+            candidateSessions.append(mediaElementSessionInfo);
+        else if (mediaSessionMayBeConfusedWithMainContent(mediaElementSessionInfo, purpose))
+            atLeastOneNonCandidateMayBeConfusedForMainContent = true;
+    }
+
+    if (!candidateSessions.size())
+        return nullptr;
+
+    std::sort(candidateSessions.begin(), candidateSessions.end(), preferMediaControlsForCandidateSessionOverOtherCandidateSession);
+    auto strongestSessionCandidate = candidateSessions.first();
+    if (!strongestSessionCandidate.isVisibleInViewportOrFullscreen &amp;&amp; !strongestSessionCandidate.isPlayingAudio &amp;&amp; atLeastOneNonCandidateMayBeConfusedForMainContent)
+        return nullptr;
+
+    return &amp;strongestSessionCandidate.session-&gt;element();
+}
+
</ins><span class="cx"> void HTMLMediaElement::registerWithDocument(Document&amp; document)
</span><span class="cx"> {
</span><span class="cx">     m_mediaSession-&gt;registerWithDocument(document);
</span><span class="lines">@@ -7326,8 +7329,8 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // FIXME: Ensure that the renderer here should be up to date.
</span><del>-    if (auto bestMediaSession = bestMediaSessionForShowingPlaybackControlsManager())
-        page-&gt;chrome().client().setUpPlaybackControlsManager(bestMediaSession-&gt;element());
</del><ins>+    if (auto bestMediaElement = bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::ControlsManager))
+        page-&gt;chrome().client().setUpPlaybackControlsManager(*bestMediaElement);
</ins><span class="cx">     else
</span><span class="cx">         page-&gt;chrome().client().clearPlaybackControlsManager();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -115,6 +115,8 @@
</span><span class="cx"> 
</span><span class="cx">     static HashSet&lt;HTMLMediaElement*&gt;&amp; allMediaElements();
</span><span class="cx"> 
</span><ins>+    static HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose);
+
</ins><span class="cx">     void rewind(double timeDelta);
</span><span class="cx">     WEBCORE_EXPORT void returnToRealtime() override;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlMediaElementSessioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/MediaElementSession.cpp        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -216,8 +216,13 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool MediaElementSession::canShowControlsManager() const
</del><ins>+bool MediaElementSession::canShowControlsManager(PlaybackControlsPurpose purpose) const
</ins><span class="cx"> {
</span><ins>+    if (purpose == PlaybackControlsPurpose::NowPlaying &amp;&amp; !pageAllowsNowPlayingControls()) {
+        LOG(Media, &quot;MediaElementSession::canShowControlsManager - returning FALSE: Now playing not allowed in foreground tab&quot;);
+        return false;
+    }
+
</ins><span class="cx">     if (m_element.isFullscreen()) {
</span><span class="cx">         LOG(Media, &quot;MediaElementSession::canShowControlsManager - returning TRUE: Is fullscreen&quot;);
</span><span class="cx">         return true;
</span><span class="lines">@@ -228,7 +233,8 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_element.hasAudio() &amp;&amp; !m_element.hasEverHadAudio()) {
</del><ins>+    bool meetsAudioTrackRequirements = m_element.hasAudio() || (purpose == PlaybackControlsPurpose::ControlsManager &amp;&amp; m_element.hasEverHadAudio());
+    if (!meetsAudioTrackRequirements) {
</ins><span class="cx">         LOG(Media, &quot;MediaElementSession::canShowControlsManager - returning FALSE: No audio&quot;);
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -274,7 +280,7 @@
</span><span class="cx">             return false;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (!m_element.hasVideo() &amp;&amp; !m_element.hasEverHadVideo()) {
</del><ins>+        if (purpose == PlaybackControlsPurpose::ControlsManager &amp;&amp; !m_element.hasVideo() &amp;&amp; !m_element.hasEverHadVideo()) {
</ins><span class="cx">             LOG(Media, &quot;MediaElementSession::canShowControlsManager - returning FALSE: No video&quot;);
</span><span class="cx">             return false;
</span><span class="cx">         }
</span><span class="lines">@@ -722,6 +728,12 @@
</span><span class="cx">     return m_isMainContent;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool MediaElementSession::pageAllowsNowPlayingControls() const
+{
+    auto page = m_element.document().page();
+    return page &amp;&amp; !page-&gt;isVisibleAndActive();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> #endif // ENABLE(VIDEO)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlMediaElementSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/MediaElementSession.h (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/MediaElementSession.h        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/html/MediaElementSession.h        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -118,7 +118,9 @@
</span><span class="cx"> 
</span><span class="cx">     bool wantsToObserveViewportVisibilityForMediaControls() const;
</span><span class="cx">     bool wantsToObserveViewportVisibilityForAutoplay() const;
</span><del>-    bool canShowControlsManager() const;
</del><ins>+
+    enum class PlaybackControlsPurpose { ControlsManager, NowPlaying };
+    bool canShowControlsManager(PlaybackControlsPurpose) const;
</ins><span class="cx">     bool isLargeEnoughForMainContent(MediaSessionMainContentPurpose) const;
</span><span class="cx">     double mostRecentUserInteractionTime() const;
</span><span class="cx"> 
</span><span class="lines">@@ -138,6 +140,8 @@
</span><span class="cx">     bool updateIsMainContent() const;
</span><span class="cx">     void mainContentCheckTimerFired();
</span><span class="cx"> 
</span><ins>+    bool pageAllowsNowPlayingControls() const;
+
</ins><span class="cx">     HTMLMediaElement&amp; m_element;
</span><span class="cx">     BehaviorRestrictions m_restrictions;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.cpp (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.cpp        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/page/Page.cpp        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx"> #include &quot;PageGroup.h&quot;
</span><span class="cx"> #include &quot;PageOverlayController.h&quot;
</span><span class="cx"> #include &quot;PageThrottler.h&quot;
</span><ins>+#include &quot;PlatformMediaSessionManager.h&quot;
</ins><span class="cx"> #include &quot;PlugInClient.h&quot;
</span><span class="cx"> #include &quot;PluginData.h&quot;
</span><span class="cx"> #include &quot;PluginInfoProvider.h&quot;
</span><span class="lines">@@ -1449,7 +1450,9 @@
</span><span class="cx"> 
</span><span class="cx">     ViewState::Flags oldViewState = m_viewState;
</span><span class="cx"> 
</span><ins>+    bool wasVisibleAndActive = isVisibleAndActive();
</ins><span class="cx">     m_viewState = viewState;
</span><ins>+
</ins><span class="cx">     m_focusController-&gt;setViewState(viewState);
</span><span class="cx"> 
</span><span class="cx">     if (changed &amp; ViewState::IsVisible)
</span><span class="lines">@@ -1464,8 +1467,16 @@
</span><span class="cx"> 
</span><span class="cx">     for (auto* observer : m_viewStateChangeObservers)
</span><span class="cx">         observer-&gt;viewStateDidChange(oldViewState, m_viewState);
</span><ins>+
+    if (wasVisibleAndActive != isVisibleAndActive())
+        PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool Page::isVisibleAndActive() const
+{
+    return (m_viewState &amp; ViewState::IsVisible) &amp;&amp; (m_viewState &amp; ViewState::WindowIsActive);
+}
+
</ins><span class="cx"> void Page::setPageActivityState(PageActivityState::Flags activityState)
</span><span class="cx"> {
</span><span class="cx">     chrome().client().setPageActivityState(activityState);
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.h (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.h        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/page/Page.h        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -335,6 +335,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Notifications when the Page starts and stops being presented via a native window.
</span><span class="cx">     WEBCORE_EXPORT void setViewState(ViewState::Flags);
</span><ins>+    bool isVisibleAndActive() const;
</ins><span class="cx">     void setPageActivityState(PageActivityState::Flags);
</span><span class="cx">     WEBCORE_EXPORT void setIsVisible(bool);
</span><span class="cx">     WEBCORE_EXPORT void setIsPrerender();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessionManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -36,7 +36,13 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-#if !PLATFORM(IOS) &amp;&amp; !PLATFORM(MAC)
</del><ins>+#if !PLATFORM(MAC)
+
+void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
+{
+}
+
+#if !PLATFORM(IOS)
</ins><span class="cx"> static PlatformMediaSessionManager* platformMediaSessionManager = nullptr;
</span><span class="cx"> 
</span><span class="cx"> PlatformMediaSessionManager&amp; PlatformMediaSessionManager::sharedManager()
</span><span class="lines">@@ -50,8 +56,10 @@
</span><span class="cx"> {
</span><span class="cx">     return platformMediaSessionManager;
</span><span class="cx"> }
</span><del>-#endif
</del><ins>+#endif // !PLATFORM(IOS)
</ins><span class="cx"> 
</span><ins>+#endif // !PLATFORM(MAC)
+
</ins><span class="cx"> PlatformMediaSessionManager::PlatformMediaSessionManager()
</span><span class="cx">     : m_systemSleepListener(SystemSleepListener::create(*this))
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessionManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -46,6 +46,9 @@
</span><span class="cx"> public:
</span><span class="cx">     WEBCORE_EXPORT static PlatformMediaSessionManager* sharedManagerIfExists();
</span><span class="cx">     WEBCORE_EXPORT static PlatformMediaSessionManager&amp; sharedManager();
</span><ins>+
+    static void updateNowPlayingInfoIfNecessary();
+
</ins><span class="cx">     virtual ~PlatformMediaSessionManager() { }
</span><span class="cx"> 
</span><span class="cx">     bool has(PlatformMediaSession::MediaType) const;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudiomacMediaSessionManagerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (206314 => 206315)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm        2016-09-23 18:09:44 UTC (rev 206314)
+++ trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm        2016-09-23 18:45:53 UTC (rev 206315)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx"> 
</span><ins>+#import &quot;HTMLMediaElement.h&quot;
</ins><span class="cx"> #import &quot;Logging.h&quot;
</span><span class="cx"> #import &quot;MediaPlayer.h&quot;
</span><span class="cx"> #import &quot;PlatformMediaSession.h&quot;
</span><span class="lines">@@ -52,6 +53,12 @@
</span><span class="cx">     return platformMediaSessionManager;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
+{
+    if (auto existingManager = (MediaSessionManagerMac *)PlatformMediaSessionManager::sharedManagerIfExists())
+        existingManager-&gt;updateNowPlayingInfo();
+}
+
</ins><span class="cx"> MediaSessionManagerMac::MediaSessionManagerMac()
</span><span class="cx">     : PlatformMediaSessionManager()
</span><span class="cx"> {
</span><span class="lines">@@ -94,15 +101,9 @@
</span><span class="cx"> 
</span><span class="cx"> PlatformMediaSession* MediaSessionManagerMac::nowPlayingEligibleSession()
</span><span class="cx"> {
</span><del>-    for (auto session : sessions()) {
-        PlatformMediaSession::MediaType type = session-&gt;mediaType();
-        if (type != PlatformMediaSession::Video &amp;&amp; type != PlatformMediaSession::Audio)
-            continue;
</del><ins>+    if (auto element = HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::NowPlaying))
+        return &amp;element-&gt;mediaSession();
</ins><span class="cx"> 
</span><del>-        if (session-&gt;characteristics() &amp; PlatformMediaSession::HasAudio)
-            return session;
-    }
-
</del><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -122,6 +123,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_reportedTitle = &quot;&quot;;
+            m_reportedRate = 0;
+            m_reportedDuration = 0;
</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">@@ -143,6 +147,7 @@
</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">     if (m_reportedTitle == title &amp;&amp; m_reportedRate == rate &amp;&amp; m_reportedDuration == duration) {
</span><ins>+        m_nowPlayingActive = true;
</ins><span class="cx">         LOG(Media, &quot;MediaSessionManagerMac::updateNowPlayingInfo - nothing new to show&quot;);
</span><span class="cx">         return;
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>