[Mac] video playing to external device should not be interrupted
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Apr 2015 20:23:17 +0000 (20:23 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Apr 2015 20:23:17 +0000 (20:23 +0000)
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.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182486 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediacontrols/mediaControlsApple.js
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLMediaSession.cpp
Source/WebCore/html/HTMLMediaSession.h
Source/WebCore/platform/audio/MediaSession.cpp
Source/WebCore/platform/audio/MediaSession.h
Source/WebCore/platform/audio/MediaSessionManager.cpp
Source/WebCore/platform/audio/MediaSessionManager.h
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/MediaPlayerPrivate.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

index e0c072e..ff13c88 100644 (file)
@@ -1,3 +1,65 @@
+2015-04-07  Eric Carlson  <eric.carlson@apple.com>
+
+        [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.
+
 2015-04-07  Sam Weinig  <sam@webkit.org>
 
         Re-add JSReadableStream and JSReadableStreamReader the Xcode project to
index b4a4816..3694f69 100644 (file)
@@ -783,7 +783,7 @@ Controller.prototype = {
         var opacity = window.getComputedStyle(this.controls.panel).opacity;
         if (parseInt(opacity) > 0) {
             this.controls.panel.classList.remove(this.ClassNames.hidden);
-        } else {
+        } else if (!this.controlsAlwaysVisible()) {
             this.controls.panel.classList.add(this.ClassNames.hidden);
         }
     },
index de688ec..57f4c1a 100644 (file)
                078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetPicker.h; sourceTree = "<group>"; };
                078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaPlaybackTargetPickerMac.h; path = objc/MediaPlaybackTargetPickerMac.h; sourceTree = "<group>"; };
                078E43DC1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MediaPlaybackTargetPickerMac.mm; path = objc/MediaPlaybackTargetPickerMac.mm; sourceTree = "<group>"; };
-               079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaPlaybackTargetPickerClient.h; path = graphics/MediaPlaybackTargetPickerClient.h; sourceTree = "<group>"; };
+               079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetPickerClient.h; sourceTree = "<group>"; };
                0794178F166E855F009416C2 /* InbandTextTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InbandTextTrack.cpp; sourceTree = "<group>"; };
                07941790166E855F009416C2 /* InbandTextTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrack.h; sourceTree = "<group>"; };
                07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivate.h; sourceTree = "<group>"; };
                                6C568CAF19DAFEA000430CA2 /* MaskImageOperation.h */,
                                078E43D71ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.cpp */,
                                078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */,
+                               079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */,
                                E4B41E0C0CBF90BD00AF2ECE /* MediaPlayer.cpp */,
                                E4B41E0D0CBF90BD00AF2ECE /* MediaPlayer.h */,
                                079F5E4B0F3BEBEA005E0782 /* MediaPlayerPrivate.h */,
                BCF1A5BA097832090061A123 /* platform */ = {
                        isa = PBXGroup;
                        children = (
-                               079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */,
                                49E912A40EFAC8E6009D0CAF /* animation */,
                                FD31604012B026A300C1A359 /* audio */,
                                1AE42F670AA4B8CB00C8612D /* cf */,
index 4f59513..a42437b 100644 (file)
@@ -4885,7 +4885,7 @@ void HTMLMediaElement::setWirelessPlaybackTarget(const MediaPlaybackTarget& devi
         m_player->setWirelessPlaybackTarget(device);
 }
 
-bool HTMLMediaElement::canPlayToWirelessPlaybackTarget()
+bool HTMLMediaElement::canPlayToWirelessPlaybackTarget() const
 {
     bool canPlay = m_player && m_player->canPlayToWirelessPlaybackTarget();
 
@@ -4894,6 +4894,15 @@ bool HTMLMediaElement::canPlayToWirelessPlaybackTarget()
     return canPlay;
 }
 
+bool HTMLMediaElement::isPlayingToWirelessPlaybackTarget() const
+{
+    bool isPlaying = m_player && m_player->isPlayingToWirelessPlaybackTarget();
+
+    LOG(Media, "HTMLMediaElement::isPlayingToWirelessPlaybackTarget(%p) - returning %s", this, boolString(isPlaying));
+    
+    return isPlaying;
+}
+
 void HTMLMediaElement::startPlayingToPlaybackTarget()
 {
     if (m_player)
index 649b522..308a21c 100644 (file)
@@ -361,7 +361,8 @@ public:
     virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
 
     virtual void wirelessRoutesAvailableDidChange() override;
-    virtual bool canPlayToWirelessPlaybackTarget() override;
+    virtual bool canPlayToWirelessPlaybackTarget() const override;
+    virtual bool isPlayingToWirelessPlaybackTarget() const override;
     virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) override;
     virtual void startPlayingToPlaybackTarget() override;
     virtual void stopPlayingToPlaybackTarget() override;
index 02cdfb6..da80629 100644 (file)
@@ -317,6 +317,38 @@ bool HTMLMediaSession::requiresPlaybackTargetRouteMonitoring() const
 {
     return m_hasPlaybackTargetAvailabilityListeners;
 }
+
+bool HTMLMediaSession::canPlayToWirelessPlaybackTarget() const
+{
+    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
+        return false;
+
+    return client().canPlayToWirelessPlaybackTarget();
+}
+
+bool HTMLMediaSession::isPlayingToWirelessPlaybackTarget() const
+{
+    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
+        return false;
+
+    return client().isPlayingToWirelessPlaybackTarget();
+}
+
+void HTMLMediaSession::startPlayingToPlaybackTarget()
+{
+    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
+        return;
+
+    client().startPlayingToPlaybackTarget();
+}
+
+void HTMLMediaSession::stopPlayingToPlaybackTarget()
+{
+    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
+        return;
+
+    client().stopPlayingToPlaybackTarget();
+}    
 #endif
 
 MediaPlayer::Preload HTMLMediaSession::effectivePreloadForElement(const HTMLMediaElement& element) const
index 9cf5e1c..bdc46f2 100644 (file)
@@ -63,6 +63,11 @@ public:
     void setWirelessVideoPlaybackDisabled(const HTMLMediaElement&, bool);
 
     void setHasPlaybackTargetAvailabilityListeners(const HTMLMediaElement&, bool);
+
+    virtual bool canPlayToWirelessPlaybackTarget() const override;
+    virtual bool isPlayingToWirelessPlaybackTarget() const override;
+    virtual void startPlayingToPlaybackTarget() override;
+    virtual void stopPlayingToPlaybackTarget() override;
 #endif
 
     bool requiresFullscreenForVideoPlayback(const HTMLMediaElement&) const;
index e64b580..69b846f 100644 (file)
@@ -227,21 +227,6 @@ MediaSession::DisplayType MediaSession::displayType() const
     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();
index 9f59d04..bfe7efb 100644 (file)
@@ -117,9 +117,10 @@ public:
 
     bool isHidden() const;
 
-    bool canPlayToWirelessPlaybackTarget() const;
-    void startPlayingToPlaybackTarget();
-    void stopPlayingToPlaybackTarget();
+    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
+    virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
+    virtual void startPlayingToPlaybackTarget() { }
+    virtual void stopPlayingToPlaybackTarget() { }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     // MediaPlaybackTargetPickerClient
@@ -169,7 +170,8 @@ public:
 
     virtual void wirelessRoutesAvailableDidChange() { }
     virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
-    virtual bool canPlayToWirelessPlaybackTarget() { return false; }
+    virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
+    virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
     virtual void startPlayingToPlaybackTarget() { }
     virtual void stopPlayingToPlaybackTarget() { }
 
index 0d55ff7..cb3f31b 100644 (file)
@@ -45,7 +45,6 @@ MediaSessionManager& MediaSessionManager::sharedManager()
 
 MediaSessionManager::MediaSessionManager()
     : m_systemSleepListener(SystemSleepListener::create(*this))
-    , m_interrupted(false)
 {
     resetRestrictions();
 }
@@ -167,6 +166,25 @@ MediaSessionManager::SessionRestrictions MediaSessionManager::restrictions(Media
     return m_restrictions[type];
 }
 
+bool MediaSessionManager::sessionShouldBeginPlayingToWirelessPlaybackTarget(MediaSession& session) const
+{
+    if (!session.canPlayToWirelessPlaybackTarget())
+        return false;
+
+    if (session.isPlayingToWirelessPlaybackTarget())
+        return false;
+
+    Vector<MediaSession*> sessions = m_sessions;
+    for (auto* oneSession : sessions) {
+        if (oneSession == &session)
+            continue;
+        if (oneSession->isPlayingToWirelessPlaybackTarget())
+            return false;
+    }
+
+    return true;
+}
+
 bool MediaSessionManager::sessionWillBeginPlayback(MediaSession& session)
 {
     LOG(Media, "MediaSessionManager::sessionWillBeginPlayback - %p", &session);
@@ -186,17 +204,19 @@ bool MediaSessionManager::sessionWillBeginPlayback(MediaSession& session)
     if (m_interrupted)
         endInterruption(MediaSession::NoFlags);
 
-    bool newSessionCanPlayToPlaybackTarget = session.canPlayToWirelessPlaybackTarget();
+    bool shouldPlayToPlaybackTarget = sessionShouldBeginPlayingToWirelessPlaybackTarget(session);
     Vector<MediaSession*> sessions = m_sessions;
     for (auto* oneSession : sessions) {
         if (oneSession == &session)
             continue;
-        if (newSessionCanPlayToPlaybackTarget)
+        if (shouldPlayToPlaybackTarget)
             oneSession->stopPlayingToPlaybackTarget();
         if (oneSession->mediaType() == sessionType && restrictions & ConcurrentPlaybackNotPermitted)
             oneSession->pauseSession();
     }
-    session.startPlayingToPlaybackTarget();
+
+    if (shouldPlayToPlaybackTarget)
+        session.startPlayingToPlaybackTarget();
 
     updateSessionState();
     return true;
index 40a4cb7..74026dd 100644 (file)
@@ -101,6 +101,7 @@ private:
     friend class Internals;
 
     void updateSessionState();
+    bool sessionShouldBeginPlayingToWirelessPlaybackTarget(MediaSession&) const;
 
     // RemoteCommandListenerClient
     WEBCORE_EXPORT virtual void didReceiveRemoteControlCommand(MediaSession::RemoteControlCommandType) override;
@@ -117,10 +118,11 @@ private:
     SessionRestrictions m_restrictions[MediaSession::WebAudio + 1];
 
     Vector<MediaSession*> m_sessions;
+
     std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
     std::unique_ptr<SystemSleepListener> m_systemSleepListener;
     RefPtr<AudioHardwareListener> m_audioHardwareListener;
-    bool m_interrupted;
+    bool m_interrupted { false };
 };
 
 }
index 3a410fc..a52adc2 100644 (file)
@@ -878,6 +878,11 @@ bool MediaPlayer::canPlayToWirelessPlaybackTarget() const
     return m_private->canPlayToWirelessPlaybackTarget();
 }
 
+bool MediaPlayer::isPlayingToWirelessPlaybackTarget() const
+{
+    return m_private->isPlayingToWirelessPlaybackTarget();
+}
+
 void MediaPlayer::setWirelessPlaybackTarget(const MediaPlaybackTarget& device)
 {
     m_private->setWirelessPlaybackTarget(device);
index c7510fd..e0fb932 100644 (file)
@@ -480,6 +480,7 @@ public:
     void playbackTargetAvailabilityChanged();
 
     bool canPlayToWirelessPlaybackTarget() const;
+    bool isPlayingToWirelessPlaybackTarget() const;
     void setWirelessPlaybackTarget(const MediaPlaybackTarget&);
 
     void startPlayingToPlaybackTarget();
index 25ef250..0bd1672 100644 (file)
@@ -170,6 +170,7 @@ public:
     virtual void setWirelessVideoPlaybackDisabled(bool) { }
 
     virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
+    virtual bool isPlayingToWirelessPlaybackTarget() { return false; }
     virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&) { }
 
     virtual void startPlayingToPlaybackTarget() { }
index 007e311..08e47a6 100644 (file)
@@ -277,14 +277,15 @@ private:
     virtual MediaPlayer::WirelessPlaybackTargetType wirelessPlaybackTargetType() const override;
     virtual bool wirelessVideoPlaybackDisabled() const override;
     virtual void setWirelessVideoPlaybackDisabled(bool) override;
+    virtual bool canPlayToWirelessPlaybackTarget() const { return true; }
     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;
+    virtual bool isPlayingToWirelessPlaybackTarget();
 #endif
 
     virtual double maxFastForwardRate() const override { return m_cachedCanPlayFastForward ? std::numeric_limits<double>::infinity() : 2.0; }
index e4addcf..ccec52c 100644 (file)
@@ -2768,6 +2768,9 @@ void MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(const MediaPl
 {
     m_outputContext = target.devicePickerContext();
     LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p", this, m_outputContext.get());
+
+    if (!m_outputContext || !m_outputContext.get().deviceName)
+        stopPlayingToPlaybackTarget();
 }
 
 void MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget()
@@ -2781,6 +2784,8 @@ void MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget()
     setDelayCallbacks(true);
     m_avPlayer.get().outputContext = m_outputContext.get();
     setDelayCallbacks(false);
+
+    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget(%p) - target = %p", this, m_avPlayer.get().outputContext);
 }
 
 void MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget()
@@ -2792,8 +2797,21 @@ void MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget()
     // FIXME: uncomment the following line once rdar://20335217 has been fixed.
     // m_avPlayer.get().outputContext = nil;
     setDelayCallbacks(false);
+
+    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget(%p) - target = %p", this, m_avPlayer.get().outputContext);
 }
-#endif
+
+bool MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget()
+{
+    if (!m_avPlayer)
+        return false;
+
+    if (!m_outputContext || !m_outputContext.get().deviceName)
+        return false;
+
+    return m_cachedRate;
+}
+#endif // !PLATFORM(IOS)
 
 void MediaPlayerPrivateAVFoundationObjC::updateDisableExternalPlayback()
 {
@@ -3110,7 +3128,7 @@ NSArray* playerKVOProperties()
 {
     static NSArray* keys = [[NSArray alloc] initWithObjects:@"rate",
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-                            @"externalPlaybackActive", @"outputContext", @"allowsExternalPlayback",
+                            @"externalPlaybackActive", @"allowsExternalPlayback",
 #endif
                             nil];
     return keys;
@@ -3231,7 +3249,7 @@ NSArray* playerKVOProperties()
         if ([keyPath isEqualToString:@"rate"])
             function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::rateDidChange, m_callback, [newValue doubleValue]);
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-        else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"outputContext"] || [keyPath isEqualToString:@"allowsExternalPlayback"])
+        else if ([keyPath isEqualToString:@"externalPlaybackActive"] || [keyPath isEqualToString:@"allowsExternalPlayback"])
             function = WTF::bind(&MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
 #endif
     }