Changeset 207220 in webkit


Ignore:
Timestamp:
Oct 12, 2016 9:48:21 AM (7 years ago)
Author:
Wenson Hsieh
Message:

Now playing media sessions are always cleared for the active foreground tab
https://bugs.webkit.org/show_bug.cgi?id=163310
<rdar://problem/28573301>

Reviewed by Jer Noble.

Source/WebCore:

Currently, we clear out Now Playing info whenever we set the visibility of Now Playing controls to Never. This
is incorrect, as the Now Playing session needs to still be active (just not visible) in this state. Instead, we
should not be taking the active/foregrounded-ness of a media session for Now Playing into account in
MediaElementSession::canShowControlsManager so that even if a media session is in the active/foreground tab, we
will update the Now Playing session with the latest info. However, when setting the visibility, we now check
and see if the session allows Now Playing visibility, and set the Now Playing visibility to Always or Never
depending on the answer.

Tweaked existing unit tests in NowPlayingControlsTests.

  • html/MediaElementSession.cpp:

(WebCore::MediaElementSession::canShowControlsManager):
(WebCore::MediaElementSession::allowsNowPlayingControlsVisibility):
(WebCore::MediaElementSession::pageAllowsNowPlayingControls): Deleted.

  • html/MediaElementSession.h:
  • platform/audio/PlatformMediaSession.h:

(WebCore::PlatformMediaSession::allowsNowPlayingControlsVisibility):

  • platform/audio/mac/MediaSessionManagerMac.mm:

(WebCore::MediaSessionManagerMac::updateNowPlayingInfo):

Tools:

Tweaks existing unit tests to verify that media session info persists when backgrounding and foregrounding, but
that media session info is correctly cleared out if the media session itself is no longer eligible for Now
Playing (not accounting for foreground/active state). Previously, these tests were verifying that we would
always clear out the information, but this is incorrect, and is the source of the problem.

  • TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm:

(-[NowPlayingTestWebView waitForNowPlayingInfoToChange]):
(TestWebKitAPI::TEST):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r207219 r207220  
     12016-10-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Now playing media sessions are always cleared for the active foreground tab
     4        https://bugs.webkit.org/show_bug.cgi?id=163310
     5        <rdar://problem/28573301>
     6
     7        Reviewed by Jer Noble.
     8
     9        Currently, we clear out Now Playing info whenever we set the visibility of Now Playing controls to Never. This
     10        is incorrect, as the Now Playing session needs to still be active (just not visible) in this state. Instead, we
     11        should not be taking the active/foregrounded-ness of a media session for Now Playing into account in
     12        MediaElementSession::canShowControlsManager so that even if a media session is in the active/foreground tab, we
     13        will update the Now Playing session with the latest info. However, when setting the visibility, we now check
     14        and see if the session allows Now Playing visibility, and set the Now Playing visibility to Always or Never
     15        depending on the answer.
     16
     17        Tweaked existing unit tests in NowPlayingControlsTests.
     18
     19        * html/MediaElementSession.cpp:
     20        (WebCore::MediaElementSession::canShowControlsManager):
     21        (WebCore::MediaElementSession::allowsNowPlayingControlsVisibility):
     22        (WebCore::MediaElementSession::pageAllowsNowPlayingControls): Deleted.
     23        * html/MediaElementSession.h:
     24        * platform/audio/PlatformMediaSession.h:
     25        (WebCore::PlatformMediaSession::allowsNowPlayingControlsVisibility):
     26        * platform/audio/mac/MediaSessionManagerMac.mm:
     27        (WebCore::MediaSessionManagerMac::updateNowPlayingInfo):
     28
    1292016-10-12  Zalan Bujtas  <zalan@apple.com>
    230
  • trunk/Source/WebCore/html/MediaElementSession.cpp

    r206721 r207220  
    222222bool MediaElementSession::canShowControlsManager(PlaybackControlsPurpose purpose) const
    223223{
    224     if (purpose == PlaybackControlsPurpose::NowPlaying && !pageAllowsNowPlayingControls()) {
    225         LOG(Media, "MediaElementSession::canShowControlsManager - returning FALSE: Now playing not allowed in foreground tab");
    226         return false;
    227     }
    228 
    229224    if (m_element.isFullscreen()) {
    230225        LOG(Media, "MediaElementSession::canShowControlsManager - returning TRUE: Is fullscreen");
     
    752747}
    753748
    754 bool MediaElementSession::pageAllowsNowPlayingControls() const
     749bool MediaElementSession::allowsNowPlayingControlsVisibility() const
    755750{
    756751    auto page = m_element.document().page();
  • trunk/Source/WebCore/html/MediaElementSession.h

    r206721 r207220  
    126126
    127127    bool allowsPlaybackControlsForAutoplayingAudio() const;
     128    bool allowsNowPlayingControlsVisibility() const override;
    128129
    129130private:
     
    142143    bool updateIsMainContent() const;
    143144    void mainContentCheckTimerFired();
    144 
    145     bool pageAllowsNowPlayingControls() const;
    146145
    147146    HTMLMediaElement& m_element;
  • trunk/Source/WebCore/platform/audio/PlatformMediaSession.h

    r206193 r207220  
    169169    String sourceApplicationIdentifier() const;
    170170
     171    virtual bool allowsNowPlayingControlsVisibility() const { return false; }
     172
    171173protected:
    172174    PlatformMediaSessionClient& client() const { return m_client; }
  • trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm

    r206771 r207220  
    130130
    131131    if (!currentSession) {
    132         if (m_nowPlayingActive) {
    133             if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
    134                 MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityNeverVisible);
    135 
    136             LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
    137             MRMediaRemoteSetNowPlayingInfo(nullptr);
    138             m_nowPlayingActive = false;
    139             m_lastUpdatedNowPlayingTitle = emptyString();
    140             m_lastUpdatedNowPlayingDuration = NAN;
    141             m_lastUpdatedNowPlayingElapsedTime = NAN;
    142             MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
     132        if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
     133            MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityNeverVisible);
     134
     135        LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
     136        MRMediaRemoteSetNowPlayingInfo(nullptr);
     137        m_nowPlayingActive = false;
     138        m_lastUpdatedNowPlayingTitle = emptyString();
     139        m_lastUpdatedNowPlayingDuration = NAN;
     140        m_lastUpdatedNowPlayingElapsedTime = NAN;
     141        MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
    143142#if LOG_DISABLED
    144                 UNUSED_PARAM(error);
     143            UNUSED_PARAM(error);
    145144#else
    146                 LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
     145            LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
    147146#endif
    148             });
    149         }
     147        });
    150148
    151149        return;
     
    190188        MRMediaRemoteSetParentApplication(MRMediaRemoteGetLocalOrigin(), parentApplication.createCFString().get());
    191189
    192     m_nowPlayingActive = true;
     190    m_nowPlayingActive = currentSession->allowsNowPlayingControlsVisibility();
    193191    MRPlaybackState playbackState = (currentSession->state() == PlatformMediaSession::Playing) ? kMRPlaybackStatePlaying : kMRPlaybackStatePaused;
    194192    MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), playbackState, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
     
    201199    MRMediaRemoteSetNowPlayingInfo(info.get());
    202200
    203     if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
    204         MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityAlwaysVisible);
     201    if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility()) {
     202        MRNowPlayingClientVisibility visibility = currentSession->allowsNowPlayingControlsVisibility() ? MRNowPlayingClientVisibilityAlwaysVisible : MRNowPlayingClientVisibilityNeverVisible;
     203        MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), visibility);
     204    }
    205205#endif
    206206}
  • trunk/Tools/ChangeLog

    r207218 r207220  
     12016-10-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Now playing media sessions are always cleared for the active foreground tab
     4        https://bugs.webkit.org/show_bug.cgi?id=163310
     5        <rdar://problem/28573301>
     6
     7        Reviewed by Jer Noble.
     8
     9        Tweaks existing unit tests to verify that media session info persists when backgrounding and foregrounding, but
     10        that media session info is correctly cleared out if the media session itself is no longer eligible for Now
     11        Playing (not accounting for foreground/active state). Previously, these tests were verifying that we would
     12        always clear out the information, but this is incorrect, and is the source of the problem.
     13
     14        * TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm:
     15        (-[NowPlayingTestWebView waitForNowPlayingInfoToChange]):
     16        (TestWebKitAPI::TEST):
     17
    1182016-10-12  Per Arne Vollan  <pvollan@apple.com>
    219
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm

    r206771 r207220  
    6363}
    6464
     65- (void)waitForNowPlayingInfoToChange
     66{
     67    BOOL initialHasActiveNowPlayingSession = self.hasActiveNowPlayingSession;
     68    NSString *initialTitle = self.lastUpdatedTitle;
     69    double initialDuration = self.lastUpdatedDuration;
     70    double initialElapsedTime = self.lastUpdatedElapsedTime;
     71    while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
     72        BOOL currentlyHasActiveNowPlayingSession = self.hasActiveNowPlayingSession;
     73        if (initialHasActiveNowPlayingSession != currentlyHasActiveNowPlayingSession)
     74            break;
     75
     76        if (initialDuration != self.lastUpdatedDuration)
     77            break;
     78
     79        if (initialElapsedTime != self.lastUpdatedElapsedTime)
     80            break;
     81
     82        if (![initialTitle isEqualToString:self.lastUpdatedTitle] && self.lastUpdatedTitle != initialTitle)
     83            break;
     84    }
     85}
     86
    6587- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime
    6688{
     
    88110    [webView expectHasActiveNowPlayingSession:NO];
    89111
    90     ASSERT_STREQ("", webView.lastUpdatedTitle.UTF8String);
    91     ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
    92     ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
     112    ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
     113    ASSERT_EQ(10, webView.lastUpdatedDuration);
     114    ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
    93115}
    94116
     
    110132}
    111133
    112 TEST(NowPlayingControlsTests, NowPlayingControlsHideAfterShowingClearsInfo)
     134TEST(NowPlayingControlsTests, NowPlayingControlsHideAfterShowingKeepsSessionActive)
    113135{
    114136    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
     
    128150    [webView expectHasActiveNowPlayingSession:NO];
    129151
    130     ASSERT_STREQ("", webView.lastUpdatedTitle.UTF8String);
    131     ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
    132     ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
     152    ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
     153    ASSERT_EQ(10, webView.lastUpdatedDuration);
     154    ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
    133155}
    134156
     
    145167    [webView.window resignKeyWindow];
    146168
    147     [webView expectHasActiveNowPlayingSession:NO];
     169    [webView waitForNowPlayingInfoToChange];
    148170
    149171    ASSERT_STREQ("", webView.lastUpdatedTitle.UTF8String);
Note: See TracChangeset for help on using the changeset viewer.