MediaSessionManagerMac::nowPlayingEligibleSession() needs to honor the main content...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Sep 2016 18:45:53 +0000 (18:45 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Sep 2016 18:45:53 +0000 (18:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162480
<rdar://problem/28430615>

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 && 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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206315 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/MediaElementSession.cpp
Source/WebCore/html/MediaElementSession.h
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp
Source/WebCore/platform/audio/PlatformMediaSessionManager.h
Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm

index ed2e588c6dc4c69285c12a44f445a19c1207b448..5d9d3a2b448a7be8737fb391dfca17be7b9ff4a0 100644 (file)
@@ -1,3 +1,49 @@
+2016-09-23  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        MediaSessionManagerMac::nowPlayingEligibleSession() needs to honor the main content heuristic
+        https://bugs.webkit.org/show_bug.cgi?id=162480
+        <rdar://problem/28430615>
+
+        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 && 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):
+
 2016-09-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r206311.
 2016-09-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r206311.
index 69730a7972b17b9dce97e31e1b22db446b442d42..b285d5c04cf871bd57b9634dc6b539a1dc4228d8 100644 (file)
@@ -358,13 +358,13 @@ struct MediaElementSessionInfo {
     bool isPlayingAudio : 1;
 };
 
     bool isPlayingAudio : 1;
 };
 
-static MediaElementSessionInfo mediaElementSessionInfoForSession(const MediaElementSession& session)
+static MediaElementSessionInfo mediaElementSessionInfoForSession(const MediaElementSession& session, MediaElementSession::PlaybackControlsPurpose purpose)
 {
     const HTMLMediaElement& element = session.element();
     return {
         &session,
         session.mostRecentUserInteractionTime(),
 {
     const HTMLMediaElement& element = session.element();
     return {
         &session,
         session.mostRecentUserInteractionTime(),
-        session.canShowControlsManager(),
+        session.canShowControlsManager(purpose),
         element.isFullscreen() || element.isVisibleInViewport(),
         session.isLargeEnoughForMainContent(MediaSessionMainContentPurpose::MediaControls),
         element.isPlaying() && element.hasAudio() && !element.muted()
         element.isFullscreen() || element.isVisibleInViewport(),
         session.isLargeEnoughForMainContent(MediaSessionMainContentPurpose::MediaControls),
         element.isPlaying() && element.hasAudio() && !element.muted()
@@ -381,8 +381,11 @@ static bool preferMediaControlsForCandidateSessionOverOtherCandidateSession(cons
     return session.timeOfLastUserInteraction > otherSession.timeOfLastUserInteraction;
 }
 
     return session.timeOfLastUserInteraction > otherSession.timeOfLastUserInteraction;
 }
 
-static bool mediaSessionMayBeConfusedWithMainContent(const MediaElementSessionInfo& session)
+static bool mediaSessionMayBeConfusedWithMainContent(const MediaElementSessionInfo& session, MediaElementSession::PlaybackControlsPurpose purpose)
 {
 {
+    if (purpose == MediaElementSession::PlaybackControlsPurpose::NowPlaying)
+        return session.isPlayingAudio;
+
     if (!session.isVisibleInViewportOrFullscreen)
         return false;
 
     if (!session.isVisibleInViewportOrFullscreen)
         return false;
 
@@ -394,33 +397,6 @@ static bool mediaSessionMayBeConfusedWithMainContent(const MediaElementSessionIn
     return true;
 }
 
     return true;
 }
 
-static const MediaElementSession* bestMediaSessionForShowingPlaybackControlsManager()
-{
-    auto allSessions = PlatformMediaSessionManager::sharedManager().currentSessionsMatching([] (const PlatformMediaSession& session) {
-        return is<MediaElementSession>(session);
-    });
-
-    Vector<MediaElementSessionInfo> candidateSessions;
-    bool atLeastOneNonCandidateMayBeConfusedForMainContent = false;
-    for (auto& session : allSessions) {
-        auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast<MediaElementSession>(*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 && !strongestSessionCandidate.isPlayingAudio && atLeastOneNonCandidateMayBeConfusedForMainContent)
-        return nullptr;
-
-    return strongestSessionCandidate.session;
-}
-
 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
     : HTMLElement(tagName, document)
     , ActiveDOMObject(&document)
 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
     : HTMLElement(tagName, document)
     , ActiveDOMObject(&document)
@@ -643,6 +619,33 @@ HTMLMediaElement::~HTMLMediaElement()
     updatePlaybackControlsManager();
 }
 
     updatePlaybackControlsManager();
 }
 
+HTMLMediaElement* HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose purpose)
+{
+    auto allSessions = PlatformMediaSessionManager::sharedManager().currentSessionsMatching([] (const PlatformMediaSession& session) {
+        return is<MediaElementSession>(session);
+    });
+
+    Vector<MediaElementSessionInfo> candidateSessions;
+    bool atLeastOneNonCandidateMayBeConfusedForMainContent = false;
+    for (auto& session : allSessions) {
+        auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast<MediaElementSession>(*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 && !strongestSessionCandidate.isPlayingAudio && atLeastOneNonCandidateMayBeConfusedForMainContent)
+        return nullptr;
+
+    return &strongestSessionCandidate.session->element();
+}
+
 void HTMLMediaElement::registerWithDocument(Document& document)
 {
     m_mediaSession->registerWithDocument(document);
 void HTMLMediaElement::registerWithDocument(Document& document)
 {
     m_mediaSession->registerWithDocument(document);
@@ -7326,8 +7329,8 @@ void HTMLMediaElement::updatePlaybackControlsManager()
         return;
 
     // FIXME: Ensure that the renderer here should be up to date.
         return;
 
     // FIXME: Ensure that the renderer here should be up to date.
-    if (auto bestMediaSession = bestMediaSessionForShowingPlaybackControlsManager())
-        page->chrome().client().setUpPlaybackControlsManager(bestMediaSession->element());
+    if (auto bestMediaElement = bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::ControlsManager))
+        page->chrome().client().setUpPlaybackControlsManager(*bestMediaElement);
     else
         page->chrome().client().clearPlaybackControlsManager();
 }
     else
         page->chrome().client().clearPlaybackControlsManager();
 }
index c9cb6a85b2dc63124e3b7129c0e42fb7cc1b047b..7cd0ff3b768ab3325b27c5b032a7ab7a00ef80a3 100644 (file)
@@ -115,6 +115,8 @@ public:
 
     static HashSet<HTMLMediaElement*>& allMediaElements();
 
 
     static HashSet<HTMLMediaElement*>& allMediaElements();
 
+    static HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose);
+
     void rewind(double timeDelta);
     WEBCORE_EXPORT void returnToRealtime() override;
 
     void rewind(double timeDelta);
     WEBCORE_EXPORT void returnToRealtime() override;
 
index 50fb7e139b1519ade95ce9c847c1bd5cd2b63b16..f9811ea7d506c427632d0dcde2227868328c4f37 100644 (file)
@@ -216,8 +216,13 @@ bool MediaElementSession::pageAllowsPlaybackAfterResuming(const HTMLMediaElement
     return true;
 }
 
     return true;
 }
 
-bool MediaElementSession::canShowControlsManager() const
+bool MediaElementSession::canShowControlsManager(PlaybackControlsPurpose purpose) const
 {
 {
+    if (purpose == PlaybackControlsPurpose::NowPlaying && !pageAllowsNowPlayingControls()) {
+        LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: Now playing not allowed in foreground tab");
+        return false;
+    }
+
     if (m_element.isFullscreen()) {
         LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Is fullscreen");
         return true;
     if (m_element.isFullscreen()) {
         LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Is fullscreen");
         return true;
@@ -228,7 +233,8 @@ bool MediaElementSession::canShowControlsManager() const
         return false;
     }
 
         return false;
     }
 
-    if (!m_element.hasAudio() && !m_element.hasEverHadAudio()) {
+    bool meetsAudioTrackRequirements = m_element.hasAudio() || (purpose == PlaybackControlsPurpose::ControlsManager && m_element.hasEverHadAudio());
+    if (!meetsAudioTrackRequirements) {
         LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No audio");
         return false;
     }
         LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No audio");
         return false;
     }
@@ -274,7 +280,7 @@ bool MediaElementSession::canShowControlsManager() const
             return false;
         }
 
             return false;
         }
 
-        if (!m_element.hasVideo() && !m_element.hasEverHadVideo()) {
+        if (purpose == PlaybackControlsPurpose::ControlsManager && !m_element.hasVideo() && !m_element.hasEverHadVideo()) {
             LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No video");
             return false;
         }
             LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: No video");
             return false;
         }
@@ -722,6 +728,12 @@ bool MediaElementSession::updateIsMainContent() const
     return m_isMainContent;
 }
 
     return m_isMainContent;
 }
 
+bool MediaElementSession::pageAllowsNowPlayingControls() const
+{
+    auto page = m_element.document().page();
+    return page && !page->isVisibleAndActive();
+}
+
 }
 
 #endif // ENABLE(VIDEO)
 }
 
 #endif // ENABLE(VIDEO)
index 833fe6a16e75bae87a454c900afc54016d40677e..05e8068a2d55155ac571138db2493686f702d04e 100644 (file)
@@ -118,7 +118,9 @@ public:
 
     bool wantsToObserveViewportVisibilityForMediaControls() const;
     bool wantsToObserveViewportVisibilityForAutoplay() const;
 
     bool wantsToObserveViewportVisibilityForMediaControls() const;
     bool wantsToObserveViewportVisibilityForAutoplay() const;
-    bool canShowControlsManager() const;
+
+    enum class PlaybackControlsPurpose { ControlsManager, NowPlaying };
+    bool canShowControlsManager(PlaybackControlsPurpose) const;
     bool isLargeEnoughForMainContent(MediaSessionMainContentPurpose) const;
     double mostRecentUserInteractionTime() const;
 
     bool isLargeEnoughForMainContent(MediaSessionMainContentPurpose) const;
     double mostRecentUserInteractionTime() const;
 
@@ -138,6 +140,8 @@ private:
     bool updateIsMainContent() const;
     void mainContentCheckTimerFired();
 
     bool updateIsMainContent() const;
     void mainContentCheckTimerFired();
 
+    bool pageAllowsNowPlayingControls() const;
+
     HTMLMediaElement& m_element;
     BehaviorRestrictions m_restrictions;
 
     HTMLMediaElement& m_element;
     BehaviorRestrictions m_restrictions;
 
index 30187a473fef69a6e50ce8306b46f032c94fdc4c..f798793af9d13df786e0cf30e1b9474c1332dd05 100644 (file)
@@ -67,6 +67,7 @@
 #include "PageGroup.h"
 #include "PageOverlayController.h"
 #include "PageThrottler.h"
 #include "PageGroup.h"
 #include "PageOverlayController.h"
 #include "PageThrottler.h"
+#include "PlatformMediaSessionManager.h"
 #include "PlugInClient.h"
 #include "PluginData.h"
 #include "PluginInfoProvider.h"
 #include "PlugInClient.h"
 #include "PluginData.h"
 #include "PluginInfoProvider.h"
@@ -1449,7 +1450,9 @@ void Page::setViewState(ViewState::Flags viewState)
 
     ViewState::Flags oldViewState = m_viewState;
 
 
     ViewState::Flags oldViewState = m_viewState;
 
+    bool wasVisibleAndActive = isVisibleAndActive();
     m_viewState = viewState;
     m_viewState = viewState;
+
     m_focusController->setViewState(viewState);
 
     if (changed & ViewState::IsVisible)
     m_focusController->setViewState(viewState);
 
     if (changed & ViewState::IsVisible)
@@ -1464,6 +1467,14 @@ void Page::setViewState(ViewState::Flags viewState)
 
     for (auto* observer : m_viewStateChangeObservers)
         observer->viewStateDidChange(oldViewState, m_viewState);
 
     for (auto* observer : m_viewStateChangeObservers)
         observer->viewStateDidChange(oldViewState, m_viewState);
+
+    if (wasVisibleAndActive != isVisibleAndActive())
+        PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary();
+}
+
+bool Page::isVisibleAndActive() const
+{
+    return (m_viewState & ViewState::IsVisible) && (m_viewState & ViewState::WindowIsActive);
 }
 
 void Page::setPageActivityState(PageActivityState::Flags activityState)
 }
 
 void Page::setPageActivityState(PageActivityState::Flags activityState)
index 9753f746add517539e5627eca66058c025fd0342..da487b924d130e89fc52ca6a5d2416b185759970 100644 (file)
@@ -335,6 +335,7 @@ public:
 
     // Notifications when the Page starts and stops being presented via a native window.
     WEBCORE_EXPORT void setViewState(ViewState::Flags);
 
     // Notifications when the Page starts and stops being presented via a native window.
     WEBCORE_EXPORT void setViewState(ViewState::Flags);
+    bool isVisibleAndActive() const;
     void setPageActivityState(PageActivityState::Flags);
     WEBCORE_EXPORT void setIsVisible(bool);
     WEBCORE_EXPORT void setIsPrerender();
     void setPageActivityState(PageActivityState::Flags);
     WEBCORE_EXPORT void setIsVisible(bool);
     WEBCORE_EXPORT void setIsPrerender();
index 975fc50e2fa32b7324fe571403e11f621cbd9556..765a69f2c200ab53873d1babe418acfa70cda88d 100644 (file)
 
 namespace WebCore {
 
 
 namespace WebCore {
 
-#if !PLATFORM(IOS) && !PLATFORM(MAC)
+#if !PLATFORM(MAC)
+
+void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
+{
+}
+
+#if !PLATFORM(IOS)
 static PlatformMediaSessionManager* platformMediaSessionManager = nullptr;
 
 PlatformMediaSessionManager& PlatformMediaSessionManager::sharedManager()
 static PlatformMediaSessionManager* platformMediaSessionManager = nullptr;
 
 PlatformMediaSessionManager& PlatformMediaSessionManager::sharedManager()
@@ -50,7 +56,9 @@ PlatformMediaSessionManager* PlatformMediaSessionManager::sharedManagerIfExists(
 {
     return platformMediaSessionManager;
 }
 {
     return platformMediaSessionManager;
 }
-#endif
+#endif // !PLATFORM(IOS)
+
+#endif // !PLATFORM(MAC)
 
 PlatformMediaSessionManager::PlatformMediaSessionManager()
     : m_systemSleepListener(SystemSleepListener::create(*this))
 
 PlatformMediaSessionManager::PlatformMediaSessionManager()
     : m_systemSleepListener(SystemSleepListener::create(*this))
index c7a816ef05b01aa7fadb0c72efc843911213e764..9fdfc189ab302b59a20729a802dda972a903b2f6 100644 (file)
@@ -46,6 +46,9 @@ class PlatformMediaSessionManager : private RemoteCommandListenerClient, private
 public:
     WEBCORE_EXPORT static PlatformMediaSessionManager* sharedManagerIfExists();
     WEBCORE_EXPORT static PlatformMediaSessionManager& sharedManager();
 public:
     WEBCORE_EXPORT static PlatformMediaSessionManager* sharedManagerIfExists();
     WEBCORE_EXPORT static PlatformMediaSessionManager& sharedManager();
+
+    static void updateNowPlayingInfoIfNecessary();
+
     virtual ~PlatformMediaSessionManager() { }
 
     bool has(PlatformMediaSession::MediaType) const;
     virtual ~PlatformMediaSessionManager() { }
 
     bool has(PlatformMediaSession::MediaType) const;
index 420e8ebe650db52bc895045e0543bbab7a362a6b..cf27e64abdf75714e92de5d14a9c52bf65c3925a 100644 (file)
@@ -28,6 +28,7 @@
 
 #if PLATFORM(MAC)
 
 
 #if PLATFORM(MAC)
 
+#import "HTMLMediaElement.h"
 #import "Logging.h"
 #import "MediaPlayer.h"
 #import "PlatformMediaSession.h"
 #import "Logging.h"
 #import "MediaPlayer.h"
 #import "PlatformMediaSession.h"
@@ -52,6 +53,12 @@ PlatformMediaSessionManager* PlatformMediaSessionManager::sharedManagerIfExists(
     return platformMediaSessionManager;
 }
 
     return platformMediaSessionManager;
 }
 
+void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
+{
+    if (auto existingManager = (MediaSessionManagerMac *)PlatformMediaSessionManager::sharedManagerIfExists())
+        existingManager->updateNowPlayingInfo();
+}
+
 MediaSessionManagerMac::MediaSessionManagerMac()
     : PlatformMediaSessionManager()
 {
 MediaSessionManagerMac::MediaSessionManagerMac()
     : PlatformMediaSessionManager()
 {
@@ -94,14 +101,8 @@ void MediaSessionManagerMac::clientCharacteristicsChanged(PlatformMediaSession&)
 
 PlatformMediaSession* MediaSessionManagerMac::nowPlayingEligibleSession()
 {
 
 PlatformMediaSession* MediaSessionManagerMac::nowPlayingEligibleSession()
 {
-    for (auto session : sessions()) {
-        PlatformMediaSession::MediaType type = session->mediaType();
-        if (type != PlatformMediaSession::Video && type != PlatformMediaSession::Audio)
-            continue;
-
-        if (session->characteristics() & PlatformMediaSession::HasAudio)
-            return session;
-    }
+    if (auto element = HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::NowPlaying))
+        return &element->mediaSession();
 
     return nullptr;
 }
 
     return nullptr;
 }
@@ -122,6 +123,9 @@ void MediaSessionManagerMac::updateNowPlayingInfo()
             LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
             MRMediaRemoteSetNowPlayingInfo(nullptr);
             m_nowPlayingActive = false;
             LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
             MRMediaRemoteSetNowPlayingInfo(nullptr);
             m_nowPlayingActive = false;
+            m_reportedTitle = "";
+            m_reportedRate = 0;
+            m_reportedDuration = 0;
             MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
 #if LOG_DISABLED
                 UNUSED_PARAM(error);
             MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
 #if LOG_DISABLED
                 UNUSED_PARAM(error);
@@ -143,6 +147,7 @@ void MediaSessionManagerMac::updateNowPlayingInfo()
     double duration = currentSession->duration();
     double rate = currentSession->state() == PlatformMediaSession::Playing ? 1 : 0;
     if (m_reportedTitle == title && m_reportedRate == rate && m_reportedDuration == duration) {
     double duration = currentSession->duration();
     double rate = currentSession->state() == PlatformMediaSession::Playing ? 1 : 0;
     if (m_reportedTitle == title && m_reportedRate == rate && m_reportedDuration == duration) {
+        m_nowPlayingActive = true;
         LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - nothing new to show");
         return;
     }
         LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - nothing new to show");
         return;
     }