Diff
Modified: trunk/Source/WebCore/ChangeLog (184787 => 184788)
--- trunk/Source/WebCore/ChangeLog 2015-05-22 19:11:46 UTC (rev 184787)
+++ trunk/Source/WebCore/ChangeLog 2015-05-22 19:14:48 UTC (rev 184788)
@@ -1,3 +1,43 @@
+2015-05-22 Eric Carlson <[email protected]>
+
+ [Mac] Device picker menu should be persistent
+ https://bugs.webkit.org/show_bug.cgi?id=145311
+
+ Reviewed by Brent Fulgham.
+
+ * Modules/mediasession/WebMediaSessionManager.cpp:
+ (WebCore::WebMediaSessionManager::addPlaybackTargetPickerClient): Add logging.
+ (WebCore::WebMediaSessionManager::removePlaybackTargetPickerClient): Ditto.
+ (WebCore::WebMediaSessionManager::removeAllPlaybackTargetPickerClients): Ditto.
+ (WebCore::WebMediaSessionManager::showPlaybackTargetPicker): Ditto.
+ (WebCore::WebMediaSessionManager::clientStateDidChange): Ditto.
+ (WebCore::WebMediaSessionManager::externalOutputDeviceAvailableDidChange): Ditto.
+ (WebCore::WebMediaSessionManager::configurePlaybackTargetMonitoring): Ditto.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::mediaState): Don't set ExternalDeviceAutoPlayCandidate unless
+ there is an event listener.
+
+ * platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm:
+ (WebCore::MediaPlaybackTargetPickerMac::~MediaPlaybackTargetPickerMac): Release the menu
+ controller and remove observers.
+ (WebCore::MediaPlaybackTargetPickerMac::create): Add logging.
+ (WebCore::MediaPlaybackTargetPickerMac::pendingActionTimerFired): Ditto.
+ (WebCore::MediaPlaybackTargetPickerMac::availableDevicesDidChange): Ditto.
+ (WebCore::MediaPlaybackTargetPickerMac::devicePicker): Ditto.
+ (WebCore::MediaPlaybackTargetPickerMac::showPlaybackTargetPicker): Ditto.
+ (WebCore::MediaPlaybackTargetPickerMac::addPendingAction): Start the timer after
+ a brief pause to debounce multiple identical notifications.
+ (WebCore::MediaPlaybackTargetPickerMac::currentDeviceDidChange): Add logging.
+ (WebCore::MediaPlaybackTargetPickerMac::startingMonitoringPlaybackTargets): Add logging.
+ (WebCore::MediaPlaybackTargetPickerMac::stopMonitoringPlaybackTargets): Don't release
+ the menu controller delegate.
+ (-[WebAVOutputDeviceMenuControllerHelper observeValueForKeyPath:ofObject:change:context:]): Add logging.
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget): Update logging.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget): Ditto.
+
2015-05-22 Alexey Proskuryakov <[email protected]>
Build fix. Added a platform ifdef.
Modified: trunk/Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp (184787 => 184788)
--- trunk/Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp 2015-05-22 19:11:46 UTC (rev 184787)
+++ trunk/Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp 2015-05-22 19:14:48 UTC (rev 184788)
@@ -29,6 +29,7 @@
#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
#include "FloatRect.h"
+#include "Logging.h"
#include "MediaPlaybackTargetPickerMac.h"
#include "WebMediaSessionManagerClient.h"
@@ -76,6 +77,8 @@
if (index != notFound)
return 0;
+ LOG(Media, "WebMediaSessionManager::addPlaybackTargetPickerClient(%p + %llu)", &client, contextId);
+
m_clientState.append(std::make_unique<ClientState>(client, contextId));
if (m_externalOutputDeviceAvailable || m_playbackTarget)
@@ -91,12 +94,16 @@
if (index == notFound)
return;
+ LOG(Media, "WebMediaSessionManager::removePlaybackTargetPickerClient(%p + %llu)", &client, contextId);
+
m_clientState.remove(index);
scheduleDelayedTask(TargetMonitoringConfigurationTask | TargetClientsConfigurationTask);
}
void WebMediaSessionManager::removeAllPlaybackTargetPickerClients(WebMediaSessionManagerClient& client)
{
+ LOG(Media, "WebMediaSessionManager::removeAllPlaybackTargetPickerClients(%p)", &client);
+
for (size_t i = m_clientState.size(); i > 0; --i) {
if (&m_clientState[i - 1]->client == &client)
m_clientState.remove(i - 1);
@@ -116,6 +123,7 @@
state->requestedPicker = state == clientRequestingPicker;
bool hasActiveRoute = flagsAreSet(m_clientState[index]->flags, MediaProducer::IsPlayingToExternalDevice);
+ LOG(Media, "WebMediaSessionManager::showPlaybackTargetPicker(%p + %llu) - hasActiveRoute = %i", &client, contextId, (int)hasActiveRoute);
targetPicker().showPlaybackTargetPicker(FloatRect(rect), hasActiveRoute);
}
@@ -128,6 +136,7 @@
auto& changedClientState = m_clientState[index];
MediaProducer::MediaStateFlags oldFlags = changedClientState->flags;
+ LOG(Media, "WebMediaSessionManager::clientStateDidChange(%p + %llu) - new flags = 0x%x, old flags = 0x%x", &client, contextId, newFlags, oldFlags);
if (newFlags == oldFlags)
return;
@@ -175,6 +184,8 @@
void WebMediaSessionManager::externalOutputDeviceAvailableDidChange(bool available)
{
+ LOG(Media, "WebMediaSessionManager::externalOutputDeviceAvailableDidChange - clients = %zu, available = %i", m_clientState.size(), (int)available);
+
m_externalOutputDeviceAvailable = available;
for (auto& state : m_clientState)
state->client.externalOutputDeviceAvailableDidChange(state->contextId, available);
@@ -246,6 +257,8 @@
}
}
+ LOG(Media, "WebMediaSessionManager::configurePlaybackTargetMonitoring - monitoringRequired = %i", (int)monitoringRequired);
+
if (monitoringRequired)
targetPicker().startingMonitoringPlaybackTargets();
else
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (184787 => 184788)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2015-05-22 19:11:46 UTC (rev 184787)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2015-05-22 19:14:48 UTC (rev 184788)
@@ -6281,10 +6281,8 @@
if (isPlayingToWirelessPlaybackTarget())
state |= IsPlayingToExternalDevice;
- if (!m_mediaSession->wirelessVideoPlaybackDisabled(*this)) {
- if ((m_hasPlaybackTargetAvailabilityListeners || hasActiveVideo) && m_player->canPlayToWirelessPlaybackTarget())
- state |= RequiresPlaybackTargetMonitoring;
- }
+ if (!m_mediaSession->wirelessVideoPlaybackDisabled(*this) && m_hasPlaybackTargetAvailabilityListeners && m_player->canPlayToWirelessPlaybackTarget())
+ state |= RequiresPlaybackTargetMonitoring;
bool requireUserGesture = m_mediaSession->hasBehaviorRestriction(HTMLMediaSession::RequireUserGestureToAutoplayToExternalDevice);
if (hasActiveVideo && (!requireUserGesture || (hasAudio && !loop())))
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm (184787 => 184788)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm 2015-05-22 19:11:46 UTC (rev 184787)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm 2015-05-22 19:14:48 UTC (rev 184788)
@@ -28,6 +28,7 @@
#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+#import "Logging.h"
#import <WebCore/AVFoundationSPI.h>
#import <WebCore/AVKitSPI.h>
#import <WebCore/FloatRect.h>
@@ -66,6 +67,8 @@
namespace WebCore {
+static const double pendingActionInterval = 1.0 / 10.0;
+
std::unique_ptr<MediaPlaybackTargetPickerMac> MediaPlaybackTargetPickerMac::create(MediaPlaybackTargetPicker::Client& client)
{
return std::unique_ptr<MediaPlaybackTargetPickerMac>(new MediaPlaybackTargetPickerMac(client));
@@ -82,11 +85,18 @@
{
m_pendingActionTimer.stop();
[m_outputDeviceMenuControllerDelegate clearCallback];
- stopMonitoringPlaybackTargets();
+
+ if (m_outputDeviceMenuController) {
+ [m_outputDeviceMenuController removeObserver:m_outputDeviceMenuControllerDelegate.get() forKeyPath:externalOutputDeviceAvailableKeyName];
+ [m_outputDeviceMenuController removeObserver:m_outputDeviceMenuControllerDelegate.get() forKeyPath:externalOutputDevicePickedKeyName];
+ m_outputDeviceMenuController = nullptr;
+ }
}
void MediaPlaybackTargetPickerMac::pendingActionTimerFired()
{
+ LOG(Media, "MediaPlaybackTargetPickerMac::pendingActionTimerFired - flags = 0x%x", m_pendingActionFlags);
+
if (!m_outputDeviceMenuController || !m_client)
return;
@@ -105,6 +115,8 @@
void MediaPlaybackTargetPickerMac::availableDevicesDidChange()
{
+ LOG(Media, "MediaPlaybackTargetPickerMac::availableDevicesDidChange - available = %i", (int)devicePicker().externalOutputDeviceAvailable);
+
if (!m_client)
return;
@@ -123,6 +135,8 @@
[m_outputDeviceMenuController.get() addObserver:m_outputDeviceMenuControllerDelegate.get() forKeyPath:externalOutputDeviceAvailableKeyName options:NSKeyValueObservingOptionNew context:nullptr];
[m_outputDeviceMenuController.get() addObserver:m_outputDeviceMenuControllerDelegate.get() forKeyPath:externalOutputDevicePickedKeyName options:NSKeyValueObservingOptionNew context:nullptr];
+ LOG(Media, "MediaPlaybackTargetPickerMac::devicePicker - allocated menu controller %p", m_outputDeviceMenuController.get());
+
if (m_outputDeviceMenuController.get().externalOutputDeviceAvailable)
availableDevicesDidChange();
}
@@ -135,6 +149,8 @@
if (!m_client || m_showingMenu)
return;
+ LOG(Media, "MediaPlaybackTargetPickerMac::showPlaybackTargetPicker - checkActiveRoute = %i", (int)checkActiveRoute);
+
AVOutputDeviceMenuControllerType *picker = devicePicker();
if (![picker respondsToSelector:@selector(showMenuForRect:appearanceName:allowReselectionOfSelectedOutputDevice:)])
return;
@@ -150,11 +166,13 @@
void MediaPlaybackTargetPickerMac::addPendingAction(PendingActionFlags action)
{
m_pendingActionFlags |= action;
- m_pendingActionTimer.startOneShot(0);
+ m_pendingActionTimer.startOneShot(pendingActionInterval);
}
void MediaPlaybackTargetPickerMac::currentDeviceDidChange()
{
+ LOG(Media, "MediaPlaybackTargetPickerMac::currentDeviceDidChange");
+
if (!m_client)
return;
@@ -163,16 +181,16 @@
void MediaPlaybackTargetPickerMac::startingMonitoringPlaybackTargets()
{
+ LOG(Media, "MediaPlaybackTargetPickerMac::startingMonitoringPlaybackTargets");
+
devicePicker();
}
void MediaPlaybackTargetPickerMac::stopMonitoringPlaybackTargets()
{
- if (m_outputDeviceMenuController) {
- [m_outputDeviceMenuController removeObserver:m_outputDeviceMenuControllerDelegate.get() forKeyPath:externalOutputDeviceAvailableKeyName];
- [m_outputDeviceMenuController removeObserver:m_outputDeviceMenuControllerDelegate.get() forKeyPath:externalOutputDevicePickedKeyName];
- m_outputDeviceMenuController = nullptr;
- }
+ LOG(Media, "MediaPlaybackTargetPickerMac::stopMonitoringPlaybackTargets");
+
+ // FIXME: update once rdar://21062536 has been fixed.
}
} // namespace WebCore
@@ -202,6 +220,8 @@
if (!m_callback)
return;
+ LOG(Media, "MediaPlaybackTargetPickerMac::observeValueForKeyPath - key = %s", [keyPath UTF8String]);
+
if (![keyPath isEqualToString:externalOutputDeviceAvailableKeyName] && ![keyPath isEqualToString:externalOutputDevicePickedKeyName])
return;
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (184787 => 184788)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2015-05-22 19:11:46 UTC (rev 184787)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2015-05-22 19:14:48 UTC (rev 184788)
@@ -2797,7 +2797,7 @@
MediaPlaybackTargetMac* macTarget = toMediaPlaybackTargetMac(&target.get());
m_outputContext = macTarget->outputContext();
- LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p", this, m_outputContext.get());
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p, device name = %s", this, m_outputContext.get(), [m_outputContext.get().deviceName UTF8String]);
if (!m_outputContext || !m_outputContext.get().deviceName)
setShouldPlayToPlaybackTarget(false);
@@ -2812,14 +2812,15 @@
AVOutputContext *newContext = shouldPlay ? m_outputContext.get() : nil;
RetainPtr<AVOutputContext> currentContext = m_avPlayer.get().outputContext;
+
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget(%p) - target = %p, shouldPlay = %s", this, newContext, boolString(shouldPlay));
+
if ((!newContext && !currentContext.get()) || [currentContext.get() isEqual:newContext])
return;
setDelayCallbacks(true);
m_avPlayer.get().outputContext = newContext;
setDelayCallbacks(false);
-
- LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget(%p) - target = %p, playing to target = %s", this, m_avPlayer.get().outputContext, boolString(shouldPlay));
}
bool MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget()