Title: [206321] branches/safari-602-branch/Source/WebCore

Diff

Modified: branches/safari-602-branch/Source/WebCore/ChangeLog (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/ChangeLog	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/ChangeLog	2016-09-23 19:33:54 UTC (rev 206321)
@@ -1,5 +1,55 @@
 2016-09-23  Babak Shafiei  <[email protected]>
 
+        Merge r206315. rdar://problem/28430615
+
+    2016-09-23  Wenson Hsieh  <[email protected]>
+
+            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  Babak Shafiei  <[email protected]>
+
         Merge r206272. rdar://problem/28339129
 
     2016-09-22  Jer Noble  <[email protected]>

Modified: branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.cpp (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.cpp	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.cpp	2016-09-23 19:33:54 UTC (rev 206321)
@@ -358,13 +358,13 @@
     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(),
-        session.canShowControlsManager(),
+        session.canShowControlsManager(purpose),
         element.isFullscreen() || element.isVisibleInViewport(),
         session.isLargeEnoughForMainContent(MediaSessionMainContentPurpose::MediaControls),
         element.isPlaying() && element.hasAudio() && !element.muted()
@@ -381,8 +381,11 @@
     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;
 
@@ -394,33 +397,6 @@
     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)
@@ -643,6 +619,33 @@
     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);
@@ -7287,8 +7290,8 @@
         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();
 }

Modified: branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.h (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.h	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.h	2016-09-23 19:33:54 UTC (rev 206321)
@@ -115,6 +115,8 @@
 
     static HashSet<HTMLMediaElement*>& allMediaElements();
 
+    static HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose);
+
     void rewind(double timeDelta);
     WEBCORE_EXPORT void returnToRealtime() override;
 

Modified: branches/safari-602-branch/Source/WebCore/html/MediaElementSession.cpp (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/html/MediaElementSession.cpp	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/html/MediaElementSession.cpp	2016-09-23 19:33:54 UTC (rev 206321)
@@ -216,8 +216,13 @@
     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;
@@ -228,7 +233,8 @@
         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;
     }
@@ -274,7 +280,7 @@
             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;
         }
@@ -722,6 +728,12 @@
     return m_isMainContent;
 }
 
+bool MediaElementSession::pageAllowsNowPlayingControls() const
+{
+    auto page = m_element.document().page();
+    return page && !page->isVisibleAndActive();
 }
 
+}
+
 #endif // ENABLE(VIDEO)

Modified: branches/safari-602-branch/Source/WebCore/html/MediaElementSession.h (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/html/MediaElementSession.h	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/html/MediaElementSession.h	2016-09-23 19:33:54 UTC (rev 206321)
@@ -118,7 +118,9 @@
 
     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;
 
@@ -138,6 +140,8 @@
     bool updateIsMainContent() const;
     void mainContentCheckTimerFired();
 
+    bool pageAllowsNowPlayingControls() const;
+
     HTMLMediaElement& m_element;
     BehaviorRestrictions m_restrictions;
 

Modified: branches/safari-602-branch/Source/WebCore/page/Page.cpp (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/page/Page.cpp	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/page/Page.cpp	2016-09-23 19:33:54 UTC (rev 206321)
@@ -67,6 +67,7 @@
 #include "PageGroup.h"
 #include "PageOverlayController.h"
 #include "PageThrottler.h"
+#include "PlatformMediaSessionManager.h"
 #include "PlugInClient.h"
 #include "PluginData.h"
 #include "PluginViewBase.h"
@@ -1449,7 +1450,9 @@
 
     ViewState::Flags oldViewState = m_viewState;
 
+    bool wasVisibleAndActive = isVisibleAndActive();
     m_viewState = viewState;
+
     m_focusController->setViewState(viewState);
 
     if (changed & ViewState::IsVisible)
@@ -1464,8 +1467,16 @@
 
     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)
 {
     chrome().client().setPageActivityState(activityState);

Modified: branches/safari-602-branch/Source/WebCore/page/Page.h (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/page/Page.h	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/page/Page.h	2016-09-23 19:33:54 UTC (rev 206321)
@@ -337,6 +337,7 @@
 
     // 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();

Modified: branches/safari-602-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2016-09-23 19:33:54 UTC (rev 206321)
@@ -36,7 +36,13 @@
 
 namespace WebCore {
 
-#if !PLATFORM(IOS) && !PLATFORM(MAC)
+#if !PLATFORM(MAC)
+
+void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
+{
+}
+
+#if !PLATFORM(IOS)
 static PlatformMediaSessionManager* platformMediaSessionManager = nullptr;
 
 PlatformMediaSessionManager& PlatformMediaSessionManager::sharedManager()
@@ -50,8 +56,10 @@
 {
     return platformMediaSessionManager;
 }
-#endif
+#endif // !PLATFORM(IOS)
 
+#endif // !PLATFORM(MAC)
+
 PlatformMediaSessionManager::PlatformMediaSessionManager()
     : m_systemSleepListener(SystemSleepListener::create(*this))
 {

Modified: branches/safari-602-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-09-23 19:33:54 UTC (rev 206321)
@@ -46,6 +46,9 @@
 public:
     WEBCORE_EXPORT static PlatformMediaSessionManager* sharedManagerIfExists();
     WEBCORE_EXPORT static PlatformMediaSessionManager& sharedManager();
+
+    static void updateNowPlayingInfoIfNecessary();
+
     virtual ~PlatformMediaSessionManager() { }
 
     bool has(PlatformMediaSession::MediaType) const;

Modified: branches/safari-602-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (206320 => 206321)


--- branches/safari-602-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm	2016-09-23 19:33:49 UTC (rev 206320)
+++ branches/safari-602-branch/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm	2016-09-23 19:33:54 UTC (rev 206321)
@@ -28,6 +28,7 @@
 
 #if PLATFORM(MAC)
 
+#import "HTMLMediaElement.h"
 #import "Logging.h"
 #import "MediaPlayer.h"
 #import "PlatformMediaSession.h"
@@ -52,6 +53,12 @@
     return platformMediaSessionManager;
 }
 
+void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
+{
+    if (auto existingManager = (MediaSessionManagerMac *)PlatformMediaSessionManager::sharedManagerIfExists())
+        existingManager->updateNowPlayingInfo();
+}
+
 MediaSessionManagerMac::MediaSessionManagerMac()
     : PlatformMediaSessionManager()
 {
@@ -94,15 +101,9 @@
 
 PlatformMediaSession* MediaSessionManagerMac::nowPlayingEligibleSession()
 {
-    for (auto session : sessions()) {
-        PlatformMediaSession::MediaType type = session->mediaType();
-        if (type != PlatformMediaSession::Video && type != PlatformMediaSession::Audio)
-            continue;
+    if (auto element = HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::NowPlaying))
+        return &element->mediaSession();
 
-        if (session->characteristics() & PlatformMediaSession::HasAudio)
-            return session;
-    }
-
     return nullptr;
 }
 
@@ -122,6 +123,9 @@
             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);
@@ -143,6 +147,7 @@
     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;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to