<!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>[199351] 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/199351">199351</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2016-04-12 08:19:31 -0700 (Tue, 12 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] media title sometimes remain in Control Center after tab is closed
https://bugs.webkit.org/show_bug.cgi?id=156243
&lt;rdar://problem/20167445&gt;

Reviewed by Darin Adler.

* Modules/webaudio/AudioContext.h: Implement characteristics.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaLoadingFailed): Call mediaSession-&gt;clientCharacteristicsChanged.
(WebCore::HTMLMediaElement::setReadyState): Ditto.
(WebCore::HTMLMediaElement::clearMediaPlayer): Ditto.
(WebCore::HTMLMediaElement::stop): Call mediaSession-&gt;stopSession.
(WebCore::HTMLMediaElement::characteristics): New, return current characteristics.
* html/HTMLMediaElement.h:

* platform/audio/PlatformMediaSession.cpp:
(WebCore::PlatformMediaSession::stopSession): Suspend playback, and remove the session
  from the manager, it will never play again.
(WebCore::PlatformMediaSession::characteristics): Return client characteristics.
(WebCore::PlatformMediaSession::clientCharacteristicsChanged):
* platform/audio/PlatformMediaSession.h:

* platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForProcess): Call stopSession
  instead of pauseSession to signal that playback will never start again.
* platform/audio/PlatformMediaSessionManager.h:

* platform/audio/ios/MediaSessionManagerIOS.h:
* platform/audio/ios/MediaSessionManagerIOS.mm:
(WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Add logging.
(WebCore::MediaSessionManageriOS::removeSession): Update NowPlaying.
(WebCore::MediaSessionManageriOS::sessionWillEndPlayback): Add logging.
(WebCore::MediaSessionManageriOS::clientCharacteristicsChanged): Update NowPlaying.
(WebCore::MediaSessionManageriOS::nowPlayingEligibleSession): New, return the first session
  that is an audio or video element with playable audio. WebAudio is not currently controllable
  so it isn't appropriate to show it in the NowPlaying info center.
(WebCore::MediaSessionManageriOS::updateNowPlayingInfo): Remember the last state passed to
  NowPlaying so we can call it only when something has changed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioAudioContexth">trunk/Source/WebCore/Modules/webaudio/AudioContext.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="#trunkSourceWebCoreplatformaudioPlatformMediaSessioncpp">trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioPlatformMediaSessionh">trunk/Source/WebCore/platform/audio/PlatformMediaSession.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="#trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSh">trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSmm">trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/ChangeLog        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2016-04-12  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [iOS] media title sometimes remain in Control Center after tab is closed
+        https://bugs.webkit.org/show_bug.cgi?id=156243
+        &lt;rdar://problem/20167445&gt;
+
+        Reviewed by Darin Adler.
+
+        * Modules/webaudio/AudioContext.h: Implement characteristics.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::mediaLoadingFailed): Call mediaSession-&gt;clientCharacteristicsChanged.
+        (WebCore::HTMLMediaElement::setReadyState): Ditto.
+        (WebCore::HTMLMediaElement::clearMediaPlayer): Ditto.
+        (WebCore::HTMLMediaElement::stop): Call mediaSession-&gt;stopSession.
+        (WebCore::HTMLMediaElement::characteristics): New, return current characteristics.
+        * html/HTMLMediaElement.h:
+
+        * platform/audio/PlatformMediaSession.cpp:
+        (WebCore::PlatformMediaSession::stopSession): Suspend playback, and remove the session 
+          from the manager, it will never play again.
+        (WebCore::PlatformMediaSession::characteristics): Return client characteristics.
+        (WebCore::PlatformMediaSession::clientCharacteristicsChanged):
+        * platform/audio/PlatformMediaSession.h:
+
+        * platform/audio/PlatformMediaSessionManager.cpp:
+        (WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForProcess): Call stopSession 
+          instead of pauseSession to signal that playback will never start again.
+        * platform/audio/PlatformMediaSessionManager.h:
+
+        * platform/audio/ios/MediaSessionManagerIOS.h:
+        * platform/audio/ios/MediaSessionManagerIOS.mm:
+        (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Add logging.
+        (WebCore::MediaSessionManageriOS::removeSession): Update NowPlaying.
+        (WebCore::MediaSessionManageriOS::sessionWillEndPlayback): Add logging.
+        (WebCore::MediaSessionManageriOS::clientCharacteristicsChanged): Update NowPlaying.
+        (WebCore::MediaSessionManageriOS::nowPlayingEligibleSession): New, return the first session
+          that is an audio or video element with playable audio. WebAudio is not currently controllable
+          so it isn't appropriate to show it in the NowPlaying info center.
+        (WebCore::MediaSessionManageriOS::updateNowPlayingInfo): Remember the last state passed to
+          NowPlaying so we can call it only when something has changed.
+
</ins><span class="cx"> 2016-04-12  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Rework scrollbars theming code for GTK+ 3.20
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioAudioContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.h (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/AudioContext.h        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.h        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -318,6 +318,7 @@
</span><span class="cx">     // PlatformMediaSessionClient
</span><span class="cx">     PlatformMediaSession::MediaType mediaType() const override { return PlatformMediaSession::WebAudio; }
</span><span class="cx">     PlatformMediaSession::MediaType presentationType() const override { return PlatformMediaSession::WebAudio; }
</span><ins>+    PlatformMediaSession::CharacteristicsFlags characteristics() const override { return m_state == State::Running ? PlatformMediaSession::HasAudio : PlatformMediaSession::HasNothing; }
</ins><span class="cx">     void mayResumePlayback(bool shouldResume) override;
</span><span class="cx">     void suspendPlayback() override;
</span><span class="cx">     bool canReceiveRemoteControlCommands() const override { return false; }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -2058,6 +2058,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     logMediaLoadRequest(document().page(), String(), stringForNetworkState(error), false);
</span><ins>+
+    m_mediaSession-&gt;clientCharacteristicsChanged();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
</span><span class="lines">@@ -2213,6 +2215,8 @@
</span><span class="cx"> #if ENABLE(WIRELESS_PLAYBACK_TARGET)
</span><span class="cx">         updateMediaState(UpdateMediaState::Asynchronously);
</span><span class="cx"> #endif
</span><ins>+
+        m_mediaSession-&gt;clientCharacteristicsChanged();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool shouldUpdateDisplayState = false;
</span><span class="lines">@@ -5004,6 +5008,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     m_mediaSession-&gt;setCanProduceAudio(false);
</span><ins>+    m_mediaSession-&gt;clientCharacteristicsChanged();
</ins><span class="cx"> 
</span><span class="cx">     updateSleepDisabling();
</span><span class="cx"> }
</span><span class="lines">@@ -5064,6 +5069,8 @@
</span><span class="cx">     // if the media was not fully loaded, but we need the same cleanup if the file was completely
</span><span class="cx">     // loaded and calling it again won't cause any problems.
</span><span class="cx">     clearMediaPlayer(EveryDelayedAction);
</span><ins>+
+    m_mediaSession-&gt;stopSession();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::suspend(ReasonForSuspension why)
</span><span class="lines">@@ -6577,6 +6584,20 @@
</span><span class="cx">     return PlatformMediaSession::Normal;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+PlatformMediaSession::CharacteristicsFlags HTMLMediaElement::characteristics() const
+{
+    if (m_readyState &lt; HAVE_METADATA)
+        return PlatformMediaSession::HasNothing;
+
+    PlatformMediaSession::CharacteristicsFlags state = PlatformMediaSession::HasNothing;
+    if (isVideo() &amp;&amp; hasVideo())
+        state |= PlatformMediaSession::HasVideo;
+    if (this-&gt;hasAudio())
+        state |= PlatformMediaSession::HasAudio;
+
+    return state;
+}
+
</ins><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><span class="cx"> size_t HTMLMediaElement::maximumSourceBufferSize(const SourceBuffer&amp; buffer) const
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -738,6 +738,8 @@
</span><span class="cx">     PlatformMediaSession::MediaType mediaType() const override;
</span><span class="cx">     PlatformMediaSession::MediaType presentationType() const override;
</span><span class="cx">     PlatformMediaSession::DisplayType displayType() const override;
</span><ins>+    PlatformMediaSession::CharacteristicsFlags characteristics() const final;
+
</ins><span class="cx">     void suspendPlayback() override;
</span><span class="cx">     void resumeAutoplaying() override;
</span><span class="cx">     void mayResumePlayback(bool shouldResume) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -103,8 +103,10 @@
</span><span class="cx">     if (++m_interruptionCount &gt; 1)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (client().shouldOverrideBackgroundPlaybackRestriction(type))
</del><ins>+    if (client().shouldOverrideBackgroundPlaybackRestriction(type)) {
+        LOG(Media, &quot;PlatformMediaSession::beginInterruption(%p), returning early because client says to override interruption&quot;, this);
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     m_stateToRestore = state();
</span><span class="cx">     m_notifyingClient = true;
</span><span class="lines">@@ -195,6 +197,13 @@
</span><span class="cx">     m_client.suspendPlayback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PlatformMediaSession::stopSession()
+{
+    LOG(Media, &quot;PlatformMediaSession::stopSession(%p)&quot;, this);
+    m_client.suspendPlayback();
+    PlatformMediaSessionManager::sharedManager().removeSession(*this);
+}
+
</ins><span class="cx"> PlatformMediaSession::MediaType PlatformMediaSession::mediaType() const
</span><span class="cx"> {
</span><span class="cx">     return m_client.mediaType();
</span><span class="lines">@@ -205,6 +214,11 @@
</span><span class="cx">     return m_client.presentationType();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+PlatformMediaSession::CharacteristicsFlags PlatformMediaSession::characteristics() const
+{
+    return m_client.characteristics();
+}
+
</ins><span class="cx"> #if ENABLE(VIDEO)
</span><span class="cx"> String PlatformMediaSession::title() const
</span><span class="cx"> {
</span><span class="lines">@@ -318,5 +332,10 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void PlatformMediaSession::clientCharacteristicsChanged()
+{
+    PlatformMediaSessionManager::sharedManager().clientCharacteristicsChanged(*this);
</ins><span class="cx"> }
</span><ins>+
+}
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.h (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.h        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.h        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -86,6 +86,16 @@
</span><span class="cx">         MayResumePlaying = 1 &lt;&lt; 0,
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    enum Characteristics {
+        HasNothing = 0,
+        HasAudio = 1 &lt;&lt; 0,
+        HasVideo = 1 &lt;&lt; 1,
+    };
+    typedef unsigned CharacteristicsFlags;
+
+    CharacteristicsFlags characteristics() const;
+    void clientCharacteristicsChanged();
+
</ins><span class="cx">     void beginInterruption(InterruptionType);
</span><span class="cx">     void endInterruption(EndInterruptionFlags);
</span><span class="cx"> 
</span><span class="lines">@@ -94,6 +104,7 @@
</span><span class="cx">     bool clientWillPausePlayback();
</span><span class="cx"> 
</span><span class="cx">     void pauseSession();
</span><ins>+    void stopSession();
</ins><span class="cx">     
</span><span class="cx">     void visibilityChanged();
</span><span class="cx"> 
</span><span class="lines">@@ -173,6 +184,7 @@
</span><span class="cx">     virtual PlatformMediaSession::MediaType mediaType() const = 0;
</span><span class="cx">     virtual PlatformMediaSession::MediaType presentationType() const = 0;
</span><span class="cx">     virtual PlatformMediaSession::DisplayType displayType() const { return PlatformMediaSession::Normal; }
</span><ins>+    virtual PlatformMediaSession::CharacteristicsFlags characteristics() const = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual void resumeAutoplaying() { }
</span><span class="cx">     virtual void mayResumePlayback(bool shouldResume) = 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessionManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -153,7 +153,6 @@
</span><span class="cx">     LOG(Media, &quot;PlatformMediaSessionManager::removeSession - %p&quot;, &amp;session);
</span><span class="cx">     
</span><span class="cx">     size_t index = m_sessions.find(&amp;session);
</span><del>-    ASSERT(index != notFound);
</del><span class="cx">     if (index == notFound)
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="lines">@@ -380,7 +379,7 @@
</span><span class="cx"> {
</span><span class="cx">     Vector&lt;PlatformMediaSession*&gt; sessions = m_sessions;
</span><span class="cx">     for (auto* session : sessions)
</span><del>-        session-&gt;pauseSession();
</del><ins>+        session-&gt;stopSession();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessionManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -82,6 +82,7 @@
</span><span class="cx">     virtual bool sessionWillBeginPlayback(PlatformMediaSession&amp;);
</span><span class="cx">     virtual void sessionWillEndPlayback(PlatformMediaSession&amp;);
</span><span class="cx">     virtual bool sessionCanLoadMedia(const PlatformMediaSession&amp;) const;
</span><ins>+    virtual void clientCharacteristicsChanged(PlatformMediaSession&amp;) { }
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     virtual void configureWireLessTargetMonitoring() { }
</span><span class="lines">@@ -99,7 +100,7 @@
</span><span class="cx">     explicit PlatformMediaSessionManager();
</span><span class="cx"> 
</span><span class="cx">     void addSession(PlatformMediaSession&amp;);
</span><del>-    void removeSession(PlatformMediaSession&amp;);
</del><ins>+    virtual void removeSession(PlatformMediaSession&amp;);
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;PlatformMediaSession*&gt; sessions() { return m_sessions; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -56,9 +56,12 @@
</span><span class="cx"> 
</span><span class="cx">     MediaSessionManageriOS();
</span><span class="cx"> 
</span><ins>+    void removeSession(PlatformMediaSession&amp;) override;
+
</ins><span class="cx">     bool sessionWillBeginPlayback(PlatformMediaSession&amp;) override;
</span><span class="cx">     void sessionWillEndPlayback(PlatformMediaSession&amp;) override;
</span><del>-    
</del><ins>+    void clientCharacteristicsChanged(PlatformMediaSession&amp;) override;
+
</ins><span class="cx">     void updateNowPlayingInfo();
</span><span class="cx">     
</span><span class="cx">     void resetRestrictions() override;
</span><span class="lines">@@ -66,8 +69,11 @@
</span><span class="cx">     void configureWireLessTargetMonitoring() override;
</span><span class="cx"> 
</span><span class="cx">     bool sessionCanLoadMedia(const PlatformMediaSession&amp;) const override;
</span><ins>+
+    PlatformMediaSession* nowPlayingEligibleSession();
</ins><span class="cx">     
</span><span class="cx">     RetainPtr&lt;WebMediaSessionHelper&gt; m_objcObserver;
</span><ins>+    RetainPtr&lt;NSMutableDictionary&gt; m_nowPlayingInfo;
</ins><span class="cx">     bool m_isInBackground { false };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm (199350 => 199351)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm        2016-04-12 14:56:10 UTC (rev 199350)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm        2016-04-12 15:19:31 UTC (rev 199351)
</span><span class="lines">@@ -193,43 +193,87 @@
</span><span class="cx">     if (!PlatformMediaSessionManager::sessionWillBeginPlayback(session))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    LOG(Media, &quot;MediaSessionManageriOS::sessionWillBeginPlayback&quot;);
</ins><span class="cx">     updateNowPlayingInfo();
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><del>-    
</del><ins>+
+void MediaSessionManageriOS::removeSession(PlatformMediaSession&amp; session)
+{
+    PlatformMediaSessionManager::removeSession(session);
+    LOG(Media, &quot;MediaSessionManageriOS::removeSession&quot;);
+    updateNowPlayingInfo();
+}
+
</ins><span class="cx"> void MediaSessionManageriOS::sessionWillEndPlayback(PlatformMediaSession&amp; session)
</span><span class="cx"> {
</span><span class="cx">     PlatformMediaSessionManager::sessionWillEndPlayback(session);
</span><ins>+    LOG(Media, &quot;MediaSessionManageriOS::sessionWillEndPlayback&quot;);
</ins><span class="cx">     updateNowPlayingInfo();
</span><span class="cx"> }
</span><del>-    
</del><ins>+
+void MediaSessionManageriOS::clientCharacteristicsChanged(PlatformMediaSession&amp;)
+{
+    LOG(Media, &quot;MediaSessionManageriOS::clientCharacteristicsChanged&quot;);
+    updateNowPlayingInfo();
+}
+
+PlatformMediaSession* MediaSessionManageriOS::nowPlayingEligibleSession()
+{
+    for (auto session : sessions()) {
+        PlatformMediaSession::MediaType type = session-&gt;mediaType();
+        if (type != PlatformMediaSession::Video &amp;&amp; type != PlatformMediaSession::Audio)
+            continue;
+
+        if (session-&gt;characteristics() &amp; PlatformMediaSession::HasAudio)
+            return session;
+    }
+
+    return nullptr;
+}
+
</ins><span class="cx"> void MediaSessionManageriOS::updateNowPlayingInfo()
</span><span class="cx"> {
</span><del>-    LOG(Media, &quot;MediaSessionManageriOS::updateNowPlayingInfo&quot;);
</del><ins>+    MPNowPlayingInfoCenter *nowPlaying = (MPNowPlayingInfoCenter *)[getMPNowPlayingInfoCenterClass() defaultCenter];
+    const PlatformMediaSession* currentSession = this-&gt;nowPlayingEligibleSession();
</ins><span class="cx"> 
</span><del>-    MPNowPlayingInfoCenter *nowPlaying = (MPNowPlayingInfoCenter *)[getMPNowPlayingInfoCenterClass() defaultCenter];
-    const PlatformMediaSession* currentSession = this-&gt;currentSession();
-    
</del><ins>+    LOG(Media, &quot;MediaSessionManageriOS::updateNowPlayingInfo - currentSession = %p&quot;, currentSession);
+
</ins><span class="cx">     if (!currentSession) {
</span><del>-        [nowPlaying setNowPlayingInfo:nil];
</del><ins>+        if (m_nowPlayingInfo) {
+            LOG(Media, &quot;MediaSessionManageriOS::updateNowPlayingInfo - clearing now playing info&quot;);
+            [nowPlaying setNowPlayingInfo:nil];
+            m_nowPlayingInfo = nil;
+        }
+
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     RetainPtr&lt;NSMutableDictionary&gt; info = adoptNS([[NSMutableDictionary alloc] init]);
</span><del>-    
</del><ins>+
</ins><span class="cx">     String title = currentSession-&gt;title();
</span><span class="cx">     if (!title.isEmpty())
</span><span class="cx">         [info setValue:static_cast&lt;NSString *&gt;(title) forKey:MPMediaItemPropertyTitle];
</span><del>-    
</del><ins>+
</ins><span class="cx">     double duration = currentSession-&gt;duration();
</span><span class="cx">     if (std::isfinite(duration) &amp;&amp; duration != MediaPlayer::invalidTime())
</span><span class="cx">         [info setValue:@(duration) forKey:MPMediaItemPropertyPlaybackDuration];
</span><del>-    
</del><ins>+
+    [info setValue:(currentSession-&gt;state() == PlatformMediaSession::Playing ? @YES : @NO) forKey:MPNowPlayingInfoPropertyPlaybackRate];
+
+    if ([m_nowPlayingInfo.get() isEqualToDictionary:info.get()]) {
+        LOG(Media, &quot;MediaSessionManageriOS::updateNowPlayingInfo - nothing new to show&quot;);
+        return;
+    }
+
+    m_nowPlayingInfo = info;
+
</ins><span class="cx">     double currentTime = currentSession-&gt;currentTime();
</span><span class="cx">     if (std::isfinite(currentTime) &amp;&amp; currentTime != MediaPlayer::invalidTime())
</span><span class="cx">         [info setValue:@(currentTime) forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
</span><del>-    
-    [info setValue:(currentSession-&gt;state() == PlatformMediaSession::Playing ? @YES : @NO) forKey:MPNowPlayingInfoPropertyPlaybackRate];
</del><ins>+
+    LOG(Media, &quot;MediaSessionManageriOS::updateNowPlayingInfo - title = \&quot;%s\&quot;&quot;, [[info.get() valueForKey:MPMediaItemPropertyTitle] UTF8String]);
+
</ins><span class="cx">     [nowPlaying setNowPlayingInfo:info.get()];
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>