Changeset 182486 in webkit


Ignore:
Timestamp:
Apr 7, 2015 1:23:17 PM (9 years ago)
Author:
eric.carlson@apple.com
Message:

[Mac] video playing to external device should not be interrupted
https://bugs.webkit.org/show_bug.cgi?id=143492

Reviewed by Jer Noble.

  • Modules/mediacontrols/mediaControlsApple.js:

(Controller.prototype.handlePanelTransitionEnd): Drive-by fix to make sure the controls are

not hidden if the opacity timer is primed before they go into a state where they should
never be hidden.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::canPlayToWirelessPlaybackTarget): Make it const.
(WebCore::HTMLMediaElement::isPlayingToWirelessPlaybackTarget): New.

  • html/HTMLMediaElement.h:
  • html/HTMLMediaSession.cpp:

(WebCore::HTMLMediaSession::canPlayToWirelessPlaybackTarget): New. Short-circuit call to

client when we already know the answer.

(WebCore::HTMLMediaSession::isPlayingToWirelessPlaybackTarget): Ditto.
(WebCore::HTMLMediaSession::startPlayingToPlaybackTarget): Ditto.
(WebCore::HTMLMediaSession::stopPlayingToPlaybackTarget): Ditto.

  • html/HTMLMediaSession.h:
  • platform/audio/MediaSession.cpp:

(WebCore::MediaSession::canPlayToWirelessPlaybackTarget): Deleted, moved inline and neutered

because only HTMLMediaSession needs to use them.

(WebCore::MediaSession::startPlayingToPlaybackTarget): Ditto.
(WebCore::MediaSession::stopPlayingToPlaybackTarget): Ditto.

  • platform/audio/MediaSession.h:

(WebCore::MediaSession::canPlayToWirelessPlaybackTarget):
(WebCore::MediaSession::isPlayingToWirelessPlaybackTarget):
(WebCore::MediaSession::startPlayingToPlaybackTarget):
(WebCore::MediaSession::stopPlayingToPlaybackTarget):
(WebCore::MediaSessionClient::canPlayToWirelessPlaybackTarget):
(WebCore::MediaSessionClient::isPlayingToWirelessPlaybackTarget):

  • platform/audio/MediaSessionManager.cpp:

(WebCore::MediaSessionManager::MediaSessionManager):
(WebCore::MediaSessionManager::sessionShouldBeginPlayingToWirelessPlaybackTarget): New.
(WebCore::MediaSessionManager::sessionWillBeginPlayback): Don't interrupt an active session

playing to a target device.

  • platform/audio/MediaSessionManager.h:
  • platform/graphics/MediaPlayer.cpp:

(WebCore::MediaPlayer::isPlayingToWirelessPlaybackTarget): New, passthrough.

  • platform/graphics/MediaPlayer.h:
  • platform/graphics/MediaPlayerPrivate.h:

(WebCore::MediaPlayerPrivateInterface::isPlayingToWirelessPlaybackTarget):

  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:

(WebCore::MediaPlayerPrivateAVFoundationObjC::canPlayToWirelessPlaybackTarget):

  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:

(WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget): Explicitly call

when passed a nil or inactive target context.

(WebCore::MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget): Add logging.
(WebCore::MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget): Ditto.
(WebCore::MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget): New. Return

true when playing with an active context.

(WebCore::playerKVOProperties): "outputContext" is not observable.

Location:
trunk/Source/WebCore
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r182478 r182486  
     12015-04-07  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [Mac] video playing to external device should not be interrupted
     4        https://bugs.webkit.org/show_bug.cgi?id=143492
     5
     6        Reviewed by Jer Noble.
     7
     8        * Modules/mediacontrols/mediaControlsApple.js:
     9        (Controller.prototype.handlePanelTransitionEnd):  Drive-by fix to make sure the controls are
     10            not hidden if the opacity timer is primed before they go into a state where they should
     11            never be hidden.
     12
     13        * html/HTMLMediaElement.cpp:
     14        (WebCore::HTMLMediaElement::canPlayToWirelessPlaybackTarget): Make it const.
     15        (WebCore::HTMLMediaElement::isPlayingToWirelessPlaybackTarget): New.
     16        * html/HTMLMediaElement.h:
     17
     18        * html/HTMLMediaSession.cpp:
     19        (WebCore::HTMLMediaSession::canPlayToWirelessPlaybackTarget): New. Short-circuit call to
     20            client when we already know the answer.
     21        (WebCore::HTMLMediaSession::isPlayingToWirelessPlaybackTarget): Ditto.
     22        (WebCore::HTMLMediaSession::startPlayingToPlaybackTarget): Ditto.
     23        (WebCore::HTMLMediaSession::stopPlayingToPlaybackTarget): Ditto.
     24        * html/HTMLMediaSession.h:
     25
     26        * platform/audio/MediaSession.cpp:
     27        (WebCore::MediaSession::canPlayToWirelessPlaybackTarget): Deleted, moved inline and neutered
     28            because only HTMLMediaSession needs to use them.
     29        (WebCore::MediaSession::startPlayingToPlaybackTarget): Ditto.
     30        (WebCore::MediaSession::stopPlayingToPlaybackTarget): Ditto.
     31        * platform/audio/MediaSession.h:
     32        (WebCore::MediaSession::canPlayToWirelessPlaybackTarget):
     33        (WebCore::MediaSession::isPlayingToWirelessPlaybackTarget):
     34        (WebCore::MediaSession::startPlayingToPlaybackTarget):
     35        (WebCore::MediaSession::stopPlayingToPlaybackTarget):
     36        (WebCore::MediaSessionClient::canPlayToWirelessPlaybackTarget):
     37        (WebCore::MediaSessionClient::isPlayingToWirelessPlaybackTarget):
     38
     39        * platform/audio/MediaSessionManager.cpp:
     40        (WebCore::MediaSessionManager::MediaSessionManager):
     41        (WebCore::MediaSessionManager::sessionShouldBeginPlayingToWirelessPlaybackTarget): New.
     42        (WebCore::MediaSessionManager::sessionWillBeginPlayback): Don't interrupt an active session
     43            playing to a target device.
     44        * platform/audio/MediaSessionManager.h:
     45
     46        * platform/graphics/MediaPlayer.cpp:
     47        (WebCore::MediaPlayer::isPlayingToWirelessPlaybackTarget): New, passthrough.
     48        * platform/graphics/MediaPlayer.h:
     49        * platform/graphics/MediaPlayerPrivate.h:
     50        (WebCore::MediaPlayerPrivateInterface::isPlayingToWirelessPlaybackTarget):
     51
     52        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
     53        (WebCore::MediaPlayerPrivateAVFoundationObjC::canPlayToWirelessPlaybackTarget):
     54        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
     55        (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget): Explicitly call
     56            when passed a nil or inactive target context.
     57        (WebCore::MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget): Add logging.
     58        (WebCore::MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget): Ditto.
     59        (WebCore::MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget): New. Return
     60            true when playing with an active context.
     61        (WebCore::playerKVOProperties): "outputContext" is not observable.
     62
    1632015-04-07  Sam Weinig  <sam@webkit.org>
    264
  • trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js

    r182282 r182486  
    784784        if (parseInt(opacity) > 0) {
    785785            this.controls.panel.classList.remove(this.ClassNames.hidden);
    786         } else {
     786        } else if (!this.controlsAlwaysVisible()) {
    787787            this.controls.panel.classList.add(this.ClassNames.hidden);
    788788        }
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r182478 r182486  
    73047304                078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaPlaybackTargetPickerMac.h; path = objc/MediaPlaybackTargetPickerMac.h; sourceTree = "<group>"; };
    73057305                078E43DC1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MediaPlaybackTargetPickerMac.mm; path = objc/MediaPlaybackTargetPickerMac.mm; sourceTree = "<group>"; };
    7306                 079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaPlaybackTargetPickerClient.h; path = graphics/MediaPlaybackTargetPickerClient.h; sourceTree = "<group>"; };
     7306                079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetPickerClient.h; sourceTree = "<group>"; };
    73077307                0794178F166E855F009416C2 /* InbandTextTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InbandTextTrack.cpp; sourceTree = "<group>"; };
    73087308                07941790166E855F009416C2 /* InbandTextTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrack.h; sourceTree = "<group>"; };
     
    2081920819                                078E43D71ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.cpp */,
    2082020820                                078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */,
     20821                                079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */,
    2082120822                                E4B41E0C0CBF90BD00AF2ECE /* MediaPlayer.cpp */,
    2082220823                                E4B41E0D0CBF90BD00AF2ECE /* MediaPlayer.h */,
     
    2162421625                        isa = PBXGroup;
    2162521626                        children = (
    21626                                 079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */,
    2162721627                                49E912A40EFAC8E6009D0CAF /* animation */,
    2162821628                                FD31604012B026A300C1A359 /* audio */,
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r182240 r182486  
    48864886}
    48874887
    4888 bool HTMLMediaElement::canPlayToWirelessPlaybackTarget()
     4888bool HTMLMediaElement::canPlayToWirelessPlaybackTarget() const
    48894889{
    48904890    bool canPlay = m_player && m_player->canPlayToWirelessPlaybackTarget();
     
    48934893
    48944894    return canPlay;
     4895}
     4896
     4897bool HTMLMediaElement::isPlayingToWirelessPlaybackTarget() const
     4898{
     4899    bool isPlaying = m_player && m_player->isPlayingToWirelessPlaybackTarget();
     4900
     4901    LOG(Media, "HTMLMediaElement::isPlayingToWirelessPlaybackTarget(%p) - returning %s", this, boolString(isPlaying));
     4902   
     4903    return isPlaying;
    48954904}
    48964905
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r182439 r182486  
    362362
    363363    virtual void wirelessRoutesAvailableDidChange() override;
    364     virtual bool canPlayToWirelessPlaybackTarget() override;
     364    virtual bool canPlayToWirelessPlaybackTarget() const override;
     365    virtual bool isPlayingToWirelessPlaybackTarget() const override;
    365366    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
    366367    virtual void startPlayingToPlaybackTarget() override;
  • trunk/Source/WebCore/html/HTMLMediaSession.cpp

    r182274 r182486  
    318318    return m_hasPlaybackTargetAvailabilityListeners;
    319319}
     320
     321bool HTMLMediaSession::canPlayToWirelessPlaybackTarget() const
     322{
     323    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
     324        return false;
     325
     326    return client().canPlayToWirelessPlaybackTarget();
     327}
     328
     329bool HTMLMediaSession::isPlayingToWirelessPlaybackTarget() const
     330{
     331    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
     332        return false;
     333
     334    return client().isPlayingToWirelessPlaybackTarget();
     335}
     336
     337void HTMLMediaSession::startPlayingToPlaybackTarget()
     338{
     339    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
     340        return;
     341
     342    client().startPlayingToPlaybackTarget();
     343}
     344
     345void HTMLMediaSession::stopPlayingToPlaybackTarget()
     346{
     347    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
     348        return;
     349
     350    client().stopPlayingToPlaybackTarget();
     351}   
    320352#endif
    321353
  • trunk/Source/WebCore/html/HTMLMediaSession.h

    r182240 r182486  
    6464
    6565    void setHasPlaybackTargetAvailabilityListeners(const HTMLMediaElement&, bool);
     66
     67    virtual bool canPlayToWirelessPlaybackTarget() const override;
     68    virtual bool isPlayingToWirelessPlaybackTarget() const override;
     69    virtual void startPlayingToPlaybackTarget() override;
     70    virtual void stopPlayingToPlaybackTarget() override;
    6671#endif
    6772
  • trunk/Source/WebCore/platform/audio/MediaSession.cpp

    r182240 r182486  
    228228}
    229229
    230 bool MediaSession::canPlayToWirelessPlaybackTarget() const
    231 {
    232     return m_client.canPlayToWirelessPlaybackTarget();
    233 }
    234 
    235 void MediaSession::startPlayingToPlaybackTarget()
    236 {
    237     client().startPlayingToPlaybackTarget();
    238 }
    239 
    240 void MediaSession::stopPlayingToPlaybackTarget()
    241 {
    242     client().stopPlayingToPlaybackTarget();
    243 }
    244 
    245230String MediaSessionClient::mediaSessionTitle() const
    246231{
  • trunk/Source/WebCore/platform/audio/MediaSession.h

    r182240 r182486  
    118118    bool isHidden() const;
    119119
    120     bool canPlayToWirelessPlaybackTarget() const;
    121     void startPlayingToPlaybackTarget();
    122     void stopPlayingToPlaybackTarget();
     120    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
     121    virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
     122    virtual void startPlayingToPlaybackTarget() { }
     123    virtual void stopPlayingToPlaybackTarget() { }
    123124
    124125#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     
    170171    virtual void wirelessRoutesAvailableDidChange() { }
    171172    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
    172     virtual bool canPlayToWirelessPlaybackTarget() { return false; }
     173    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
     174    virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
    173175    virtual void startPlayingToPlaybackTarget() { }
    174176    virtual void stopPlayingToPlaybackTarget() { }
  • trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp

    r182240 r182486  
    4646MediaSessionManager::MediaSessionManager()
    4747    : m_systemSleepListener(SystemSleepListener::create(*this))
    48     , m_interrupted(false)
    4948{
    5049    resetRestrictions();
     
    168167}
    169168
     169bool MediaSessionManager::sessionShouldBeginPlayingToWirelessPlaybackTarget(MediaSession& session) const
     170{
     171    if (!session.canPlayToWirelessPlaybackTarget())
     172        return false;
     173
     174    if (session.isPlayingToWirelessPlaybackTarget())
     175        return false;
     176
     177    Vector<MediaSession*> sessions = m_sessions;
     178    for (auto* oneSession : sessions) {
     179        if (oneSession == &session)
     180            continue;
     181        if (oneSession->isPlayingToWirelessPlaybackTarget())
     182            return false;
     183    }
     184
     185    return true;
     186}
     187
    170188bool MediaSessionManager::sessionWillBeginPlayback(MediaSession& session)
    171189{
     
    187205        endInterruption(MediaSession::NoFlags);
    188206
    189     bool newSessionCanPlayToPlaybackTarget = session.canPlayToWirelessPlaybackTarget();
     207    bool shouldPlayToPlaybackTarget = sessionShouldBeginPlayingToWirelessPlaybackTarget(session);
    190208    Vector<MediaSession*> sessions = m_sessions;
    191209    for (auto* oneSession : sessions) {
    192210        if (oneSession == &session)
    193211            continue;
    194         if (newSessionCanPlayToPlaybackTarget)
     212        if (shouldPlayToPlaybackTarget)
    195213            oneSession->stopPlayingToPlaybackTarget();
    196214        if (oneSession->mediaType() == sessionType && restrictions & ConcurrentPlaybackNotPermitted)
    197215            oneSession->pauseSession();
    198216    }
    199     session.startPlayingToPlaybackTarget();
     217
     218    if (shouldPlayToPlaybackTarget)
     219        session.startPlayingToPlaybackTarget();
    200220
    201221    updateSessionState();
  • trunk/Source/WebCore/platform/audio/MediaSessionManager.h

    r182240 r182486  
    102102
    103103    void updateSessionState();
     104    bool sessionShouldBeginPlayingToWirelessPlaybackTarget(MediaSession&) const;
    104105
    105106    // RemoteCommandListenerClient
     
    118119
    119120    Vector<MediaSession*> m_sessions;
     121
    120122    std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
    121123    std::unique_ptr<SystemSleepListener> m_systemSleepListener;
    122124    RefPtr<AudioHardwareListener> m_audioHardwareListener;
    123     bool m_interrupted;
     125    bool m_interrupted { false };
    124126};
    125127
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r182240 r182486  
    879879}
    880880
     881bool MediaPlayer::isPlayingToWirelessPlaybackTarget() const
     882{
     883    return m_private->isPlayingToWirelessPlaybackTarget();
     884}
     885
    881886void MediaPlayer::setWirelessPlaybackTarget(const MediaPlaybackTarget& device)
    882887{
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.h

    r182240 r182486  
    481481
    482482    bool canPlayToWirelessPlaybackTarget() const;
     483    bool isPlayingToWirelessPlaybackTarget() const;
    483484    void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
    484485
  • trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h

    r182240 r182486  
    171171
    172172    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
     173    virtual bool isPlayingToWirelessPlaybackTarget() { return false; }
    173174    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
    174175
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h

    r182240 r182486  
    278278    virtual bool wirelessVideoPlaybackDisabled() const override;
    279279    virtual void setWirelessVideoPlaybackDisabled(bool) override;
     280    virtual bool canPlayToWirelessPlaybackTarget() const { return true; }
    280281    void updateDisableExternalPlayback();
    281     bool canPlayToWirelessPlaybackTarget() const { return true; }
    282282#endif
    283283
     
    286286    virtual void startPlayingToPlaybackTarget() override;
    287287    virtual void stopPlayingToPlaybackTarget() override;
     288    virtual bool isPlayingToWirelessPlaybackTarget();
    288289#endif
    289290
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

    r182292 r182486  
    27692769    m_outputContext = target.devicePickerContext();
    27702770    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p", this, m_outputContext.get());
     2771
     2772    if (!m_outputContext || !m_outputContext.get().deviceName)
     2773        stopPlayingToPlaybackTarget();
    27712774}
    27722775
     
    27822785    m_avPlayer.get().outputContext = m_outputContext.get();
    27832786    setDelayCallbacks(false);
     2787
     2788    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget(%p) - target = %p", this, m_avPlayer.get().outputContext);
    27842789}
    27852790
     
    27932798    // m_avPlayer.get().outputContext = nil;
    27942799    setDelayCallbacks(false);
    2795 }
    2796 #endif
     2800
     2801    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget(%p) - target = %p", this, m_avPlayer.get().outputContext);
     2802}
     2803
     2804bool MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget()
     2805{
     2806    if (!m_avPlayer)
     2807        return false;
     2808
     2809    if (!m_outputContext || !m_outputContext.get().deviceName)
     2810        return false;
     2811
     2812    return m_cachedRate;
     2813}
     2814#endif // !PLATFORM(IOS)
    27972815
    27982816void MediaPlayerPrivateAVFoundationObjC::updateDisableExternalPlayback()
     
    31113129    static NSArray* keys = [[NSArray alloc] initWithObjects:@"rate",
    31123130#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    3113                             @"externalPlaybackActive", @"outputContext", @"allowsExternalPlayback",
     3131                            @"externalPlaybackActive", @"allowsExternalPlayback",
    31143132#endif
    31153133                            nil];
     
    32323250            function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::rateDidChange, m_callback, [newValue doubleValue]);
    32333251#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    3234         else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"outputContext"] || [keyPath isEqualToString:@"allowsExternalPlayback"])
     3252        else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"allowsExternalPlayback"])
    32353253            function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
    32363254#endif
Note: See TracChangeset for help on using the changeset viewer.