Diff
Modified: trunk/Source/WebCore/ChangeLog (182239 => 182240)
--- trunk/Source/WebCore/ChangeLog 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/ChangeLog 2015-04-01 18:07:16 UTC (rev 182240)
@@ -1,3 +1,125 @@
+2015-04-01 Eric Carlson <eric.carl...@apple.com>
+
+ [Mac] Do not include route button if element does not support target playback
+ https://bugs.webkit.org/show_bug.cgi?id=143251
+
+ Reviewed by Jer Noble.
+
+ * Modules/mediacontrols/mediaControlsApple.js:
+ (Controller.prototype.currentPlaybackTargetIsWireless): Return false if target playback is disabled.
+ (Controller.prototype.updateWirelessTargetAvailable): Do not show the picker if target
+ playback is disabled.
+ (Controller.prototype.handleWirelessPlaybackChange): Call updateWirelessTargetAvailable.
+
+ * dom/Document.cpp:
+ (WebCore::Document::showPlaybackTargetPicker): Update for Page::showPlaybackTargetPicker change.
+ (WebCore::Document::didChoosePlaybackTarget): Notify clients in vector-order, lower level code
+ now tracks which one requested the picker.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::loadResource): Don't call applyMediaPlayerRestrictions, it is done
+ in mediaPlayerEngineFailedToLoad.
+ (WebCore::HTMLMediaElement::setReadyState): Enqueue a target availability event if there are
+ listeners readyState reaches HAVE_METADATA so controls are setup correctly.
+ (WebCore::HTMLMediaElement::mediaPlayerEngineFailedToLoad): Call applyMediaPlayerRestrictions.
+ (WebCore::HTMLMediaElement::clearMediaPlayer): Enqueue a target availability event in so controls
+ have a chance to hide the picker.
+ (WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsSupported): New, passthrough to the
+ media engine.
+ (WebCore::HTMLMediaElement::canPlayToWirelessPlaybackTarget): Ditto.
+ (WebCore::HTMLMediaElement::startPlayingToPlaybackTarget): Ditto.
+ (WebCore::HTMLMediaElement::stopPlayingToPlaybackTarget): Ditto.
+ * html/HTMLMediaElement.h:
+ * html/HTMLMediaElement.idl:
+
+ * html/HTMLMediaSession.cpp:
+ (WebCore::HTMLMediaSession::HTMLMediaSession): Initialize m_playbackTarget.
+ (WebCore::HTMLMediaSession::currentPlaybackTargetIsSupported): New.
+ (WebCore::HTMLMediaSession::showPlaybackTargetPicker): Pull logic from showingPlaybackTargetPickerPermitted
+ inline. Don't refuse to show a picker if the element doesn't support target playback, it is up
+ to script to decide which elements can display a picker.
+ (WebCore::HTMLMediaSession::wirelessVideoPlaybackDisabled): Return true if there is no player.
+ (WebCore::HTMLMediaSession::didChoosePlaybackTarget): Call startPlayingToPlaybackTarget or
+ stopPlayingToPlaybackTarget because setWirelessPlaybackTarget doesn't apply the target.
+ (WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange): Add logging.
+ (WebCore::HTMLMediaSession::showingPlaybackTargetPickerPermitted): Deleted.
+ * html/HTMLMediaSession.h:
+
+ * page/Page.cpp:
+ (WebCore::Page::Page): Initialize m_playbackTarget.
+ (WebCore::Page::showPlaybackTargetPicker): Don't set m_documentRequestingPlaybackTargetPicker.
+ (WebCore::Page::didChoosePlaybackTarget): Notify Pages in vector-order, lower level code
+ now tracks which one requested the picker.
+ (WebCore::Page::configurePlaybackTargetMonitoring): Don't track m_requiresPlaybackTargetMonitoring, it
+ is too easy for it to get out of sync with the UI process state.
+ * page/Page.h:
+
+ * platform/audio/MediaSession.cpp:
+ (WebCore::MediaSession::canPlayToWirelessPlaybackTarget): New, client passthrough.
+ (WebCore::MediaSession::startPlayingToPlaybackTarget): Ditto.
+ (WebCore::MediaSession::stopPlayingToPlaybackTarget): Ditto.
+ * platform/audio/MediaSession.h:
+ (WebCore::MediaSessionClient::canPlayToWirelessPlaybackTarget):
+ (WebCore::MediaSessionClient::startPlayingToPlaybackTarget):
+ (WebCore::MediaSessionClient::stopPlayingToPlaybackTarget):
+
+ * platform/audio/MediaSessionManager.cpp:
+ (WebCore::MediaSessionManager::sessionWillBeginPlayback): Call startPlayingToPlaybackTarget &
+ stopPlayingToPlaybackTarget as necessary.
+ * platform/audio/MediaSessionManager.h:
+
+ * platform/graphics/MediaPlaybackTarget.h:
+ (WebCore::MediaPlaybackTarget::hasActiveRoute): New.
+ * platform/graphics/MediaPlaybackTargetPickerClient.h:
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::isCurrentPlaybackTargetSupported): New, engine passthrough.
+ (WebCore::MediaPlayer::canPlayToWirelessPlaybackTarget): Ditto.
+ (WebCore::MediaPlayer::startPlayingToPlaybackTarget): Ditto.
+ (WebCore::MediaPlayer::stopPlayingToPlaybackTarget): Ditto.
+ * platform/graphics/MediaPlayer.h:
+ * platform/graphics/MediaPlayerPrivate.h:
+ (WebCore::MediaPlayerPrivateInterface::isCurrentPlaybackTargetSupported):
+ (WebCore::MediaPlayerPrivateInterface::wirelessVideoPlaybackDisabled):
+ (WebCore::MediaPlayerPrivateInterface::canPlayToWirelessPlaybackTarget):
+ (WebCore::MediaPlayerPrivateInterface::startPlayingToPlaybackTarget):
+ (WebCore::MediaPlayerPrivateInterface::stopPlayingToPlaybackTarget):
+
+ * platform/graphics/avfoundation/MediaPlaybackTargetMac.mm:
+ (WebCore::MediaPlaybackTarget::hasActiveRoute): New.
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::canPlayToWirelessPlaybackTarget):
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad): Use playerKVOProperties. Drive-by
+ code cleanup.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer): Use playerKVOProperties.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::wirelessPlaybackTargetName): Implement for Mac.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessVideoPlaybackDisabled): Delay callbacks
+ while setting AVPlayer property.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget): Add logging. Don't set
+ the AVPlayer outputContext immediately.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget): New.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget): New.
+ (WebCore::playerKVOProperties): New.
+ (-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]): Notify when
+ allowsExternalPlayback changes.
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetSupported): New.
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setWirelessPlaybackTarget): Ditto.
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::togglePlayingToPlaybackTarget): Ditto.
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::startPlayingToPlaybackTarget): Ditto.
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::stopPlayingToPlaybackTarget): Ditto.
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivateQTKit::isCurrentPlaybackTargetSupported): Ditto.
+ (WebCore::MediaPlayerPrivateQTKit::setWirelessPlaybackTarget): Ditto.
+ (WebCore::MediaPlayerPrivateQTKit::togglePlayingToPlaybackTarget): Ditto.
+ (WebCore::MediaPlayerPrivateQTKit::startPlayingToPlaybackTarget): Ditto.
+ (WebCore::MediaPlayerPrivateQTKit::stopPlayingToPlaybackTarget): Ditto.
+
2015-04-01 Alex Christensen <achristen...@webkit.org>
[Content Extensions] Properly handle regexes that match everything.
Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js (182239 => 182240)
--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js 2015-04-01 18:07:16 UTC (rev 182240)
@@ -1695,7 +1695,13 @@
},
currentPlaybackTargetIsWireless: function() {
- return Controller.gSimulateWirelessPlaybackTarget || (('webkitCurrentPlaybackTargetIsWireless' in this.video) && this.video.webkitCurrentPlaybackTargetIsWireless);
+ if (Controller.gSimulateWirelessPlaybackTarget)
+ return true;
+
+ if (!this.video.webkitCurrentPlaybackTargetIsWireless || this.video.webkitWirelessVideoPlaybackDisabled)
+ return false;
+
+ return true;
},
updateShouldListenForPlaybackTargetAvailabilityEvent: function() {
@@ -1740,7 +1746,11 @@
},
updateWirelessTargetAvailable: function() {
- if (Controller.gSimulateWirelessPlaybackTarget || this.hasWirelessPlaybackTargets)
+ var wirelessPlaybackTargetsAvailable = Controller.gSimulateWirelessPlaybackTarget || this.hasWirelessPlaybackTargets;
+ if (this.video.webkitWirelessVideoPlaybackDisabled)
+ wirelessPlaybackTargetsAvailable = false;
+
+ if (wirelessPlaybackTargetsAvailable)
this.controls.wirelessTargetPicker.classList.remove(this.ClassNames.hidden);
else
this.controls.wirelessTargetPicker.classList.add(this.ClassNames.hidden);
@@ -1753,6 +1763,7 @@
},
handleWirelessPlaybackChange: function(event) {
+ this.updateWirelessTargetAvailable();
this.updateWirelessPlaybackStatus();
this.setNeedsTimelineMetricsUpdate();
},
Modified: trunk/Source/WebCore/dom/Document.cpp (182239 => 182240)
--- trunk/Source/WebCore/dom/Document.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/dom/Document.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -6550,7 +6550,7 @@
if (!page)
return;
- page->showPlaybackTargetPicker(this, view()->lastKnownMousePosition(), is<HTMLVideoElement>(element));
+ page->showPlaybackTargetPicker(view()->lastKnownMousePosition(), is<HTMLVideoElement>(element));
}
void Document::addPlaybackTargetPickerClient(MediaPlaybackTargetPickerClient& client)
@@ -6604,22 +6604,8 @@
void Document::didChoosePlaybackTarget(const MediaPlaybackTarget& device)
{
- MediaPlaybackTargetPickerClient* clientThatRequestedPicker = nullptr;
-
- for (auto* client : m_playbackTargetClients) {
- if (client->requestedPlaybackTargetPicker()) {
- clientThatRequestedPicker = client;
- continue;
- }
-
+ for (auto* client : m_playbackTargetClients)
client->didChoosePlaybackTarget(device);
- }
-
- // Notify the client that requested the chooser last because if more than one
- // is playing, only the last one to set the context will actually get to play
- // to the external device.
- if (clientThatRequestedPicker)
- clientThatRequestedPicker->didChoosePlaybackTarget(device);
}
#endif
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (182239 => 182240)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -1179,8 +1179,6 @@
if (!m_player->load(url, contentType, keySystem))
mediaLoadingFailed(MediaPlayer::FormatError);
- m_mediaSession->applyMediaPlayerRestrictions(*this);
-
// If there is no poster to display, allow the media engine to render video frames as soon as
// they are available.
updateDisplayState();
@@ -1987,6 +1985,11 @@
prepareMediaFragmentURI();
scheduleEvent(eventNames().durationchangeEvent);
scheduleEvent(eventNames().loadedmetadataEvent);
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent))
+ enqueuePlaybackTargetAvailabilityChangedEvent();
+#endif
+
if (hasMediaControls())
mediaControls()->loadedMetadata();
if (renderer())
@@ -4268,6 +4271,8 @@
m_havePreparedToPlay = false;
+ m_mediaSession->applyMediaPlayerRestrictions(*this);
+
#if PLATFORM(IOS)
if (!m_player)
return;
@@ -4654,8 +4659,13 @@
#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent))
+ if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
+
+ // Send an availability event in case scripts want to hide the picker when the element
+ // doesn't support playback to a target.
+ enqueuePlaybackTargetAvailabilityChangedEvent();
+ }
#endif
m_player = nullptr;
@@ -4810,6 +4820,11 @@
return m_mediaSession->currentPlaybackTargetIsWireless(*this);
}
+bool HTMLMediaElement::webkitCurrentPlaybackTargetIsSupported() const
+{
+ return m_mediaSession->currentPlaybackTargetIsSupported(*this);
+}
+
void HTMLMediaElement::wirelessRoutesAvailableDidChange()
{
enqueuePlaybackTargetAvailabilityChangedEvent();
@@ -4869,6 +4884,27 @@
if (m_player)
m_player->setWirelessPlaybackTarget(device);
}
+
+bool HTMLMediaElement::canPlayToWirelessPlaybackTarget()
+{
+ bool canPlay = m_player && m_player->canPlayToWirelessPlaybackTarget();
+
+ LOG(Media, "HTMLMediaElement::canPlayToWirelessPlaybackTarget(%p) - returning %s", this, boolString(canPlay));
+
+ return canPlay;
+}
+
+void HTMLMediaElement::startPlayingToPlaybackTarget()
+{
+ if (m_player)
+ m_player->startPlayingToPlaybackTarget();
+}
+
+void HTMLMediaElement::stopPlayingToPlaybackTarget()
+{
+ if (m_player)
+ m_player->stopPlayingToPlaybackTarget();
+}
#endif
double HTMLMediaElement::minFastReverseRate() const
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (182239 => 182240)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -354,12 +354,16 @@
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void webkitShowPlaybackTargetPicker();
bool webkitCurrentPlaybackTargetIsWireless() const;
+ bool webkitCurrentPlaybackTargetIsSupported() const;
virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override;
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
virtual void wirelessRoutesAvailableDidChange() override;
+ virtual bool canPlayToWirelessPlaybackTarget() override;
virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
+ virtual void startPlayingToPlaybackTarget() override;
+ virtual void stopPlayingToPlaybackTarget() override;
#endif
// EventTarget function.
Modified: trunk/Source/WebCore/html/HTMLMediaElement.idl (182239 => 182240)
--- trunk/Source/WebCore/html/HTMLMediaElement.idl 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/html/HTMLMediaElement.idl 2015-04-01 18:07:16 UTC (rev 182240)
@@ -116,4 +116,5 @@
[Conditional=WIRELESS_PLAYBACK_TARGET] void webkitShowPlaybackTargetPicker();
[Conditional=WIRELESS_PLAYBACK_TARGET] readonly attribute boolean webkitCurrentPlaybackTargetIsWireless;
+ [Conditional=WIRELESS_PLAYBACK_TARGET] readonly attribute boolean webkitCurrentPlaybackTargetIsSupported;
};
Modified: trunk/Source/WebCore/html/HTMLMediaSession.cpp (182239 => 182240)
--- trunk/Source/WebCore/html/HTMLMediaSession.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/html/HTMLMediaSession.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -76,6 +76,7 @@
, m_restrictions(NoRestrictions)
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
, m_targetAvailabilityChangedTimer(*this, &HTMLMediaSession::targetAvailabilityChangedTimerFired)
+ , m_playbackTarget(std::make_unique<MediaPlaybackTarget>())
#endif
{
}
@@ -163,43 +164,49 @@
}
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-bool HTMLMediaSession::showingPlaybackTargetPickerPermitted(const HTMLMediaElement& element) const
+bool HTMLMediaSession::currentPlaybackTargetIsWireless(const HTMLMediaElement& element) const
{
- if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGesture()) {
- LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning FALSE because of permissions");
+ MediaPlayer* player = element.player();
+ if (!player) {
+ LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsWireless - returning FALSE because player is NULL");
return false;
}
- if (!element.document().page()) {
- LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning FALSE because page is NULL");
- return false;
- }
+ bool isWireless = player->isCurrentPlaybackTargetWireless();
+ LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsWireless - returning %s", isWireless ? "TRUE" : "FALSE");
- return !wirelessVideoPlaybackDisabled(element);
+ return isWireless;
}
-bool HTMLMediaSession::currentPlaybackTargetIsWireless(const HTMLMediaElement& element) const
+bool HTMLMediaSession::currentPlaybackTargetIsSupported(const HTMLMediaElement& element) const
{
MediaPlayer* player = element.player();
if (!player) {
- LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsWireless - returning FALSE because player is NULL");
+ LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsSupported - returning FALSE because player is NULL");
return false;
}
- bool isWireless = player->isCurrentPlaybackTargetWireless();
- LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsWireless - returning %s", isWireless ? "TRUE" : "FALSE");
-
- return isWireless;
+ bool isSupported = player->isCurrentPlaybackTargetSupported();
+ LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsSupported - returning %s", isSupported ? "TRUE" : "FALSE");
+
+ return isSupported;
}
void HTMLMediaSession::showPlaybackTargetPicker(const HTMLMediaElement& element)
{
LOG(Media, "HTMLMediaSession::showPlaybackTargetPicker");
- if (!showingPlaybackTargetPickerPermitted(element))
+ if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGesture()) {
+ LOG(Media, "HTMLMediaSession::showPlaybackTargetPicker - returning early because of permissions");
return;
+ }
- m_haveRequestedPlaybackTargetPicker = true;
+ if (!element.document().page()) {
+ LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning early because page is NULL");
+ return;
+ }
+
+ MediaSessionManager::sharedManager().setCurrentSession(*this);
element.document().showPlaybackTargetPicker(element);
}
@@ -238,7 +245,7 @@
MediaPlayer* player = element.player();
if (!player)
- return false;
+ return true;
bool disabled = player->wirelessVideoPlaybackDisabled();
LOG(Media, "HTMLMediaSession::wirelessVideoPlaybackDisabled - returning %s because media engine says so", disabled ? "TRUE" : "FALSE");
@@ -277,8 +284,12 @@
void HTMLMediaSession::didChoosePlaybackTarget(const MediaPlaybackTarget& device)
{
- m_haveRequestedPlaybackTargetPicker = false;
- client().setWirelessPlaybackTarget(device);
+ m_playbackTarget->setDevicePickerContext(device.devicePickerContext());
+ client().setWirelessPlaybackTarget(*m_playbackTarget.get());
+ if (device.hasActiveRoute() && MediaSessionManager::sharedManager().currentSession() == this)
+ startPlayingToPlaybackTarget();
+ else
+ stopPlayingToPlaybackTarget();
}
void HTMLMediaSession::targetAvailabilityChangedTimerFired()
@@ -291,6 +302,8 @@
if (m_hasPlaybackTargets == hasTargets)
return;
+ LOG(Media, "HTMLMediaSession::externalOutputDeviceAvailableDidChange - hasTargets %s", hasTargets ? "TRUE" : "FALSE");
+
m_hasPlaybackTargets = hasTargets;
if (!m_targetAvailabilityChangedTimer.isActive())
m_targetAvailabilityChangedTimer.startOneShot(0);
Modified: trunk/Source/WebCore/html/HTMLMediaSession.h (182239 => 182240)
--- trunk/Source/WebCore/html/HTMLMediaSession.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/html/HTMLMediaSession.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -54,8 +54,8 @@
bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&) const;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- bool showingPlaybackTargetPickerPermitted(const HTMLMediaElement&) const;
bool currentPlaybackTargetIsWireless(const HTMLMediaElement&) const;
+ bool currentPlaybackTargetIsSupported(const HTMLMediaElement&) const;
void showPlaybackTargetPicker(const HTMLMediaElement&);
bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
@@ -102,16 +102,15 @@
virtual void didChoosePlaybackTarget(const MediaPlaybackTarget&) override;
virtual void externalOutputDeviceAvailableDidChange(bool) const override;
virtual bool requiresPlaybackTargetRouteMonitoring() const override;
- virtual bool requestedPlaybackTargetPicker() const override { return m_haveRequestedPlaybackTargetPicker; }
#endif
BehaviorRestrictions m_restrictions;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
mutable Timer m_targetAvailabilityChangedTimer;
+ std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
bool m_hasPlaybackTargetAvailabilityListeners { false };
mutable bool m_hasPlaybackTargets { false };
- mutable bool m_haveRequestedPlaybackTargetPicker { false };
#endif
};
Modified: trunk/Source/WebCore/page/Page.cpp (182239 => 182240)
--- trunk/Source/WebCore/page/Page.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/page/Page.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -212,6 +212,9 @@
, m_userContentController(WTF::move(pageConfiguration.userContentController))
, m_visitedLinkStore(*WTF::move(pageConfiguration.visitedLinkStore))
, m_sessionID(SessionID::defaultSessionID())
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ , m_playbackTarget(std::make_unique<MediaPlaybackTarget>())
+#endif
, m_isClosing(false)
, m_isPlayingAudio(false)
{
@@ -1681,10 +1684,8 @@
}
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void Page::showPlaybackTargetPicker(Document* document, const WebCore::IntPoint& location, bool isVideo)
+void Page::showPlaybackTargetPicker(const WebCore::IntPoint& location, bool isVideo)
{
- m_documentRequestingPlaybackTargetPicker = document;
-
#if PLATFORM(IOS)
// FIXME: refactor iOS implementation.
UNUSED_PARAM(location);
@@ -1696,25 +1697,9 @@
void Page::didChoosePlaybackTarget(const MediaPlaybackTarget& target)
{
- Document* documentThatRequestedPicker = nullptr;
-
- m_playbackTarget = std::make_unique<MediaPlaybackTarget>(target.devicePickerContext());
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- Document* document = frame->document();
- if (frame->document() == m_documentRequestingPlaybackTargetPicker) {
- documentThatRequestedPicker = document;
- continue;
- }
+ m_playbackTarget->setDevicePickerContext(target.devicePickerContext());
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
frame->document()->didChoosePlaybackTarget(target);
- }
-
- // Notify the document that requested the chooser last because if more than one element
- // is playing the last one to set the context will be the one that actually gets to
- // play to the external device.
- if (documentThatRequestedPicker)
- documentThatRequestedPicker->didChoosePlaybackTarget(target);
-
- m_documentRequestingPlaybackTargetPicker = nullptr;
}
void Page::playbackTargetAvailabilityDidChange(bool available)
@@ -1734,10 +1719,6 @@
}
}
- if (m_requiresPlaybackTargetMonitoring == monitoringRequired)
- return;
- m_requiresPlaybackTargetMonitoring = monitoringRequired;
-
if (monitoringRequired)
chrome().client().startingMonitoringPlaybackTargets();
else
Modified: trunk/Source/WebCore/page/Page.h (182239 => 182240)
--- trunk/Source/WebCore/page/Page.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/page/Page.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -426,7 +426,7 @@
WEBCORE_EXPORT void setMuted(bool);
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- void showPlaybackTargetPicker(Document*, const WebCore::IntPoint&, bool);
+ void showPlaybackTargetPicker(const WebCore::IntPoint&, bool);
bool hasWirelessPlaybackTarget() const { return m_hasWirelessPlaybackTarget; }
MediaPlaybackTarget& playbackTarget() const { return *m_playbackTarget.get(); }
void configurePlaybackTargetMonitoring();
@@ -587,9 +587,7 @@
SessionID m_sessionID;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- Document* m_documentRequestingPlaybackTargetPicker { nullptr };
std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
- bool m_requiresPlaybackTargetMonitoring { false };
bool m_hasWirelessPlaybackTarget { false };
#endif
Modified: trunk/Source/WebCore/platform/audio/MediaSession.cpp (182239 => 182240)
--- trunk/Source/WebCore/platform/audio/MediaSession.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/audio/MediaSession.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -227,6 +227,21 @@
return m_client.displayType();
}
+bool MediaSession::canPlayToWirelessPlaybackTarget() const
+{
+ return m_client.canPlayToWirelessPlaybackTarget();
+}
+
+void MediaSession::startPlayingToPlaybackTarget()
+{
+ client().startPlayingToPlaybackTarget();
+}
+
+void MediaSession::stopPlayingToPlaybackTarget()
+{
+ client().stopPlayingToPlaybackTarget();
+}
+
String MediaSessionClient::mediaSessionTitle() const
{
return String();
@@ -241,6 +256,5 @@
{
return MediaPlayer::invalidTime();
}
-
}
#endif
Modified: trunk/Source/WebCore/platform/audio/MediaSession.h (182239 => 182240)
--- trunk/Source/WebCore/platform/audio/MediaSession.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/audio/MediaSession.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -117,12 +117,15 @@
bool isHidden() const;
+ bool canPlayToWirelessPlaybackTarget() const;
+ void startPlayingToPlaybackTarget();
+ void stopPlayingToPlaybackTarget();
+
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
// MediaPlaybackTargetPickerClient
virtual void didChoosePlaybackTarget(const MediaPlaybackTarget&) override { }
virtual void externalOutputDeviceAvailableDidChange(bool) const override { }
virtual bool requiresPlaybackTargetRouteMonitoring() const override { return false; }
- virtual bool requestedPlaybackTargetPicker() const override { return false; }
#endif
protected:
@@ -164,10 +167,11 @@
virtual bool overrideBackgroundPlaybackRestriction() const = 0;
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
virtual void wirelessRoutesAvailableDidChange() { }
virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
-#endif
+ virtual bool canPlayToWirelessPlaybackTarget() { return false; }
+ virtual void startPlayingToPlaybackTarget() { }
+ virtual void stopPlayingToPlaybackTarget() { }
protected:
virtual ~MediaSessionClient() { }
Modified: trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp (182239 => 182240)
--- trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -186,19 +186,18 @@
if (m_interrupted)
endInterruption(MediaSession::NoFlags);
- if (!restrictions & ConcurrentPlaybackNotPermitted)
- return true;
-
+ bool newSessionCanPlayToPlaybackTarget = session.canPlayToWirelessPlaybackTarget();
Vector<MediaSession*> sessions = m_sessions;
for (auto* oneSession : sessions) {
if (_oneSession_ == &session)
continue;
- if (oneSession->mediaType() != sessionType)
- continue;
- if (restrictions & ConcurrentPlaybackNotPermitted)
+ if (newSessionCanPlayToPlaybackTarget)
+ oneSession->stopPlayingToPlaybackTarget();
+ if (oneSession->mediaType() == sessionType && restrictions & ConcurrentPlaybackNotPermitted)
oneSession->pauseSession();
}
-
+ session.startPlayingToPlaybackTarget();
+
updateSessionState();
return true;
}
Modified: trunk/Source/WebCore/platform/audio/MediaSessionManager.h (182239 => 182240)
--- trunk/Source/WebCore/platform/audio/MediaSessionManager.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/audio/MediaSessionManager.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -85,6 +85,9 @@
virtual bool hasWirelessTargetsAvailable() { return false; }
#endif
+ void setCurrentSession(MediaSession&);
+ MediaSession* currentSession();
+
protected:
friend class MediaSession;
explicit MediaSessionManager();
@@ -92,9 +95,6 @@
void addSession(MediaSession&);
void removeSession(MediaSession&);
- void setCurrentSession(MediaSession&);
- MediaSession* currentSession();
-
Vector<MediaSession*> sessions() { return m_sessions; }
private:
Modified: trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -50,6 +50,11 @@
void setDevicePickerContext(AVOutputContext *context) { m_devicePickerContext = context; }
AVOutputContext *devicePickerContext() const { return m_devicePickerContext.get(); }
+ bool hasActiveRoute() const;
+#else
+ void setDevicePickerContext(AVOutputContext *) { }
+ AVOutputContext *devicePickerContext() const { return nullptr; }
+ bool hasActiveRoute() const { return false; }
#endif
protected:
Modified: trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -42,7 +42,6 @@
virtual void externalOutputDeviceAvailableDidChange(bool) const = 0;
virtual bool requiresPlaybackTargetRouteMonitoring() const = 0;
- virtual bool requestedPlaybackTargetPicker() const = 0;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -843,6 +843,11 @@
return m_private->isCurrentPlaybackTargetWireless();
}
+bool MediaPlayer::isCurrentPlaybackTargetSupported() const
+{
+ return m_private->isCurrentPlaybackTargetSupported();
+}
+
String MediaPlayer::wirelessPlaybackTargetName() const
{
return m_private->wirelessPlaybackTargetName();
@@ -868,10 +873,25 @@
m_client.mediaPlayerCurrentPlaybackTargetIsWirelessChanged(this);
}
+bool MediaPlayer::canPlayToWirelessPlaybackTarget() const
+{
+ return m_private->canPlayToWirelessPlaybackTarget();
+}
+
void MediaPlayer::setWirelessPlaybackTarget(const MediaPlaybackTarget& device)
{
m_private->setWirelessPlaybackTarget(device);
}
+
+void MediaPlayer::startPlayingToPlaybackTarget()
+{
+ m_private->startPlayingToPlaybackTarget();
+}
+
+void MediaPlayer::stopPlayingToPlaybackTarget()
+{
+ m_private->stopPlayingToPlaybackTarget();
+}
#endif
double MediaPlayer::maxFastForwardRate() const
Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -466,6 +466,7 @@
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
bool isCurrentPlaybackTargetWireless() const;
+ bool isCurrentPlaybackTargetSupported() const;
enum WirelessPlaybackTargetType { TargetTypeNone, TargetTypeAirPlay, TargetTypeTVOut };
WirelessPlaybackTargetType wirelessPlaybackTargetType() const;
@@ -478,7 +479,11 @@
void currentPlaybackTargetIsWirelessChanged();
void playbackTargetAvailabilityChanged();
+ bool canPlayToWirelessPlaybackTarget() const;
void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
+
+ void startPlayingToPlaybackTarget();
+ void stopPlayingToPlaybackTarget();
#endif
double minFastReverseRate() const;
Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -161,14 +161,19 @@
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
virtual bool isCurrentPlaybackTargetWireless() const { return false; }
+ virtual bool isCurrentPlaybackTargetSupported() const { return true; }
virtual String wirelessPlaybackTargetName() const { return emptyString(); }
virtual MediaPlayer::WirelessPlaybackTargetType wirelessPlaybackTargetType() const { return MediaPlayer::TargetTypeNone; }
- virtual bool wirelessVideoPlaybackDisabled() const { return false; }
+ virtual bool wirelessVideoPlaybackDisabled() const { return true; }
virtual void setWirelessVideoPlaybackDisabled(bool) { }
+ virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
+
+ virtual void startPlayingToPlaybackTarget() { }
+ virtual void stopPlayingToPlaybackTarget() { }
#endif
#if USE(NATIVE_FULLSCREEN_VIDEO)
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm 2015-04-01 18:07:16 UTC (rev 182240)
@@ -28,7 +28,7 @@
#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-#import <WebCore/MediaPlaybackTarget.h>
+#import <WebCore/AVFoundationSPI.h>
#import <WebCore/SoftLinking.h>
#import <objc/runtime.h>
@@ -63,6 +63,12 @@
return true;
}
+bool MediaPlaybackTarget::hasActiveRoute() const
+{
+ return m_devicePickerContext && m_devicePickerContext.get().deviceName;
+}
+
+
} // namespace WebCore
#endif // ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp 2015-04-01 18:07:16 UTC (rev 182240)
@@ -619,7 +619,7 @@
void MediaPlayerPrivateAVFoundation::rateChanged()
{
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && PLATFORM(IOS)
if (isCurrentPlaybackTargetWireless())
m_player->handlePlaybackCommand(rate() ? MediaSession::PlayCommand : MediaSession::PauseCommand);
#endif
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -276,13 +276,17 @@
virtual String wirelessPlaybackTargetName() const override;
virtual MediaPlayer::WirelessPlaybackTargetType wirelessPlaybackTargetType() const override;
virtual bool wirelessVideoPlaybackDisabled() const override;
-#if !PLATFORM(IOS)
- virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
-#endif
virtual void setWirelessVideoPlaybackDisabled(bool) override;
void updateDisableExternalPlayback();
+ bool canPlayToWirelessPlaybackTarget() const { return true; }
#endif
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+ virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
+ virtual void startPlayingToPlaybackTarget() override;
+ virtual void stopPlayingToPlaybackTarget() override;
+#endif
+
virtual double maxFastForwardRate() const override { return m_cachedCanPlayFastForward ? std::numeric_limits<double>::infinity() : 2.0; }
virtual double minFastReverseRate() const override { return m_cachedCanPlayFastReverse ? -std::numeric_limits<double>::infinity() : 0.0; }
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2015-04-01 18:07:16 UTC (rev 182240)
@@ -347,7 +347,8 @@
static NSArray *assetMetadataKeyNames();
static NSArray *itemKVOProperties();
-static NSArray* assetTrackMetadataKeyNames();
+static NSArray *assetTrackMetadataKeyNames();
+static NSArray *playerKVOProperties();
#if !LOG_DISABLED
static const char *boolString(bool val)
@@ -545,11 +546,9 @@
if (m_timeObserver)
[m_avPlayer.get() removeTimeObserver:m_timeObserver.get()];
m_timeObserver = nil;
- [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@"rate"];
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@"externalPlaybackActive"];
- [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@"outputContext"];
-#endif
+
+ for (NSString *keyName in playerKVOProperties())
+ [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:keyName];
m_avPlayer = nil;
}
@@ -927,28 +926,22 @@
setDelayCallbacks(true);
m_avPlayer = adoptNS([allocAVPlayerInstance() init]);
- [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@"externalPlaybackActive" options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
- [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@"outputContext" options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
-#endif
+ for (NSString *keyName in playerKVOProperties())
+ [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:keyName options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- updateDisableExternalPlayback();
-#endif
-
#if HAVE(AVFOUNDATION_MEDIA_SELECTION_GROUP) && HAVE(AVFOUNDATION_LEGIBLE_OUTPUT_SUPPORT)
[m_avPlayer.get() setAppliesMediaSelectionCriteriaAutomatically:NO];
#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ updateDisableExternalPlayback();
[m_avPlayer.get() setAllowsExternalPlayback:m_allowsWirelessVideoPlayback];
-#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+#if !PLATFORM(IOS)
if (m_outputContext)
m_avPlayer.get().outputContext = m_outputContext.get();
#endif
+#endif
if (player()->client().mediaPlayerIsVideo())
createAVPlayerLayer();
@@ -2731,8 +2724,14 @@
{
if (!m_avPlayer)
return emptyString();
-
- String wirelessTargetName = wkExernalDeviceDisplayNameForPlayer(m_avPlayer.get());
+
+ String wirelessTargetName;
+#if !PLATFORM(IOS)
+ if (m_outputContext)
+ wirelessTargetName = m_outputContext.get().deviceName;
+#else
+ wirelessTargetName = wkExernalDeviceDisplayNameForPlayer(m_avPlayer.get());
+#endif
LOG(Media, "MediaPlayerPrivateAVFoundationObjC::wirelessPlaybackTargetName(%p) - returning %s", this, wirelessTargetName.utf8().data());
return wirelessTargetName;
@@ -2756,21 +2755,41 @@
if (!m_avPlayer)
return;
+ setDelayCallbacks(true);
[m_avPlayer.get() setAllowsExternalPlayback:!disabled];
+ setDelayCallbacks(false);
}
#if !PLATFORM(IOS)
void MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(const MediaPlaybackTarget& target)
{
m_outputContext = target.devicePickerContext();
-
LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p", this, m_outputContext.get());
+}
+void MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget()
+{
if (!m_avPlayer)
return;
+ if ([m_avPlayer.get().outputContext isEqual:m_outputContext.get()])
+ return;
+
+ setDelayCallbacks(true);
m_avPlayer.get().outputContext = m_outputContext.get();
+ setDelayCallbacks(false);
}
+
+void MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget()
+{
+ if (!m_avPlayer)
+ return;
+
+ setDelayCallbacks(true);
+ // FIXME: uncomment the following line once rdar://20335217 has been fixed.
+ // m_avPlayer.get().outputContext = nil;
+ setDelayCallbacks(false);
+}
#endif
void MediaPlayerPrivateAVFoundationObjC::updateDisableExternalPlayback()
@@ -3084,6 +3103,15 @@
return keys;
}
+NSArray* playerKVOProperties()
+{
+ static NSArray* keys = [[NSArray alloc] initWithObjects:@"rate",
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ @"externalPlaybackActive", @"outputContext", @"allowsExternalPlayback",
+#endif
+ nil];
+ return keys;
+}
} // namespace WebCore
@implementation WebCoreAVFMovieObserver
@@ -3200,10 +3228,8 @@
if ([keyPath isEqualToString:@"rate"])
function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::rateDidChange, m_callback, [newValue doubleValue]);
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- else if ([keyPath isEqualToString:@"externalPlaybackActive"])
+ else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"outputContext"] || [keyPath isEqualToString:@"allowsExternalPlayback"])
function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
- else if ([keyPath isEqualToString:@"outputContext"])
- function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
#endif
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -171,6 +171,14 @@
virtual unsigned long corruptedVideoFrames() override;
virtual MediaTime totalFrameDelay() override;
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ virtual bool isCurrentPlaybackTargetSupported() const override;
+ virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
+ virtual void startPlayingToPlaybackTarget() override;
+ virtual void stopPlayingToPlaybackTarget() override;
+ void togglePlayingToPlaybackTarget();
+#endif
+
void ensureLayer();
void destroyLayer();
bool shouldBePlaying() const;
@@ -212,6 +220,10 @@
bool m_seekCompleted;
mutable bool m_loadingProgressed;
bool m_hasAvailableVideoFrame;
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
+ bool m_currentPlaybackTargetIsSupported { true };
+#endif
};
}
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2015-04-01 18:07:16 UTC (rev 182240)
@@ -806,6 +806,42 @@
m_player->characteristicChanged();
}
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+bool MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetSupported() const
+{
+ if (!m_playbackTarget)
+ return true;
+
+ return !m_playbackTarget->hasActiveRoute();
}
+void MediaPlayerPrivateMediaSourceAVFObjC::setWirelessPlaybackTarget(const MediaPlaybackTarget& target)
+{
+ if (!m_playbackTarget)
+ m_playbackTarget = std::make_unique<MediaPlaybackTarget>();
+ m_playbackTarget->setDevicePickerContext(target.devicePickerContext());
+}
+
+void MediaPlayerPrivateMediaSourceAVFObjC::togglePlayingToPlaybackTarget()
+{
+ bool oldSupported = m_currentPlaybackTargetIsSupported;
+ m_currentPlaybackTargetIsSupported = !m_playbackTarget || !m_playbackTarget->hasActiveRoute();
+
+ if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
+ m_player->currentPlaybackTargetIsWirelessChanged();
+}
+
+void MediaPlayerPrivateMediaSourceAVFObjC::startPlayingToPlaybackTarget()
+{
+ togglePlayingToPlaybackTarget();
+}
+
+void MediaPlayerPrivateMediaSourceAVFObjC::stopPlayingToPlaybackTarget()
+{
+ togglePlayingToPlaybackTarget();
+}
#endif
+
+}
+
+#endif
Modified: trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h 2015-04-01 18:07:16 UTC (rev 182240)
@@ -179,6 +179,14 @@
virtual String engineDescription() const { return "QTKit"; }
virtual long platformErrorCode() const;
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ virtual bool isCurrentPlaybackTargetSupported() const override;
+ virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
+ virtual void startPlayingToPlaybackTarget() override;
+ virtual void stopPlayingToPlaybackTarget() override;
+ void togglePlayingToPlaybackTarget();
+#endif
+
MediaPlayer* m_player;
RetainPtr<QTMovie> m_qtMovie;
RetainPtr<QTVideoRendererWebKitOnly> m_qtVideoRenderer;
@@ -206,6 +214,10 @@
bool m_privateBrowsing;
mutable MediaTime m_maxTimeLoadedAtLastDidLoadingProgress;
mutable FloatSize m_cachedNaturalSize;
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
+ bool m_currentPlaybackTargetIsSupported { true };
+#endif
};
}
Modified: trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm (182239 => 182240)
--- trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm 2015-04-01 17:48:57 UTC (rev 182239)
+++ trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm 2015-04-01 18:07:16 UTC (rev 182240)
@@ -1540,6 +1540,42 @@
return false;
}
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+bool MediaPlayerPrivateQTKit::isCurrentPlaybackTargetSupported() const
+{
+ if (!m_playbackTarget)
+ return true;
+
+ return !m_playbackTarget->hasActiveRoute();
+}
+
+void MediaPlayerPrivateQTKit::setWirelessPlaybackTarget(const MediaPlaybackTarget& target)
+{
+ if (!m_playbackTarget)
+ m_playbackTarget = std::make_unique<MediaPlaybackTarget>();
+ m_playbackTarget->setDevicePickerContext(target.devicePickerContext());
+}
+
+void MediaPlayerPrivateQTKit::togglePlayingToPlaybackTarget()
+{
+ bool oldSupported = m_currentPlaybackTargetIsSupported;
+ m_currentPlaybackTargetIsSupported = !m_playbackTarget || !m_playbackTarget->hasActiveRoute();
+
+ if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
+ m_player->currentPlaybackTargetIsWirelessChanged();
+}
+
+void MediaPlayerPrivateQTKit::startPlayingToPlaybackTarget()
+{
+ togglePlayingToPlaybackTarget();
+}
+
+void MediaPlayerPrivateQTKit::stopPlayingToPlaybackTarget()
+{
+ togglePlayingToPlaybackTarget();
+}
+#endif
+
} // namespace WebCore
@implementation WebCoreMovieObserver