- Revision
- 207220
- Author
- [email protected]
- Date
- 2016-10-12 09:48:21 -0700 (Wed, 12 Oct 2016)
Log 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):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (207219 => 207220)
--- trunk/Source/WebCore/ChangeLog 2016-10-12 16:45:55 UTC (rev 207219)
+++ trunk/Source/WebCore/ChangeLog 2016-10-12 16:48:21 UTC (rev 207220)
@@ -1,3 +1,31 @@
+2016-10-12 Wenson Hsieh <[email protected]>
+
+ 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.
+
+ 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):
+
2016-10-12 Zalan Bujtas <[email protected]>
Refactor LineLayoutState's float box handling.
Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (207219 => 207220)
--- trunk/Source/WebCore/html/MediaElementSession.cpp 2016-10-12 16:45:55 UTC (rev 207219)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp 2016-10-12 16:48:21 UTC (rev 207220)
@@ -221,11 +221,6 @@
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;
@@ -751,7 +746,7 @@
return m_isMainContent;
}
-bool MediaElementSession::pageAllowsNowPlayingControls() const
+bool MediaElementSession::allowsNowPlayingControlsVisibility() const
{
auto page = m_element.document().page();
return page && !page->isVisibleAndActive();
Modified: trunk/Source/WebCore/html/MediaElementSession.h (207219 => 207220)
--- trunk/Source/WebCore/html/MediaElementSession.h 2016-10-12 16:45:55 UTC (rev 207219)
+++ trunk/Source/WebCore/html/MediaElementSession.h 2016-10-12 16:48:21 UTC (rev 207220)
@@ -125,6 +125,7 @@
double mostRecentUserInteractionTime() const;
bool allowsPlaybackControlsForAutoplayingAudio() const;
+ bool allowsNowPlayingControlsVisibility() const override;
private:
@@ -142,8 +143,6 @@
bool updateIsMainContent() const;
void mainContentCheckTimerFired();
- bool pageAllowsNowPlayingControls() const;
-
HTMLMediaElement& m_element;
BehaviorRestrictions m_restrictions;
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.h (207219 => 207220)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.h 2016-10-12 16:45:55 UTC (rev 207219)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.h 2016-10-12 16:48:21 UTC (rev 207220)
@@ -168,6 +168,8 @@
virtual void resetPlaybackSessionState() { }
String sourceApplicationIdentifier() const;
+ virtual bool allowsNowPlayingControlsVisibility() const { return false; }
+
protected:
PlatformMediaSessionClient& client() const { return m_client; }
Modified: trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (207219 => 207220)
--- trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm 2016-10-12 16:45:55 UTC (rev 207219)
+++ trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm 2016-10-12 16:48:21 UTC (rev 207220)
@@ -129,24 +129,22 @@
LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - currentSession = %p", currentSession);
if (!currentSession) {
- if (m_nowPlayingActive) {
- if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
- MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityNeverVisible);
+ if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
+ MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityNeverVisible);
- LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
- MRMediaRemoteSetNowPlayingInfo(nullptr);
- m_nowPlayingActive = false;
- m_lastUpdatedNowPlayingTitle = emptyString();
- m_lastUpdatedNowPlayingDuration = NAN;
- m_lastUpdatedNowPlayingElapsedTime = NAN;
- MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
+ LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - clearing now playing info");
+ MRMediaRemoteSetNowPlayingInfo(nullptr);
+ m_nowPlayingActive = false;
+ m_lastUpdatedNowPlayingTitle = emptyString();
+ m_lastUpdatedNowPlayingDuration = NAN;
+ m_lastUpdatedNowPlayingElapsedTime = NAN;
+ MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
#if LOG_DISABLED
- UNUSED_PARAM(error);
+ UNUSED_PARAM(error);
#else
- LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
+ LOG(Media, "MediaSessionManagerMac::updateNowPlayingInfo - MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(stopped) failed with error %ud", error);
#endif
- });
- }
+ });
return;
}
@@ -189,7 +187,7 @@
if (canLoad_MediaRemote_MRMediaRemoteSetParentApplication() && !parentApplication.isEmpty())
MRMediaRemoteSetParentApplication(MRMediaRemoteGetLocalOrigin(), parentApplication.createCFString().get());
- m_nowPlayingActive = true;
+ m_nowPlayingActive = currentSession->allowsNowPlayingControlsVisibility();
MRPlaybackState playbackState = (currentSession->state() == PlatformMediaSession::Playing) ? kMRPlaybackStatePlaying : kMRPlaybackStatePaused;
MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), playbackState, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {
#if LOG_DISABLED
@@ -200,8 +198,10 @@
});
MRMediaRemoteSetNowPlayingInfo(info.get());
- if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility())
- MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), MRNowPlayingClientVisibilityAlwaysVisible);
+ if (canLoad_MediaRemote_MRMediaRemoteSetNowPlayingVisibility()) {
+ MRNowPlayingClientVisibility visibility = currentSession->allowsNowPlayingControlsVisibility() ? MRNowPlayingClientVisibilityAlwaysVisible : MRNowPlayingClientVisibilityNeverVisible;
+ MRMediaRemoteSetNowPlayingVisibility(MRMediaRemoteGetLocalOrigin(), visibility);
+ }
#endif
}
Modified: trunk/Tools/ChangeLog (207219 => 207220)
--- trunk/Tools/ChangeLog 2016-10-12 16:45:55 UTC (rev 207219)
+++ trunk/Tools/ChangeLog 2016-10-12 16:48:21 UTC (rev 207220)
@@ -1,3 +1,20 @@
+2016-10-12 Wenson Hsieh <[email protected]>
+
+ 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.
+
+ 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):
+
2016-10-12 Per Arne Vollan <[email protected]>
[Win] Parallel DRTs are sharing preferences and cache.
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm (207219 => 207220)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm 2016-10-12 16:45:55 UTC (rev 207219)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/NowPlayingControlsTests.mm 2016-10-12 16:48:21 UTC (rev 207220)
@@ -62,6 +62,28 @@
}
}
+- (void)waitForNowPlayingInfoToChange
+{
+ BOOL initialHasActiveNowPlayingSession = self.hasActiveNowPlayingSession;
+ NSString *initialTitle = self.lastUpdatedTitle;
+ double initialDuration = self.lastUpdatedDuration;
+ double initialElapsedTime = self.lastUpdatedElapsedTime;
+ while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
+ BOOL currentlyHasActiveNowPlayingSession = self.hasActiveNowPlayingSession;
+ if (initialHasActiveNowPlayingSession != currentlyHasActiveNowPlayingSession)
+ break;
+
+ if (initialDuration != self.lastUpdatedDuration)
+ break;
+
+ if (initialElapsedTime != self.lastUpdatedElapsedTime)
+ break;
+
+ if (![initialTitle isEqualToString:self.lastUpdatedTitle] && self.lastUpdatedTitle != initialTitle)
+ break;
+ }
+}
+
- (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime
{
_hasActiveNowPlayingSession = hasActiveSession;
@@ -87,9 +109,9 @@
[webView.window makeKeyWindow];
[webView expectHasActiveNowPlayingSession:NO];
- ASSERT_STREQ("", webView.lastUpdatedTitle.UTF8String);
- ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
- ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
+ ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
+ ASSERT_EQ(10, webView.lastUpdatedDuration);
+ ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
}
TEST(NowPlayingControlsTests, NowPlayingControlsShowForBackgroundPage)
@@ -109,7 +131,7 @@
ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
}
-TEST(NowPlayingControlsTests, NowPlayingControlsHideAfterShowingClearsInfo)
+TEST(NowPlayingControlsTests, NowPlayingControlsHideAfterShowingKeepsSessionActive)
{
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
@@ -127,9 +149,9 @@
[webView expectHasActiveNowPlayingSession:NO];
- ASSERT_STREQ("", webView.lastUpdatedTitle.UTF8String);
- ASSERT_TRUE(isnan(webView.lastUpdatedDuration));
- ASSERT_TRUE(isnan(webView.lastUpdatedElapsedTime));
+ ASSERT_STREQ("foo", webView.lastUpdatedTitle.UTF8String);
+ ASSERT_EQ(10, webView.lastUpdatedDuration);
+ ASSERT_GE(webView.lastUpdatedElapsedTime, 0);
}
TEST(NowPlayingControlsTests, NowPlayingControlsClearInfoAfterSessionIsNoLongerValid)
@@ -144,7 +166,7 @@
[webView.window setIsVisible:NO];
[webView.window resignKeyWindow];
- [webView expectHasActiveNowPlayingSession:NO];
+ [webView waitForNowPlayingInfoToChange];
ASSERT_STREQ("", webView.lastUpdatedTitle.UTF8String);
ASSERT_TRUE(isnan(webView.lastUpdatedDuration));