Changeset 182240 in webkit


Ignore:
Timestamp:
Apr 1, 2015, 11:07:16 AM (10 years ago)
Author:
eric.carlson@apple.com
Message:

[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.

Location:
trunk/Source/WebCore
Files:
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r182239 r182240  
     12015-04-01  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [Mac] Do not include route button if element does not support target playback
     4        https://bugs.webkit.org/show_bug.cgi?id=143251
     5
     6        Reviewed by Jer Noble.
     7
     8        * Modules/mediacontrols/mediaControlsApple.js:
     9        (Controller.prototype.currentPlaybackTargetIsWireless): Return false if target playback is disabled.
     10        (Controller.prototype.updateWirelessTargetAvailable): Do not show the picker if target
     11            playback is disabled.
     12        (Controller.prototype.handleWirelessPlaybackChange): Call updateWirelessTargetAvailable.
     13
     14        * dom/Document.cpp:
     15        (WebCore::Document::showPlaybackTargetPicker): Update for Page::showPlaybackTargetPicker change.
     16        (WebCore::Document::didChoosePlaybackTarget): Notify clients in vector-order, lower level code
     17            now tracks which one requested the picker.
     18
     19        * html/HTMLMediaElement.cpp:
     20        (WebCore::HTMLMediaElement::loadResource): Don't call applyMediaPlayerRestrictions, it is done
     21            in mediaPlayerEngineFailedToLoad.
     22        (WebCore::HTMLMediaElement::setReadyState): Enqueue a target availability event if there are
     23            listeners readyState reaches HAVE_METADATA so controls are setup correctly.
     24        (WebCore::HTMLMediaElement::mediaPlayerEngineFailedToLoad): Call applyMediaPlayerRestrictions.
     25        (WebCore::HTMLMediaElement::clearMediaPlayer): Enqueue a target availability event in so controls
     26            have a chance to hide the picker.
     27        (WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsSupported): New, passthrough to the
     28            media engine.
     29        (WebCore::HTMLMediaElement::canPlayToWirelessPlaybackTarget): Ditto.
     30        (WebCore::HTMLMediaElement::startPlayingToPlaybackTarget): Ditto.
     31        (WebCore::HTMLMediaElement::stopPlayingToPlaybackTarget): Ditto.
     32        * html/HTMLMediaElement.h:
     33        * html/HTMLMediaElement.idl:
     34
     35        * html/HTMLMediaSession.cpp:
     36        (WebCore::HTMLMediaSession::HTMLMediaSession): Initialize m_playbackTarget.
     37        (WebCore::HTMLMediaSession::currentPlaybackTargetIsSupported): New.
     38        (WebCore::HTMLMediaSession::showPlaybackTargetPicker): Pull logic from showingPlaybackTargetPickerPermitted
     39            inline. Don't refuse to show a picker if the element doesn't support target playback, it is up
     40            to script to decide which elements can display a picker.
     41        (WebCore::HTMLMediaSession::wirelessVideoPlaybackDisabled): Return true if there is no player.
     42        (WebCore::HTMLMediaSession::didChoosePlaybackTarget): Call startPlayingToPlaybackTarget or
     43            stopPlayingToPlaybackTarget because setWirelessPlaybackTarget doesn't apply the target.
     44        (WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange): Add logging.
     45        (WebCore::HTMLMediaSession::showingPlaybackTargetPickerPermitted): Deleted.
     46        * html/HTMLMediaSession.h:
     47
     48        * page/Page.cpp:
     49        (WebCore::Page::Page): Initialize m_playbackTarget.
     50        (WebCore::Page::showPlaybackTargetPicker): Don't set m_documentRequestingPlaybackTargetPicker.
     51        (WebCore::Page::didChoosePlaybackTarget): Notify Pages in vector-order, lower level code
     52            now tracks which one requested the picker.
     53        (WebCore::Page::configurePlaybackTargetMonitoring): Don't track m_requiresPlaybackTargetMonitoring, it
     54            is too easy for it to get out of sync with the UI process state.
     55        * page/Page.h:
     56
     57        * platform/audio/MediaSession.cpp:
     58        (WebCore::MediaSession::canPlayToWirelessPlaybackTarget): New, client passthrough.
     59        (WebCore::MediaSession::startPlayingToPlaybackTarget): Ditto.
     60        (WebCore::MediaSession::stopPlayingToPlaybackTarget): Ditto.
     61        * platform/audio/MediaSession.h:
     62        (WebCore::MediaSessionClient::canPlayToWirelessPlaybackTarget):
     63        (WebCore::MediaSessionClient::startPlayingToPlaybackTarget):
     64        (WebCore::MediaSessionClient::stopPlayingToPlaybackTarget):
     65
     66        * platform/audio/MediaSessionManager.cpp:
     67        (WebCore::MediaSessionManager::sessionWillBeginPlayback): Call startPlayingToPlaybackTarget &
     68            stopPlayingToPlaybackTarget as necessary.
     69        * platform/audio/MediaSessionManager.h:
     70
     71        * platform/graphics/MediaPlaybackTarget.h:
     72        (WebCore::MediaPlaybackTarget::hasActiveRoute): New.
     73        * platform/graphics/MediaPlaybackTargetPickerClient.h:
     74        * platform/graphics/MediaPlayer.cpp:
     75        (WebCore::MediaPlayer::isCurrentPlaybackTargetSupported): New, engine passthrough.
     76        (WebCore::MediaPlayer::canPlayToWirelessPlaybackTarget): Ditto.
     77        (WebCore::MediaPlayer::startPlayingToPlaybackTarget): Ditto.
     78        (WebCore::MediaPlayer::stopPlayingToPlaybackTarget): Ditto.
     79        * platform/graphics/MediaPlayer.h:
     80        * platform/graphics/MediaPlayerPrivate.h:
     81        (WebCore::MediaPlayerPrivateInterface::isCurrentPlaybackTargetSupported):
     82        (WebCore::MediaPlayerPrivateInterface::wirelessVideoPlaybackDisabled):
     83        (WebCore::MediaPlayerPrivateInterface::canPlayToWirelessPlaybackTarget):
     84        (WebCore::MediaPlayerPrivateInterface::startPlayingToPlaybackTarget):
     85        (WebCore::MediaPlayerPrivateInterface::stopPlayingToPlaybackTarget):
     86
     87        * platform/graphics/avfoundation/MediaPlaybackTargetMac.mm:
     88        (WebCore::MediaPlaybackTarget::hasActiveRoute): New.
     89
     90        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
     91        (WebCore::MediaPlayerPrivateAVFoundationObjC::canPlayToWirelessPlaybackTarget):
     92        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
     93        (WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad): Use playerKVOProperties. Drive-by
     94            code cleanup.
     95        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer): Use playerKVOProperties.
     96        (WebCore::MediaPlayerPrivateAVFoundationObjC::wirelessPlaybackTargetName): Implement for Mac.
     97        (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessVideoPlaybackDisabled): Delay callbacks
     98            while setting AVPlayer property.
     99        (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget): Add logging. Don't set
     100            the AVPlayer outputContext immediately.
     101        (WebCore::MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget): New.
     102        (WebCore::MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget): New.
     103        (WebCore::playerKVOProperties): New.
     104        (-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]): Notify when
     105            allowsExternalPlayback changes.
     106
     107        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
     108        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
     109        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetSupported): New.
     110        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setWirelessPlaybackTarget): Ditto.
     111        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::togglePlayingToPlaybackTarget): Ditto.
     112        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::startPlayingToPlaybackTarget): Ditto.
     113        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::stopPlayingToPlaybackTarget): Ditto.
     114
     115        * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
     116        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
     117        (WebCore::MediaPlayerPrivateQTKit::isCurrentPlaybackTargetSupported): Ditto.
     118        (WebCore::MediaPlayerPrivateQTKit::setWirelessPlaybackTarget): Ditto.
     119        (WebCore::MediaPlayerPrivateQTKit::togglePlayingToPlaybackTarget): Ditto.
     120        (WebCore::MediaPlayerPrivateQTKit::startPlayingToPlaybackTarget): Ditto.
     121        (WebCore::MediaPlayerPrivateQTKit::stopPlayingToPlaybackTarget): Ditto.
     122
    11232015-04-01  Alex Christensen  <achristensen@webkit.org>
    2124
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js

    r182036 r182240  
    16961696
    16971697    currentPlaybackTargetIsWireless: function() {
    1698         return Controller.gSimulateWirelessPlaybackTarget || (('webkitCurrentPlaybackTargetIsWireless' in this.video) && this.video.webkitCurrentPlaybackTargetIsWireless);
     1698        if (Controller.gSimulateWirelessPlaybackTarget)
     1699            return true;
     1700
     1701        if (!this.video.webkitCurrentPlaybackTargetIsWireless || this.video.webkitWirelessVideoPlaybackDisabled)
     1702            return false;
     1703
     1704        return true;
    16991705    },
    17001706
     
    17411747
    17421748    updateWirelessTargetAvailable: function() {
    1743         if (Controller.gSimulateWirelessPlaybackTarget || this.hasWirelessPlaybackTargets)
     1749        var wirelessPlaybackTargetsAvailable = Controller.gSimulateWirelessPlaybackTarget || this.hasWirelessPlaybackTargets;
     1750        if (this.video.webkitWirelessVideoPlaybackDisabled)
     1751            wirelessPlaybackTargetsAvailable = false;
     1752
     1753        if (wirelessPlaybackTargetsAvailable)
    17441754            this.controls.wirelessTargetPicker.classList.remove(this.ClassNames.hidden);
    17451755        else
     
    17541764
    17551765    handleWirelessPlaybackChange: function(event) {
     1766        this.updateWirelessTargetAvailable();
    17561767        this.updateWirelessPlaybackStatus();
    17571768        this.setNeedsTimelineMetricsUpdate();
  • trunk/Source/WebCore/dom/Document.cpp

    r182215 r182240  
    65516551        return;
    65526552
    6553     page->showPlaybackTargetPicker(this, view()->lastKnownMousePosition(), is<HTMLVideoElement>(element));
     6553    page->showPlaybackTargetPicker(view()->lastKnownMousePosition(), is<HTMLVideoElement>(element));
    65546554}
    65556555
     
    66056605void Document::didChoosePlaybackTarget(const MediaPlaybackTarget& device)
    66066606{
    6607     MediaPlaybackTargetPickerClient* clientThatRequestedPicker = nullptr;
    6608 
    6609     for (auto* client : m_playbackTargetClients) {
    6610         if (client->requestedPlaybackTargetPicker()) {
    6611             clientThatRequestedPicker = client;
    6612             continue;
    6613         }
    6614 
     6607    for (auto* client : m_playbackTargetClients)
    66156608        client->didChoosePlaybackTarget(device);
    6616     }
    6617 
    6618     // Notify the client that requested the chooser last because if more than one
    6619     // is playing, only the last one to set the context will actually get to play
    6620     //  to the external device.
    6621     if (clientThatRequestedPicker)
    6622         clientThatRequestedPicker->didChoosePlaybackTarget(device);
    66236609}
    66246610
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r182205 r182240  
    11801180        mediaLoadingFailed(MediaPlayer::FormatError);
    11811181
    1182     m_mediaSession->applyMediaPlayerRestrictions(*this);
    1183 
    11841182    // If there is no poster to display, allow the media engine to render video frames as soon as
    11851183    // they are available.
     
    19881986        scheduleEvent(eventNames().durationchangeEvent);
    19891987        scheduleEvent(eventNames().loadedmetadataEvent);
     1988#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     1989        if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent))
     1990            enqueuePlaybackTargetAvailabilityChangedEvent();
     1991#endif
     1992       
    19901993        if (hasMediaControls())
    19911994            mediaControls()->loadedMetadata();
     
    42694272    m_havePreparedToPlay = false;
    42704273
     4274    m_mediaSession->applyMediaPlayerRestrictions(*this);
     4275
    42714276#if PLATFORM(IOS)
    42724277    if (!m_player)
     
    46554660
    46564661#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    4657     if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent))
     4662    if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
    46584663        m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
     4664
     4665        // Send an availability event in case scripts want to hide the picker when the element
     4666        // doesn't support playback to a target.
     4667        enqueuePlaybackTargetAvailabilityChangedEvent();
     4668    }
    46594669#endif
    46604670
     
    48114821}
    48124822
     4823bool HTMLMediaElement::webkitCurrentPlaybackTargetIsSupported() const
     4824{
     4825    return m_mediaSession->currentPlaybackTargetIsSupported(*this);
     4826}
     4827
    48134828void HTMLMediaElement::wirelessRoutesAvailableDidChange()
    48144829{
     
    48694884    if (m_player)
    48704885        m_player->setWirelessPlaybackTarget(device);
     4886}
     4887
     4888bool HTMLMediaElement::canPlayToWirelessPlaybackTarget()
     4889{
     4890    bool canPlay = m_player && m_player->canPlayToWirelessPlaybackTarget();
     4891
     4892    LOG(Media, "HTMLMediaElement::canPlayToWirelessPlaybackTarget(%p) - returning %s", this, boolString(canPlay));
     4893
     4894    return canPlay;
     4895}
     4896
     4897void HTMLMediaElement::startPlayingToPlaybackTarget()
     4898{
     4899    if (m_player)
     4900        m_player->startPlayingToPlaybackTarget();
     4901}
     4902
     4903void HTMLMediaElement::stopPlayingToPlaybackTarget()
     4904{
     4905    if (m_player)
     4906        m_player->stopPlayingToPlaybackTarget();
    48714907}
    48724908#endif
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r182141 r182240  
    355355    void webkitShowPlaybackTargetPicker();
    356356    bool webkitCurrentPlaybackTargetIsWireless() const;
     357    bool webkitCurrentPlaybackTargetIsSupported() const;
    357358
    358359    virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override;
     
    360361
    361362    virtual void wirelessRoutesAvailableDidChange() override;
     363    virtual bool canPlayToWirelessPlaybackTarget() override;
    362364    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
     365    virtual void startPlayingToPlaybackTarget() override;
     366    virtual void stopPlayingToPlaybackTarget() override;
    363367#endif
    364368
  • trunk/Source/WebCore/html/HTMLMediaElement.idl

    r181358 r182240  
    117117    [Conditional=WIRELESS_PLAYBACK_TARGET] void webkitShowPlaybackTargetPicker();
    118118    [Conditional=WIRELESS_PLAYBACK_TARGET] readonly attribute boolean webkitCurrentPlaybackTargetIsWireless;
     119    [Conditional=WIRELESS_PLAYBACK_TARGET] readonly attribute boolean webkitCurrentPlaybackTargetIsSupported;
    119120};
  • trunk/Source/WebCore/html/HTMLMediaSession.cpp

    r181838 r182240  
    7777#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    7878    , m_targetAvailabilityChangedTimer(*this, &HTMLMediaSession::targetAvailabilityChangedTimerFired)
     79    , m_playbackTarget(std::make_unique<MediaPlaybackTarget>())
    7980#endif
    8081{
     
    164165
    165166#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    166 bool HTMLMediaSession::showingPlaybackTargetPickerPermitted(const HTMLMediaElement& element) const
    167 {
    168     if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGesture()) {
    169         LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning FALSE because of permissions");
    170         return false;
    171     }
    172 
    173     if (!element.document().page()) {
    174         LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning FALSE because page is NULL");
    175         return false;
    176     }
    177 
    178     return !wirelessVideoPlaybackDisabled(element);
    179 }
    180 
    181167bool HTMLMediaSession::currentPlaybackTargetIsWireless(const HTMLMediaElement& element) const
    182168{
     
    193179}
    194180
     181bool HTMLMediaSession::currentPlaybackTargetIsSupported(const HTMLMediaElement& element) const
     182{
     183    MediaPlayer* player = element.player();
     184    if (!player) {
     185        LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsSupported - returning FALSE because player is NULL");
     186        return false;
     187    }
     188
     189    bool isSupported = player->isCurrentPlaybackTargetSupported();
     190    LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsSupported - returning %s", isSupported ? "TRUE" : "FALSE");
     191   
     192    return isSupported;
     193}
     194
    195195void HTMLMediaSession::showPlaybackTargetPicker(const HTMLMediaElement& element)
    196196{
    197197    LOG(Media, "HTMLMediaSession::showPlaybackTargetPicker");
    198198
    199     if (!showingPlaybackTargetPickerPermitted(element))
     199    if (m_restrictions & RequireUserGestureToShowPlaybackTargetPicker && !ScriptController::processingUserGesture()) {
     200        LOG(Media, "HTMLMediaSession::showPlaybackTargetPicker - returning early because of permissions");
    200201        return;
    201 
    202     m_haveRequestedPlaybackTargetPicker = true;
     202    }
     203
     204    if (!element.document().page()) {
     205        LOG(Media, "HTMLMediaSession::showingPlaybackTargetPickerPermitted - returning early because page is NULL");
     206        return;
     207    }
     208
     209    MediaSessionManager::sharedManager().setCurrentSession(*this);
    203210    element.document().showPlaybackTargetPicker(element);
    204211}
     
    239246    MediaPlayer* player = element.player();
    240247    if (!player)
    241         return false;
     248        return true;
    242249
    243250    bool disabled = player->wirelessVideoPlaybackDisabled();
     
    278285void HTMLMediaSession::didChoosePlaybackTarget(const MediaPlaybackTarget& device)
    279286{
    280     m_haveRequestedPlaybackTargetPicker = false;
    281     client().setWirelessPlaybackTarget(device);
     287    m_playbackTarget->setDevicePickerContext(device.devicePickerContext());
     288    client().setWirelessPlaybackTarget(*m_playbackTarget.get());
     289    if (device.hasActiveRoute() && MediaSessionManager::sharedManager().currentSession() == this)
     290        startPlayingToPlaybackTarget();
     291    else
     292        stopPlayingToPlaybackTarget();
    282293}
    283294
     
    291302    if (m_hasPlaybackTargets == hasTargets)
    292303        return;
     304
     305    LOG(Media, "HTMLMediaSession::externalOutputDeviceAvailableDidChange - hasTargets %s", hasTargets ? "TRUE" : "FALSE");
    293306
    294307    m_hasPlaybackTargets = hasTargets;
  • trunk/Source/WebCore/html/HTMLMediaSession.h

    r182068 r182240  
    5555
    5656#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    57     bool showingPlaybackTargetPickerPermitted(const HTMLMediaElement&) const;
    5857    bool currentPlaybackTargetIsWireless(const HTMLMediaElement&) const;
     58    bool currentPlaybackTargetIsSupported(const HTMLMediaElement&) const;
    5959    void showPlaybackTargetPicker(const HTMLMediaElement&);
    6060    bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
     
    103103    virtual void externalOutputDeviceAvailableDidChange(bool) const override;
    104104    virtual bool requiresPlaybackTargetRouteMonitoring() const override;
    105     virtual bool requestedPlaybackTargetPicker() const override { return m_haveRequestedPlaybackTargetPicker; }
    106105#endif
    107106
     
    110109#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    111110    mutable Timer m_targetAvailabilityChangedTimer;
     111    std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
    112112    bool m_hasPlaybackTargetAvailabilityListeners { false };
    113113    mutable bool m_hasPlaybackTargets { false };
    114     mutable bool m_haveRequestedPlaybackTargetPicker { false };
    115114#endif
    116115};
  • trunk/Source/WebCore/page/Page.cpp

    r182132 r182240  
    213213    , m_visitedLinkStore(*WTF::move(pageConfiguration.visitedLinkStore))
    214214    , m_sessionID(SessionID::defaultSessionID())
     215#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     216    , m_playbackTarget(std::make_unique<MediaPlaybackTarget>())
     217#endif
    215218    , m_isClosing(false)
    216219    , m_isPlayingAudio(false)
     
    16821685
    16831686#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    1684 void Page::showPlaybackTargetPicker(Document* document, const WebCore::IntPoint& location, bool isVideo)
    1685 {
    1686     m_documentRequestingPlaybackTargetPicker = document;
    1687 
     1687void Page::showPlaybackTargetPicker(const WebCore::IntPoint& location, bool isVideo)
     1688{
    16881689#if PLATFORM(IOS)
    16891690    // FIXME: refactor iOS implementation.
     
    16971698void Page::didChoosePlaybackTarget(const MediaPlaybackTarget& target)
    16981699{
    1699     Document* documentThatRequestedPicker = nullptr;
    1700 
    1701     m_playbackTarget = std::make_unique<MediaPlaybackTarget>(target.devicePickerContext());
    1702     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
    1703         Document* document = frame->document();
    1704         if (frame->document() == m_documentRequestingPlaybackTargetPicker) {
    1705             documentThatRequestedPicker = document;
    1706             continue;
    1707         }
     1700    m_playbackTarget->setDevicePickerContext(target.devicePickerContext());
     1701    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
    17081702        frame->document()->didChoosePlaybackTarget(target);
    1709     }
    1710 
    1711     // Notify the document that requested the chooser last because if more than one element
    1712     // is playing the last one to set the context will be the one that actually gets to
    1713     //  play to the external device.
    1714     if (documentThatRequestedPicker)
    1715         documentThatRequestedPicker->didChoosePlaybackTarget(target);
    1716 
    1717     m_documentRequestingPlaybackTargetPicker = nullptr;
    17181703}
    17191704
     
    17351720    }
    17361721
    1737     if (m_requiresPlaybackTargetMonitoring == monitoringRequired)
    1738         return;
    1739     m_requiresPlaybackTargetMonitoring = monitoringRequired;
    1740 
    17411722    if (monitoringRequired)
    17421723        chrome().client().startingMonitoringPlaybackTargets();
  • trunk/Source/WebCore/page/Page.h

    r182132 r182240  
    427427
    428428#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    429     void showPlaybackTargetPicker(Document*, const WebCore::IntPoint&, bool);
     429    void showPlaybackTargetPicker(const WebCore::IntPoint&, bool);
    430430    bool hasWirelessPlaybackTarget() const { return m_hasWirelessPlaybackTarget; }
    431431    MediaPlaybackTarget& playbackTarget() const { return *m_playbackTarget.get(); }
     
    588588
    589589#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    590     Document* m_documentRequestingPlaybackTargetPicker { nullptr };
    591590    std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
    592     bool m_requiresPlaybackTargetMonitoring { false };
    593591    bool m_hasWirelessPlaybackTarget { false };
    594592#endif
  • trunk/Source/WebCore/platform/audio/MediaSession.cpp

    r182141 r182240  
    228228}
    229229
     230bool MediaSession::canPlayToWirelessPlaybackTarget() const
     231{
     232    return m_client.canPlayToWirelessPlaybackTarget();
     233}
     234
     235void MediaSession::startPlayingToPlaybackTarget()
     236{
     237    client().startPlayingToPlaybackTarget();
     238}
     239
     240void MediaSession::stopPlayingToPlaybackTarget()
     241{
     242    client().stopPlayingToPlaybackTarget();
     243}
     244
    230245String MediaSessionClient::mediaSessionTitle() const
    231246{
     
    242257    return MediaPlayer::invalidTime();
    243258}
    244 
    245259}
    246260#endif
  • trunk/Source/WebCore/platform/audio/MediaSession.h

    r182141 r182240  
    118118    bool isHidden() const;
    119119
     120    bool canPlayToWirelessPlaybackTarget() const;
     121    void startPlayingToPlaybackTarget();
     122    void stopPlayingToPlaybackTarget();
     123
    120124#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    121125    // MediaPlaybackTargetPickerClient
     
    123127    virtual void externalOutputDeviceAvailableDidChange(bool) const override { }
    124128    virtual bool requiresPlaybackTargetRouteMonitoring() const override { return false; }
    125     virtual bool requestedPlaybackTargetPicker() const override { return false; }
    126129#endif
    127130
     
    165168    virtual bool overrideBackgroundPlaybackRestriction() const = 0;
    166169
    167 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
    168170    virtual void wirelessRoutesAvailableDidChange() { }
    169171    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
    170 #endif
     172    virtual bool canPlayToWirelessPlaybackTarget() { return false; }
     173    virtual void startPlayingToPlaybackTarget() { }
     174    virtual void stopPlayingToPlaybackTarget() { }
    171175
    172176protected:
  • trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp

    r182141 r182240  
    187187        endInterruption(MediaSession::NoFlags);
    188188
    189     if (!restrictions & ConcurrentPlaybackNotPermitted)
    190         return true;
    191 
     189    bool newSessionCanPlayToPlaybackTarget = session.canPlayToWirelessPlaybackTarget();
    192190    Vector<MediaSession*> sessions = m_sessions;
    193191    for (auto* oneSession : sessions) {
    194192        if (oneSession == &session)
    195193            continue;
    196         if (oneSession->mediaType() != sessionType)
    197             continue;
    198         if (restrictions & ConcurrentPlaybackNotPermitted)
     194        if (newSessionCanPlayToPlaybackTarget)
     195            oneSession->stopPlayingToPlaybackTarget();
     196        if (oneSession->mediaType() == sessionType && restrictions & ConcurrentPlaybackNotPermitted)
    199197            oneSession->pauseSession();
    200198    }
    201    
     199    session.startPlayingToPlaybackTarget();
     200
    202201    updateSessionState();
    203202    return true;
  • trunk/Source/WebCore/platform/audio/MediaSessionManager.h

    r182141 r182240  
    8686#endif
    8787
     88    void setCurrentSession(MediaSession&);
     89    MediaSession* currentSession();
     90
    8891protected:
    8992    friend class MediaSession;
     
    9295    void addSession(MediaSession&);
    9396    void removeSession(MediaSession&);
    94 
    95     void setCurrentSession(MediaSession&);
    96     MediaSession* currentSession();
    9797
    9898    Vector<MediaSession*> sessions() { return m_sessions; }
  • trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h

    r182117 r182240  
    5151    void setDevicePickerContext(AVOutputContext *context) { m_devicePickerContext = context; }
    5252    AVOutputContext *devicePickerContext() const { return m_devicePickerContext.get(); }
     53    bool hasActiveRoute() const;
     54#else
     55    void setDevicePickerContext(AVOutputContext *) { }
     56    AVOutputContext *devicePickerContext() const { return nullptr; }
     57    bool hasActiveRoute() const { return false; }
    5358#endif
    5459
  • trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h

    r181838 r182240  
    4343
    4444    virtual bool requiresPlaybackTargetRouteMonitoring() const = 0;
    45     virtual bool requestedPlaybackTargetPicker() const = 0;
    4645};
    4746
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r181423 r182240  
    844844}
    845845
     846bool MediaPlayer::isCurrentPlaybackTargetSupported() const
     847{
     848    return m_private->isCurrentPlaybackTargetSupported();
     849}
     850
    846851String MediaPlayer::wirelessPlaybackTargetName() const
    847852{
     
    869874}
    870875
     876bool MediaPlayer::canPlayToWirelessPlaybackTarget() const
     877{
     878    return m_private->canPlayToWirelessPlaybackTarget();
     879}
     880
    871881void MediaPlayer::setWirelessPlaybackTarget(const MediaPlaybackTarget& device)
    872882{
    873883    m_private->setWirelessPlaybackTarget(device);
     884}
     885
     886void MediaPlayer::startPlayingToPlaybackTarget()
     887{
     888    m_private->startPlayingToPlaybackTarget();
     889}
     890
     891void MediaPlayer::stopPlayingToPlaybackTarget()
     892{
     893    m_private->stopPlayingToPlaybackTarget();
    874894}
    875895#endif
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.h

    r181423 r182240  
    467467#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    468468    bool isCurrentPlaybackTargetWireless() const;
     469    bool isCurrentPlaybackTargetSupported() const;
    469470
    470471    enum WirelessPlaybackTargetType { TargetTypeNone, TargetTypeAirPlay, TargetTypeTVOut };
     
    479480    void playbackTargetAvailabilityChanged();
    480481
     482    bool canPlayToWirelessPlaybackTarget() const;
    481483    void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
     484
     485    void startPlayingToPlaybackTarget();
     486    void stopPlayingToPlaybackTarget();
    482487#endif
    483488
  • trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h

    r181423 r182240  
    162162#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    163163    virtual bool isCurrentPlaybackTargetWireless() const { return false; }
     164    virtual bool isCurrentPlaybackTargetSupported() const { return true; }
    164165
    165166    virtual String wirelessPlaybackTargetName() const { return emptyString(); }
    166167    virtual MediaPlayer::WirelessPlaybackTargetType wirelessPlaybackTargetType() const { return MediaPlayer::TargetTypeNone; }
    167168
    168     virtual bool wirelessVideoPlaybackDisabled() const { return false; }
     169    virtual bool wirelessVideoPlaybackDisabled() const { return true; }
    169170    virtual void setWirelessVideoPlaybackDisabled(bool) { }
    170171
     172    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
    171173    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
     174
     175    virtual void startPlayingToPlaybackTarget() { }
     176    virtual void stopPlayingToPlaybackTarget() { }
    172177#endif
    173178
  • trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm

    r182117 r182240  
    2929#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
    3030
    31 #import <WebCore/MediaPlaybackTarget.h>
     31#import <WebCore/AVFoundationSPI.h>
    3232#import <WebCore/SoftLinking.h>
    3333#import <objc/runtime.h>
     
    6464}
    6565
     66bool MediaPlaybackTarget::hasActiveRoute() const
     67{
     68    return m_devicePickerContext && m_devicePickerContext.get().deviceName;
     69}
     70
     71
    6672} // namespace WebCore
    6773
  • trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp

    r182081 r182240  
    620620void MediaPlayerPrivateAVFoundation::rateChanged()
    621621{
    622 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     622#if ENABLE(WIRELESS_PLAYBACK_TARGET) && PLATFORM(IOS)
    623623    if (isCurrentPlaybackTargetWireless())
    624624        m_player->handlePlaybackCommand(rate() ? MediaSession::PlayCommand : MediaSession::PauseCommand);
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h

    r182117 r182240  
    277277    virtual MediaPlayer::WirelessPlaybackTargetType wirelessPlaybackTargetType() const override;
    278278    virtual bool wirelessVideoPlaybackDisabled() const override;
    279 #if !PLATFORM(IOS)
    280     virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
    281 #endif
    282279    virtual void setWirelessVideoPlaybackDisabled(bool) override;
    283280    void updateDisableExternalPlayback();
     281    bool canPlayToWirelessPlaybackTarget() const { return true; }
     282#endif
     283
     284#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
     285    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
     286    virtual void startPlayingToPlaybackTarget() override;
     287    virtual void stopPlayingToPlaybackTarget() override;
    284288#endif
    285289
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

    r182117 r182240  
    348348static NSArray *assetMetadataKeyNames();
    349349static NSArray *itemKVOProperties();
    350 static NSArray* assetTrackMetadataKeyNames();
     350static NSArray *assetTrackMetadataKeyNames();
     351static NSArray *playerKVOProperties();
    351352
    352353#if !LOG_DISABLED
     
    546547            [m_avPlayer.get() removeTimeObserver:m_timeObserver.get()];
    547548        m_timeObserver = nil;
    548         [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@"rate"];
    549 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
    550         [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@"externalPlaybackActive"];
    551         [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@"outputContext"];
    552 #endif
     549
     550        for (NSString *keyName in playerKVOProperties())
     551            [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:keyName];
    553552        m_avPlayer = nil;
    554553    }
     
    928927
    929928    m_avPlayer = adoptNS([allocAVPlayerInstance() init]);
    930     [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
    931 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
    932     [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@"externalPlaybackActive" options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
    933     [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@"outputContext" options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
     929    for (NSString *keyName in playerKVOProperties())
     930        [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:keyName options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
     931
     932#if HAVE(AVFOUNDATION_MEDIA_SELECTION_GROUP) && HAVE(AVFOUNDATION_LEGIBLE_OUTPUT_SUPPORT)
     933    [m_avPlayer.get() setAppliesMediaSelectionCriteriaAutomatically:NO];
    934934#endif
    935935
    936936#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    937937    updateDisableExternalPlayback();
    938 #endif
    939 
    940 #if HAVE(AVFOUNDATION_MEDIA_SELECTION_GROUP) && HAVE(AVFOUNDATION_LEGIBLE_OUTPUT_SUPPORT)
    941     [m_avPlayer.get() setAppliesMediaSelectionCriteriaAutomatically:NO];
    942 #endif
    943 
    944 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
    945938    [m_avPlayer.get() setAllowsExternalPlayback:m_allowsWirelessVideoPlayback];
    946 #endif
    947 
    948 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
     939
     940#if !PLATFORM(IOS)
    949941    if (m_outputContext)
    950942        m_avPlayer.get().outputContext = m_outputContext.get();
     943#endif
    951944#endif
    952945
     
    27322725    if (!m_avPlayer)
    27332726        return emptyString();
    2734    
    2735     String wirelessTargetName = wkExernalDeviceDisplayNameForPlayer(m_avPlayer.get());
     2727
     2728    String wirelessTargetName;
     2729#if !PLATFORM(IOS)
     2730    if (m_outputContext)
     2731        wirelessTargetName = m_outputContext.get().deviceName;
     2732#else
     2733    wirelessTargetName = wkExernalDeviceDisplayNameForPlayer(m_avPlayer.get());
     2734#endif
    27362735    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::wirelessPlaybackTargetName(%p) - returning %s", this, wirelessTargetName.utf8().data());
    27372736
     
    27572756        return;
    27582757
     2758    setDelayCallbacks(true);
    27592759    [m_avPlayer.get() setAllowsExternalPlayback:!disabled];
     2760    setDelayCallbacks(false);
    27602761}
    27612762
     
    27642765{
    27652766    m_outputContext = target.devicePickerContext();
    2766 
    27672767    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p", this, m_outputContext.get());
    2768 
     2768}
     2769
     2770void MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget()
     2771{
    27692772    if (!m_avPlayer)
    27702773        return;
    27712774
     2775    if ([m_avPlayer.get().outputContext isEqual:m_outputContext.get()])
     2776        return;
     2777
     2778    setDelayCallbacks(true);
    27722779    m_avPlayer.get().outputContext = m_outputContext.get();
     2780    setDelayCallbacks(false);
     2781}
     2782
     2783void MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget()
     2784{
     2785    if (!m_avPlayer)
     2786        return;
     2787
     2788    setDelayCallbacks(true);
     2789    // FIXME: uncomment the following line once rdar://20335217 has been fixed.
     2790    // m_avPlayer.get().outputContext = nil;
     2791    setDelayCallbacks(false);
    27732792}
    27742793#endif
     
    30853104}
    30863105
     3106NSArray* playerKVOProperties()
     3107{
     3108    static NSArray* keys = [[NSArray alloc] initWithObjects:@"rate",
     3109#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     3110                            @"externalPlaybackActive", @"outputContext", @"allowsExternalPlayback",
     3111#endif
     3112                            nil];
     3113    return keys;
     3114}
    30873115} // namespace WebCore
    30883116
     
    32013229            function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::rateDidChange, m_callback, [newValue doubleValue]);
    32023230#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    3203         else if ([keyPath isEqualToString:@"externalPlaybackActive"])
    3204             function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
    3205         else if ([keyPath isEqualToString:@"outputContext"])
     3231        else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"outputContext"] || [keyPath isEqualToString:@"allowsExternalPlayback"])
    32063232            function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
    32073233#endif
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h

    r181865 r182240  
    172172    virtual MediaTime totalFrameDelay() override;
    173173
     174#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     175    virtual bool isCurrentPlaybackTargetSupported() const override;
     176    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
     177    virtual void startPlayingToPlaybackTarget() override;
     178    virtual void stopPlayingToPlaybackTarget() override;
     179    void togglePlayingToPlaybackTarget();
     180#endif
     181
    174182    void ensureLayer();
    175183    void destroyLayer();
     
    213221    mutable bool m_loadingProgressed;
    214222    bool m_hasAvailableVideoFrame;
     223#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     224    std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
     225    bool m_currentPlaybackTargetIsSupported { true };
     226#endif
    215227};
    216228
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm

    r181036 r182240  
    807807}
    808808
    809 }
    810 
     809#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     810bool MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetSupported() const
     811{
     812    if (!m_playbackTarget)
     813        return true;
     814
     815    return !m_playbackTarget->hasActiveRoute();
     816}
     817
     818void MediaPlayerPrivateMediaSourceAVFObjC::setWirelessPlaybackTarget(const MediaPlaybackTarget& target)
     819{
     820    if (!m_playbackTarget)
     821        m_playbackTarget = std::make_unique<MediaPlaybackTarget>();
     822    m_playbackTarget->setDevicePickerContext(target.devicePickerContext());
     823}
     824
     825void MediaPlayerPrivateMediaSourceAVFObjC::togglePlayingToPlaybackTarget()
     826{
     827    bool oldSupported = m_currentPlaybackTargetIsSupported;
     828    m_currentPlaybackTargetIsSupported = !m_playbackTarget || !m_playbackTarget->hasActiveRoute();
     829
     830    if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
     831        m_player->currentPlaybackTargetIsWirelessChanged();
     832}
     833
     834void MediaPlayerPrivateMediaSourceAVFObjC::startPlayingToPlaybackTarget()
     835{
     836    togglePlayingToPlaybackTarget();
     837}
     838
     839void MediaPlayerPrivateMediaSourceAVFObjC::stopPlayingToPlaybackTarget()
     840{
     841    togglePlayingToPlaybackTarget();
     842}
    811843#endif
     844
     845}
     846
     847#endif
  • trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h

    r181153 r182240  
    179179    virtual String engineDescription() const { return "QTKit"; }
    180180    virtual long platformErrorCode() const;
     181
     182#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     183    virtual bool isCurrentPlaybackTargetSupported() const override;
     184    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
     185    virtual void startPlayingToPlaybackTarget() override;
     186    virtual void stopPlayingToPlaybackTarget() override;
     187    void togglePlayingToPlaybackTarget();
     188#endif
    181189
    182190    MediaPlayer* m_player;
     
    207215    mutable MediaTime m_maxTimeLoadedAtLastDidLoadingProgress;
    208216    mutable FloatSize m_cachedNaturalSize;
     217#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     218    std::unique_ptr<MediaPlaybackTarget> m_playbackTarget;
     219    bool m_currentPlaybackTargetIsSupported { true };
     220#endif
    209221};
    210222
  • trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm

    r182204 r182240  
    15411541}
    15421542
     1543#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     1544bool MediaPlayerPrivateQTKit::isCurrentPlaybackTargetSupported() const
     1545{
     1546    if (!m_playbackTarget)
     1547        return true;
     1548
     1549    return !m_playbackTarget->hasActiveRoute();
     1550}
     1551
     1552void MediaPlayerPrivateQTKit::setWirelessPlaybackTarget(const MediaPlaybackTarget& target)
     1553{
     1554    if (!m_playbackTarget)
     1555        m_playbackTarget = std::make_unique<MediaPlaybackTarget>();
     1556    m_playbackTarget->setDevicePickerContext(target.devicePickerContext());
     1557}
     1558
     1559void MediaPlayerPrivateQTKit::togglePlayingToPlaybackTarget()
     1560{
     1561    bool oldSupported = m_currentPlaybackTargetIsSupported;
     1562    m_currentPlaybackTargetIsSupported = !m_playbackTarget || !m_playbackTarget->hasActiveRoute();
     1563
     1564    if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
     1565        m_player->currentPlaybackTargetIsWirelessChanged();
     1566}
     1567
     1568void MediaPlayerPrivateQTKit::startPlayingToPlaybackTarget()
     1569{
     1570    togglePlayingToPlaybackTarget();
     1571}
     1572
     1573void MediaPlayerPrivateQTKit::stopPlayingToPlaybackTarget()
     1574{
     1575    togglePlayingToPlaybackTarget();
     1576}
     1577#endif
     1578
    15431579} // namespace WebCore
    15441580
Note: See TracChangeset for help on using the changeset viewer.