[Mac] Refine media playback target client configuration
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 May 2015 16:41:48 +0000 (16:41 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 May 2015 16:41:48 +0000 (16:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144892

Reviewed by Brent Fulgham.

Client and target picker state changes fequently happen several times in quick succession, so
don't react to immediately so we can batch callbacks to the web process.
* Modules/mediasession/WebMediaSessionManager.cpp:
(WebCore::ClientState::ClientState): Store the client as a reference rather than a pointer
because it can never be NULL.
(WebCore::ClientState::operator == ): New.
(WebCore::WebMediaSessionManager::addPlaybackTargetPickerClient): Schedule the initial client
configuration and a target configuration check.
(WebCore::WebMediaSessionManager::removePlaybackTargetPickerClient): Schedule a target monitoring
update, and a target configuration check.
(WebCore::WebMediaSessionManager::removeAllPlaybackTargetPickerClients): Ditto.
(WebCore::WebMediaSessionManager::showPlaybackTargetPicker): Schedule a target monitoring update.
(WebCore::WebMediaSessionManager::clientStateDidChange): If the client whose state has changed
can play to a target, tell it to start using the target even if it isn't playing as long as
no other client is actively using a target.
(WebCore::WebMediaSessionManager::setPlaybackTarget): Configure clients after a pause.
(WebCore::WebMediaSessionManager::configureNewClients): New, do new client configuration.
(WebCore::WebMediaSessionManager::configurePlaybackTargetClients): New, configure target clients.
(WebCore::WebMediaSessionManager::scheduleDelayedTask): Schedule the timer.
(WebCore::WebMediaSessionManager::taskTimerFired): Execute delayed tasks.
(WebCore::WebMediaSessionManager::find):
* Modules/mediasession/WebMediaSessionManager.h:

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::setMuted): Call updateMediaState.
(WebCore::HTMLMediaElement::setPlaying): Ditto.
(WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged): Ditto.
(WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): Expand logging.
(WebCore::HTMLMediaElement::updateMediaState): New, don't broadcast a media state change
unless something actually changed.
* html/HTMLMediaElement.h:

* html/HTMLMediaSession.cpp:
(WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange): Update logging.
(WebCore::HTMLMediaSession::setShouldPlayToPlaybackTarget): Ditto.
(WebCore::HTMLMediaSession::mediaEngineUpdated): Cleanup.

* platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm:
(WebCore::MediaPlaybackTargetPickerMac::showPlaybackTargetPicker): Remove the call to
deprecated API and the "-Wdeprecated-declarations".

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

Source/WebCore/ChangeLog
Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp
Source/WebCore/Modules/mediasession/WebMediaSessionManager.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLMediaSession.cpp
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm

index 184d616..c68721d 100644 (file)
@@ -1,3 +1,51 @@
+2015-05-12  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] Refine media playback target client configuration
+        https://bugs.webkit.org/show_bug.cgi?id=144892
+
+        Reviewed by Brent Fulgham.
+
+        Client and target picker state changes fequently happen several times in quick succession, so
+        don't react to immediately so we can batch callbacks to the web process. 
+        * Modules/mediasession/WebMediaSessionManager.cpp:
+        (WebCore::ClientState::ClientState): Store the client as a reference rather than a pointer
+        because it can never be NULL.
+        (WebCore::ClientState::operator == ): New.
+        (WebCore::WebMediaSessionManager::addPlaybackTargetPickerClient): Schedule the initial client 
+        configuration and a target configuration check.
+        (WebCore::WebMediaSessionManager::removePlaybackTargetPickerClient): Schedule a target monitoring
+        update, and a target configuration check.
+        (WebCore::WebMediaSessionManager::removeAllPlaybackTargetPickerClients): Ditto.
+        (WebCore::WebMediaSessionManager::showPlaybackTargetPicker): Schedule a target monitoring update.
+        (WebCore::WebMediaSessionManager::clientStateDidChange): If the client whose state has changed
+        can play to a target, tell it to start using the target even if it isn't playing as long as
+        no other client is actively using a target.
+        (WebCore::WebMediaSessionManager::setPlaybackTarget): Configure clients after a pause.
+        (WebCore::WebMediaSessionManager::configureNewClients): New, do new client configuration.
+        (WebCore::WebMediaSessionManager::configurePlaybackTargetClients): New, configure target clients.
+        (WebCore::WebMediaSessionManager::scheduleDelayedTask): Schedule the timer.
+        (WebCore::WebMediaSessionManager::taskTimerFired): Execute delayed tasks.
+        (WebCore::WebMediaSessionManager::find): 
+        * Modules/mediasession/WebMediaSessionManager.h:
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::setMuted): Call updateMediaState.
+        (WebCore::HTMLMediaElement::setPlaying): Ditto.
+        (WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged): Ditto.
+        (WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): Expand logging.
+        (WebCore::HTMLMediaElement::updateMediaState): New, don't broadcast a media state change
+        unless something actually changed.
+        * html/HTMLMediaElement.h:
+
+        * html/HTMLMediaSession.cpp:
+        (WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange): Update logging.
+        (WebCore::HTMLMediaSession::setShouldPlayToPlaybackTarget): Ditto.
+        (WebCore::HTMLMediaSession::mediaEngineUpdated): Cleanup.
+
+        * platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm:
+        (WebCore::MediaPlaybackTargetPickerMac::showPlaybackTargetPicker): Remove the call to
+        deprecated API and the "-Wdeprecated-declarations".
+
 2015-05-12  Joanmarie Diggs  <jdiggs@igalia.com>
 
         AX: [GTK] Defer to WebCore Accessibility for table exposure
index 3e93223..ef34dcc 100644 (file)
 
 namespace WebCore {
 
+static double taskDelayInterval = 1.0 / 10.0;
+
 struct ClientState {
     explicit ClientState(WebMediaSessionManagerClient& client, uint64_t contextId)
-        : client(&client)
+        : client(client)
         , contextId(contextId)
     {
     }
 
-    WebMediaSessionManagerClient* client { nullptr };
+    bool operator == (ClientState const& other) const
+    {
+        return contextId == other.contextId && &client == &other.client;
+    }
+
+    WebMediaSessionManagerClient& client;
     uint64_t contextId { 0 };
     WebCore::MediaProducer::MediaStateFlags flags { WebCore::MediaProducer::IsNotPlaying };
     bool requestedPicker { false };
+    bool configurationRequired { true };
 };
 
 static bool flagsAreSet(MediaProducer::MediaStateFlags value, unsigned flags)
@@ -70,24 +78,8 @@ uint64_t WebMediaSessionManager::addPlaybackTargetPickerClient(WebMediaSessionMa
 
     m_clientState.append(std::make_unique<ClientState>(client, contextId));
 
-    if (m_externalOutputDeviceAvailable || m_playbackTarget) {
-
-        TaskCallback callback = std::make_tuple(&client, contextId, [this](ClientState& state) {
-
-            if (m_externalOutputDeviceAvailable)
-                state.client->externalOutputDeviceAvailableDidChange(state.contextId, true);
-
-            if (m_playbackTarget) {
-                state.client->setPlaybackTarget(state.contextId, *m_playbackTarget.copyRef());
-
-                if (m_clientState.size() == 1 && m_playbackTarget->hasActiveRoute())
-                    state.client->setShouldPlayToPlaybackTarget(state.contextId, true);
-            }
-        });
-
-        m_taskQueue.append(callback);
-        m_taskTimer.startOneShot(0);
-    }
+    if (m_externalOutputDeviceAvailable || m_playbackTarget)
+        scheduleDelayedTask(InitialConfigurationTask | TargetClientsConfigurationTask);
 
     return contextId;
 }
@@ -100,18 +92,16 @@ void WebMediaSessionManager::removePlaybackTargetPickerClient(WebMediaSessionMan
         return;
 
     m_clientState.remove(index);
-    configurePlaybackTargetMonitoring();
-
-    if (m_playbackTarget && m_clientState.size() == 1 && m_playbackTarget->hasActiveRoute())
-        m_clientState[0]->client->setShouldPlayToPlaybackTarget(m_clientState[0]->contextId, true);
+    scheduleDelayedTask(TargetMonitoringConfigurationTask | TargetClientsConfigurationTask);
 }
 
 void WebMediaSessionManager::removeAllPlaybackTargetPickerClients(WebMediaSessionManagerClient& client)
 {
     for (size_t i = m_clientState.size(); i > 0; --i) {
-        if (m_clientState[i - 1]->client == &client)
+        if (&m_clientState[i - 1]->client == &client)
             m_clientState.remove(i - 1);
     }
+    scheduleDelayedTask(TargetMonitoringConfigurationTask | TargetClientsConfigurationTask);
 }
 
 void WebMediaSessionManager::showPlaybackTargetPicker(WebMediaSessionManagerClient& client, uint64_t contextId, const IntRect& rect, bool)
@@ -121,8 +111,9 @@ void WebMediaSessionManager::showPlaybackTargetPicker(WebMediaSessionManagerClie
     if (index == notFound)
         return;
 
+    auto& clientRequestingPicker = m_clientState[index];
     for (auto& state : m_clientState)
-        state->requestedPicker = (state->contextId == contextId && state->client == &client);
+        state->requestedPicker = state == clientRequestingPicker;
 
     bool hasActiveRoute = flagsAreSet(m_clientState[index]->flags, MediaProducer::IsPlayingToExternalDevice);
     targetPicker().showPlaybackTargetPicker(FloatRect(rect), hasActiveRoute);
@@ -142,30 +133,35 @@ void WebMediaSessionManager::clientStateDidChange(WebMediaSessionManagerClient&
 
     changedClientState->flags = newFlags;
     if (!flagsAreSet(oldFlags, MediaProducer::RequiresPlaybackTargetMonitoring) && flagsAreSet(newFlags, MediaProducer::RequiresPlaybackTargetMonitoring))
-        configurePlaybackTargetMonitoring();
+        scheduleDelayedTask(TargetMonitoringConfigurationTask);
 
-    if (!flagsAreSet(newFlags, MediaProducer::IsPlayingVideo) || !flagsAreSet(newFlags, MediaProducer::ExternalDeviceAutoPlayCandidate))
+    if (!flagsAreSet(newFlags, MediaProducer::ExternalDeviceAutoPlayCandidate))
         return;
 
     if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
         return;
 
     // Do not interrupt another element already playing to a device.
+    bool anotherClientHasActiveTarget = false;
     for (auto& state : m_clientState) {
-        if (state->contextId == contextId && state->client == &client)
-            continue;
-
-        if (flagsAreSet(state->flags, MediaProducer::IsPlayingVideo) && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
-            return;
+        if (flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice)) {
+            if (flagsAreSet(state->flags, MediaProducer::IsPlayingVideo))
+                return;
+            anotherClientHasActiveTarget = true;
+        }
     }
 
+    // Do not take the target if another client has it and the client reporting a state change is not playing.
+    if (anotherClientHasActiveTarget && !flagsAreSet(newFlags, MediaProducer::IsPlayingVideo))
+        return;
+
     for (auto& state : m_clientState) {
-        if (state->contextId == contextId && state->client == &client)
+        if (state == changedClientState)
             continue;
-        state->client->setShouldPlayToPlaybackTarget(state->contextId, false);
+        state->client.setShouldPlayToPlaybackTarget(state->contextId, false);
     }
 
-    changedClientState->client->setShouldPlayToPlaybackTarget(changedClientState->contextId, true);
+    changedClientState->client.setShouldPlayToPlaybackTarget(changedClientState->contextId, true);
 
     if (index && m_clientState.size() > 1)
         std::swap(m_clientState.at(index), m_clientState.at(0));
@@ -174,32 +170,70 @@ void WebMediaSessionManager::clientStateDidChange(WebMediaSessionManagerClient&
 void WebMediaSessionManager::setPlaybackTarget(Ref<MediaPlaybackTarget>&& target)
 {
     m_playbackTarget = WTF::move(target);
+    scheduleDelayedTask(TargetClientsConfigurationTask);
+}
 
-    size_t indexThatRequestedPicker = notFound;
-    for (size_t i = 0; i < m_clientState.size(); ++i) {
-        auto& state = m_clientState[i];
-        state->client->setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());
-        if (state->requestedPicker) {
-            indexThatRequestedPicker = i;
+void WebMediaSessionManager::externalOutputDeviceAvailableDidChange(bool available)
+{
+    m_externalOutputDeviceAvailable = available;
+    for (auto& state : m_clientState)
+        state->client.externalOutputDeviceAvailableDidChange(state->contextId, available);
+}
+
+void WebMediaSessionManager::configureNewClients()
+{
+    for (auto& state : m_clientState) {
+        if (!state->configurationRequired)
             continue;
-        }
-        state->client->setShouldPlayToPlaybackTarget(state->contextId, false);
-        state->requestedPicker = false;
-    }
 
-    if (indexThatRequestedPicker == notFound)
-        return;
+        state->configurationRequired = false;
+        if (m_externalOutputDeviceAvailable)
+            state->client.externalOutputDeviceAvailableDidChange(state->contextId, true);
 
-    auto& state = m_clientState[indexThatRequestedPicker];
-    state->client->setShouldPlayToPlaybackTarget(state->contextId, m_playbackTarget && m_playbackTarget->hasActiveRoute());
-    state->requestedPicker = false;
+        if (m_playbackTarget)
+            state->client.setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());
+    }
 }
 
-void WebMediaSessionManager::externalOutputDeviceAvailableDidChange(bool available)
+void WebMediaSessionManager::configurePlaybackTargetClients()
 {
-    m_externalOutputDeviceAvailable = available;
-    for (auto& state : m_clientState)
-        state->client->externalOutputDeviceAvailableDidChange(state->contextId, available);
+    size_t indexOfClientThatRequestedPicker = notFound;
+    size_t indexOfAutoPlayCandidate = notFound;
+    size_t indexOfClientWillPlayToTarget = notFound;
+    bool haveActiveRoute = m_playbackTarget && m_playbackTarget->hasActiveRoute();
+
+    for (size_t i = 0; i < m_clientState.size(); ++i) {
+        auto& state = m_clientState[i];
+
+        if (indexOfClientThatRequestedPicker == notFound && state->requestedPicker)
+            indexOfClientThatRequestedPicker = i;
+
+        if (indexOfClientWillPlayToTarget == notFound && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
+            indexOfClientWillPlayToTarget = i;
+
+        if (indexOfAutoPlayCandidate == notFound && flagsAreSet(state->flags, MediaProducer::ExternalDeviceAutoPlayCandidate) && !flagsAreSet(state->flags, MediaProducer::IsPlayingVideo))
+            indexOfAutoPlayCandidate = i;
+    }
+
+    if (indexOfClientThatRequestedPicker != notFound)
+        indexOfClientWillPlayToTarget = indexOfClientThatRequestedPicker;
+    if (indexOfClientWillPlayToTarget == notFound && haveActiveRoute && indexOfAutoPlayCandidate != notFound)
+        indexOfClientWillPlayToTarget = indexOfAutoPlayCandidate;
+
+    for (size_t i = 0; i < m_clientState.size(); ++i) {
+        auto& state = m_clientState[i];
+
+        if (m_playbackTarget)
+            state->client.setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());
+
+        if (i != indexOfClientWillPlayToTarget)
+            state->client.setShouldPlayToPlaybackTarget(state->contextId, false);
+        else if (!flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
+            state->client.setShouldPlayToPlaybackTarget(state->contextId, haveActiveRoute);
+
+        state->configurationRequired = false;
+        state->requestedPicker = false;
+    }
 }
 
 void WebMediaSessionManager::configurePlaybackTargetMonitoring()
@@ -218,26 +252,28 @@ void WebMediaSessionManager::configurePlaybackTargetMonitoring()
         targetPicker().stopMonitoringPlaybackTargets();
 }
 
-void WebMediaSessionManager::taskTimerFired()
+void WebMediaSessionManager::scheduleDelayedTask(ConfigurationTasks tasks)
 {
-    auto taskQueue = WTF::move(m_taskQueue);
-    if (taskQueue.isEmpty())
-        return;
-
-    for (auto& task : taskQueue) {
-        size_t index = find(std::get<0>(task), std::get<1>(task));
+    m_taskFlags |= tasks;
+    m_taskTimer.startOneShot(taskDelayInterval);
+}
 
-        if (index == notFound)
-            continue;
+void WebMediaSessionManager::taskTimerFired()
+{
+    if (m_taskFlags & InitialConfigurationTask)
+        configureNewClients();
+    if (m_taskFlags & TargetClientsConfigurationTask)
+        configurePlaybackTargetClients();
+    if (m_taskFlags & TargetMonitoringConfigurationTask)
+        configurePlaybackTargetMonitoring();
 
-        std::get<2>(task)(*m_clientState[index]);
-    }
+    m_taskFlags = NoTask;
 }
 
 size_t WebMediaSessionManager::find(WebMediaSessionManagerClient* client, uint64_t contextId)
 {
     for (size_t i = 0; i < m_clientState.size(); ++i) {
-        if (m_clientState[i]->contextId == contextId && m_clientState[i]->client == client)
+        if (m_clientState[i]->contextId == contextId && &m_clientState[i]->client == client)
             return i;
     }
 
index 16b9aac..8fe8152 100644 (file)
@@ -64,15 +64,25 @@ private:
     virtual void externalOutputDeviceAvailableDidChange(bool) override;
 
     size_t find(WebMediaSessionManagerClient*, uint64_t);
+    void configurePlaybackTargetClients();
+    void configureNewClients();
     void configurePlaybackTargetMonitoring();
-    void taskTimerFired();
 
-    typedef std::tuple<WebMediaSessionManagerClient*, uint64_t, std::function<void(ClientState&)>> TaskCallback;
-    Vector<TaskCallback> m_taskQueue;
+    enum ConfigurationTaskFlags {
+        NoTask = 0,
+        InitialConfigurationTask = 1 << 0,
+        TargetClientsConfigurationTask = 1 << 1,
+        TargetMonitoringConfigurationTask = 1 << 2,
+    };
+    typedef unsigned ConfigurationTasks;
+
+    void scheduleDelayedTask(ConfigurationTasks);
+    void taskTimerFired();
     RunLoop::Timer<WebMediaSessionManager> m_taskTimer;
 
     Vector<std::unique_ptr<ClientState>> m_clientState;
     RefPtr<MediaPlaybackTarget> m_playbackTarget;
+    ConfigurationTasks m_taskFlags { NoTask };
     bool m_externalOutputDeviceAvailable { false };
 };
 
index 99419a5..a11ad59 100644 (file)
@@ -3034,7 +3034,7 @@ void HTMLMediaElement::setMuted(bool muted)
         document().updateIsPlayingMedia();
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-        m_mediaSession->mediaStateDidChange(*this, mediaState());
+        updateMediaState();
 #endif
     }
 #endif
@@ -4632,7 +4632,7 @@ void HTMLMediaElement::setPlaying(bool playing)
     document().updateIsPlayingMedia();
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    m_mediaSession->mediaStateDidChange(*this, mediaState());
+    updateMediaState();
 #endif
 }
 
@@ -4895,7 +4895,7 @@ void HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPl
 
     configureMediaControls();
     scheduleEvent(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent);
-    m_mediaSession->mediaStateDidChange(*this, mediaState());
+    updateMediaState();
 }
 
 bool HTMLMediaElement::dispatchEvent(PassRefPtr<Event> prpEvent)
@@ -4946,8 +4946,9 @@ bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventL
 
 void HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent()
 {
-    LOG(Media, "HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent(%p)", this);
-    RefPtr<Event> event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, m_mediaSession->hasWirelessPlaybackTargets(*this));
+    bool hasTargets = m_mediaSession->hasWirelessPlaybackTargets(*this);
+    LOG(Media, "HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent(%p) - hasTargets = %s", this, boolString(hasTargets));
+    RefPtr<Event> event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, hasTargets);
     event->setTarget(this);
     m_asyncEventQueue.enqueueEvent(event.release());
 }
@@ -6218,6 +6219,18 @@ bool HTMLMediaElement::overrideBackgroundPlaybackRestriction() const
     return false;
 }
 
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+void HTMLMediaElement::updateMediaState()
+{
+    MediaProducer::MediaStateFlags state = mediaState();
+    if (m_mediaState == state)
+        return;
+
+    m_mediaState = state;
+    m_mediaSession->mediaStateDidChange(*this, m_mediaState);
+}
+#endif
+
 MediaProducer::MediaStateFlags HTMLMediaElement::mediaState() const
 {
 
index ff9944c..3b661ab 100644 (file)
@@ -740,6 +740,7 @@ private:
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     virtual void documentWillSuspendForPageCache() override final;
     virtual void documentDidResumeFromPageCache() override final;
+    void updateMediaState();
 #endif
 
     Timer m_pendingActionTimer;
@@ -931,6 +932,7 @@ private:
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
     bool m_hasPlaybackTargetAvailabilityListeners { false };
 #endif
 };
index 824be91..3c8d6ce 100644 (file)
@@ -305,11 +305,10 @@ void HTMLMediaSession::externalOutputDeviceAvailableDidChange(bool hasTargets)
     if (m_hasPlaybackTargets == hasTargets)
         return;
 
-    LOG(Media, "HTMLMediaSession::externalOutputDeviceAvailableDidChange - hasTargets %s", hasTargets ? "TRUE" : "FALSE");
+    LOG(Media, "HTMLMediaSession::externalOutputDeviceAvailableDidChange(%p) - hasTargets %s", this, hasTargets ? "TRUE" : "FALSE");
 
     m_hasPlaybackTargets = hasTargets;
-    if (!m_targetAvailabilityChangedTimer.isActive())
-        m_targetAvailabilityChangedTimer.startOneShot(0);
+    m_targetAvailabilityChangedTimer.startOneShot(0);
 }
 
 bool HTMLMediaSession::canPlayToWirelessPlaybackTarget() const
@@ -330,6 +329,7 @@ bool HTMLMediaSession::isPlayingToWirelessPlaybackTarget() const
 
 void HTMLMediaSession::setShouldPlayToPlaybackTarget(bool shouldPlay)
 {
+    LOG(Media, "HTMLMediaSession::setShouldPlayToPlaybackTarget - shouldPlay %s", shouldPlay ? "TRUE" : "FALSE");
     m_shouldPlayToPlaybackTarget = shouldPlay;
     client().setShouldPlayToPlaybackTarget(shouldPlay);
 }
@@ -386,7 +386,7 @@ void HTMLMediaSession::mediaEngineUpdated(const HTMLMediaElement& element)
     if (m_playbackTarget)
         client().setWirelessPlaybackTarget(*m_playbackTarget.copyRef());
     if (m_shouldPlayToPlaybackTarget)
-        client().setShouldPlayToPlaybackTarget(m_shouldPlayToPlaybackTarget);
+        client().setShouldPlayToPlaybackTarget(true);
 #else
     UNUSED_PARAM(element);
 #endif
index 0a8a3c9..d29ae97 100644 (file)
@@ -130,23 +130,22 @@ AVOutputDeviceMenuControllerType *MediaPlaybackTargetPickerMac::devicePicker()
     return m_outputDeviceMenuController.get();
 }
 
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 void MediaPlaybackTargetPickerMac::showPlaybackTargetPicker(const FloatRect& location, bool checkActiveRoute)
 {
     if (!m_client || m_showingMenu)
         return;
 
-    m_showingMenu = true;
     AVOutputDeviceMenuControllerType *picker = devicePicker();
-    if ([picker respondsToSelector:@selector(showMenuForRect:appearanceName:allowReselectionOfSelectedOutputDevice:)]) {
-        if ([picker showMenuForRect:location appearanceName:NSAppearanceNameVibrantLight allowReselectionOfSelectedOutputDevice:!checkActiveRoute])
+    if (![picker respondsToSelector:@selector(showMenuForRect:appearanceName:allowReselectionOfSelectedOutputDevice:)])
+        return;
+
+    m_showingMenu = true;
+    if ([picker showMenuForRect:location appearanceName:NSAppearanceNameVibrantLight allowReselectionOfSelectedOutputDevice:!checkActiveRoute]) {
+        if (!checkActiveRoute)
             currentDeviceDidChange();
-    } else
-        [picker showMenuForRect:location appearanceName:NSAppearanceNameVibrantLight];
+    }
     m_showingMenu = false;
 }
-#pragma clang diagnostic pop
 
 void MediaPlaybackTargetPickerMac::addPendingAction(PendingActionFlags action)
 {