Changeset 184204 in webkit


Ignore:
Timestamp:
May 12, 2015, 9:41:48 AM (10 years ago)
Author:
eric.carlson@apple.com
Message:

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

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/Source/WebCore/ChangeLog

    r184199 r184204  
     12015-05-12  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [Mac] Refine media playback target client configuration
     4        https://bugs.webkit.org/show_bug.cgi?id=144892
     5
     6        Reviewed by Brent Fulgham.
     7
     8        Client and target picker state changes fequently happen several times in quick succession, so
     9        don't react to immediately so we can batch callbacks to the web process.
     10        * Modules/mediasession/WebMediaSessionManager.cpp:
     11        (WebCore::ClientState::ClientState): Store the client as a reference rather than a pointer
     12        because it can never be NULL.
     13        (WebCore::ClientState::operator == ): New.
     14        (WebCore::WebMediaSessionManager::addPlaybackTargetPickerClient): Schedule the initial client
     15        configuration and a target configuration check.
     16        (WebCore::WebMediaSessionManager::removePlaybackTargetPickerClient): Schedule a target monitoring
     17        update, and a target configuration check.
     18        (WebCore::WebMediaSessionManager::removeAllPlaybackTargetPickerClients): Ditto.
     19        (WebCore::WebMediaSessionManager::showPlaybackTargetPicker): Schedule a target monitoring update.
     20        (WebCore::WebMediaSessionManager::clientStateDidChange): If the client whose state has changed
     21        can play to a target, tell it to start using the target even if it isn't playing as long as
     22        no other client is actively using a target.
     23        (WebCore::WebMediaSessionManager::setPlaybackTarget): Configure clients after a pause.
     24        (WebCore::WebMediaSessionManager::configureNewClients): New, do new client configuration.
     25        (WebCore::WebMediaSessionManager::configurePlaybackTargetClients): New, configure target clients.
     26        (WebCore::WebMediaSessionManager::scheduleDelayedTask): Schedule the timer.
     27        (WebCore::WebMediaSessionManager::taskTimerFired): Execute delayed tasks.
     28        (WebCore::WebMediaSessionManager::find):
     29        * Modules/mediasession/WebMediaSessionManager.h:
     30
     31        * html/HTMLMediaElement.cpp:
     32        (WebCore::HTMLMediaElement::setMuted): Call updateMediaState.
     33        (WebCore::HTMLMediaElement::setPlaying): Ditto.
     34        (WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged): Ditto.
     35        (WebCore::HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent): Expand logging.
     36        (WebCore::HTMLMediaElement::updateMediaState): New, don't broadcast a media state change
     37        unless something actually changed.
     38        * html/HTMLMediaElement.h:
     39
     40        * html/HTMLMediaSession.cpp:
     41        (WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange): Update logging.
     42        (WebCore::HTMLMediaSession::setShouldPlayToPlaybackTarget): Ditto.
     43        (WebCore::HTMLMediaSession::mediaEngineUpdated): Cleanup.
     44
     45        * platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm:
     46        (WebCore::MediaPlaybackTargetPickerMac::showPlaybackTargetPicker): Remove the call to
     47        deprecated API and the "-Wdeprecated-declarations".
     48
    1492015-05-12  Joanmarie Diggs  <jdiggs@igalia.com>
    250
  • TabularUnified trunk/Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp

    r183613 r184204  
    3535namespace WebCore {
    3636
     37static double taskDelayInterval = 1.0 / 10.0;
     38
    3739struct ClientState {
    3840    explicit ClientState(WebMediaSessionManagerClient& client, uint64_t contextId)
    39         : client(&client)
     41        : client(client)
    4042        , contextId(contextId)
    4143    {
    4244    }
    4345
    44     WebMediaSessionManagerClient* client { nullptr };
     46    bool operator == (ClientState const& other) const
     47    {
     48        return contextId == other.contextId && &client == &other.client;
     49    }
     50
     51    WebMediaSessionManagerClient& client;
    4552    uint64_t contextId { 0 };
    4653    WebCore::MediaProducer::MediaStateFlags flags { WebCore::MediaProducer::IsNotPlaying };
    4754    bool requestedPicker { false };
     55    bool configurationRequired { true };
    4856};
    4957
     
    7179    m_clientState.append(std::make_unique<ClientState>(client, contextId));
    7280
    73     if (m_externalOutputDeviceAvailable || m_playbackTarget) {
    74 
    75         TaskCallback callback = std::make_tuple(&client, contextId, [this](ClientState& state) {
    76 
    77             if (m_externalOutputDeviceAvailable)
    78                 state.client->externalOutputDeviceAvailableDidChange(state.contextId, true);
    79 
    80             if (m_playbackTarget) {
    81                 state.client->setPlaybackTarget(state.contextId, *m_playbackTarget.copyRef());
    82 
    83                 if (m_clientState.size() == 1 && m_playbackTarget->hasActiveRoute())
    84                     state.client->setShouldPlayToPlaybackTarget(state.contextId, true);
    85             }
    86         });
    87 
    88         m_taskQueue.append(callback);
    89         m_taskTimer.startOneShot(0);
    90     }
     81    if (m_externalOutputDeviceAvailable || m_playbackTarget)
     82        scheduleDelayedTask(InitialConfigurationTask | TargetClientsConfigurationTask);
    9183
    9284    return contextId;
     
    10193
    10294    m_clientState.remove(index);
    103     configurePlaybackTargetMonitoring();
    104 
    105     if (m_playbackTarget && m_clientState.size() == 1 && m_playbackTarget->hasActiveRoute())
    106         m_clientState[0]->client->setShouldPlayToPlaybackTarget(m_clientState[0]->contextId, true);
     95    scheduleDelayedTask(TargetMonitoringConfigurationTask | TargetClientsConfigurationTask);
    10796}
    10897
     
    11099{
    111100    for (size_t i = m_clientState.size(); i > 0; --i) {
    112         if (m_clientState[i - 1]->client == &client)
     101        if (&m_clientState[i - 1]->client == &client)
    113102            m_clientState.remove(i - 1);
    114103    }
     104    scheduleDelayedTask(TargetMonitoringConfigurationTask | TargetClientsConfigurationTask);
    115105}
    116106
     
    122112        return;
    123113
     114    auto& clientRequestingPicker = m_clientState[index];
    124115    for (auto& state : m_clientState)
    125         state->requestedPicker = (state->contextId == contextId && state->client == &client);
     116        state->requestedPicker = state == clientRequestingPicker;
    126117
    127118    bool hasActiveRoute = flagsAreSet(m_clientState[index]->flags, MediaProducer::IsPlayingToExternalDevice);
     
    143134    changedClientState->flags = newFlags;
    144135    if (!flagsAreSet(oldFlags, MediaProducer::RequiresPlaybackTargetMonitoring) && flagsAreSet(newFlags, MediaProducer::RequiresPlaybackTargetMonitoring))
    145         configurePlaybackTargetMonitoring();
    146 
    147     if (!flagsAreSet(newFlags, MediaProducer::IsPlayingVideo) || !flagsAreSet(newFlags, MediaProducer::ExternalDeviceAutoPlayCandidate))
     136        scheduleDelayedTask(TargetMonitoringConfigurationTask);
     137
     138    if (!flagsAreSet(newFlags, MediaProducer::ExternalDeviceAutoPlayCandidate))
    148139        return;
    149140
     
    152143
    153144    // Do not interrupt another element already playing to a device.
    154     for (auto& state : m_clientState) {
    155         if (state->contextId == contextId && state->client == &client)
     145    bool anotherClientHasActiveTarget = false;
     146    for (auto& state : m_clientState) {
     147        if (flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice)) {
     148            if (flagsAreSet(state->flags, MediaProducer::IsPlayingVideo))
     149                return;
     150            anotherClientHasActiveTarget = true;
     151        }
     152    }
     153
     154    // Do not take the target if another client has it and the client reporting a state change is not playing.
     155    if (anotherClientHasActiveTarget && !flagsAreSet(newFlags, MediaProducer::IsPlayingVideo))
     156        return;
     157
     158    for (auto& state : m_clientState) {
     159        if (state == changedClientState)
    156160            continue;
    157 
    158         if (flagsAreSet(state->flags, MediaProducer::IsPlayingVideo) && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
    159             return;
    160     }
    161 
    162     for (auto& state : m_clientState) {
    163         if (state->contextId == contextId && state->client == &client)
    164             continue;
    165         state->client->setShouldPlayToPlaybackTarget(state->contextId, false);
    166     }
    167 
    168     changedClientState->client->setShouldPlayToPlaybackTarget(changedClientState->contextId, true);
     161        state->client.setShouldPlayToPlaybackTarget(state->contextId, false);
     162    }
     163
     164    changedClientState->client.setShouldPlayToPlaybackTarget(changedClientState->contextId, true);
    169165
    170166    if (index && m_clientState.size() > 1)
     
    175171{
    176172    m_playbackTarget = WTF::move(target);
    177 
    178     size_t indexThatRequestedPicker = notFound;
     173    scheduleDelayedTask(TargetClientsConfigurationTask);
     174}
     175
     176void WebMediaSessionManager::externalOutputDeviceAvailableDidChange(bool available)
     177{
     178    m_externalOutputDeviceAvailable = available;
     179    for (auto& state : m_clientState)
     180        state->client.externalOutputDeviceAvailableDidChange(state->contextId, available);
     181}
     182
     183void WebMediaSessionManager::configureNewClients()
     184{
     185    for (auto& state : m_clientState) {
     186        if (!state->configurationRequired)
     187            continue;
     188
     189        state->configurationRequired = false;
     190        if (m_externalOutputDeviceAvailable)
     191            state->client.externalOutputDeviceAvailableDidChange(state->contextId, true);
     192
     193        if (m_playbackTarget)
     194            state->client.setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());
     195    }
     196}
     197
     198void WebMediaSessionManager::configurePlaybackTargetClients()
     199{
     200    size_t indexOfClientThatRequestedPicker = notFound;
     201    size_t indexOfAutoPlayCandidate = notFound;
     202    size_t indexOfClientWillPlayToTarget = notFound;
     203    bool haveActiveRoute = m_playbackTarget && m_playbackTarget->hasActiveRoute();
     204
    179205    for (size_t i = 0; i < m_clientState.size(); ++i) {
    180206        auto& state = m_clientState[i];
    181         state->client->setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());
    182         if (state->requestedPicker) {
    183             indexThatRequestedPicker = i;
    184             continue;
    185         }
    186         state->client->setShouldPlayToPlaybackTarget(state->contextId, false);
     207
     208        if (indexOfClientThatRequestedPicker == notFound && state->requestedPicker)
     209            indexOfClientThatRequestedPicker = i;
     210
     211        if (indexOfClientWillPlayToTarget == notFound && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
     212            indexOfClientWillPlayToTarget = i;
     213
     214        if (indexOfAutoPlayCandidate == notFound && flagsAreSet(state->flags, MediaProducer::ExternalDeviceAutoPlayCandidate) && !flagsAreSet(state->flags, MediaProducer::IsPlayingVideo))
     215            indexOfAutoPlayCandidate = i;
     216    }
     217
     218    if (indexOfClientThatRequestedPicker != notFound)
     219        indexOfClientWillPlayToTarget = indexOfClientThatRequestedPicker;
     220    if (indexOfClientWillPlayToTarget == notFound && haveActiveRoute && indexOfAutoPlayCandidate != notFound)
     221        indexOfClientWillPlayToTarget = indexOfAutoPlayCandidate;
     222
     223    for (size_t i = 0; i < m_clientState.size(); ++i) {
     224        auto& state = m_clientState[i];
     225
     226        if (m_playbackTarget)
     227            state->client.setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());
     228
     229        if (i != indexOfClientWillPlayToTarget)
     230            state->client.setShouldPlayToPlaybackTarget(state->contextId, false);
     231        else if (!flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
     232            state->client.setShouldPlayToPlaybackTarget(state->contextId, haveActiveRoute);
     233
     234        state->configurationRequired = false;
    187235        state->requestedPicker = false;
    188236    }
    189 
    190     if (indexThatRequestedPicker == notFound)
    191         return;
    192 
    193     auto& state = m_clientState[indexThatRequestedPicker];
    194     state->client->setShouldPlayToPlaybackTarget(state->contextId, m_playbackTarget && m_playbackTarget->hasActiveRoute());
    195     state->requestedPicker = false;
    196 }
    197 
    198 void WebMediaSessionManager::externalOutputDeviceAvailableDidChange(bool available)
    199 {
    200     m_externalOutputDeviceAvailable = available;
    201     for (auto& state : m_clientState)
    202         state->client->externalOutputDeviceAvailableDidChange(state->contextId, available);
    203237}
    204238
     
    219253}
    220254
     255void WebMediaSessionManager::scheduleDelayedTask(ConfigurationTasks tasks)
     256{
     257    m_taskFlags |= tasks;
     258    m_taskTimer.startOneShot(taskDelayInterval);
     259}
     260
    221261void WebMediaSessionManager::taskTimerFired()
    222262{
    223     auto taskQueue = WTF::move(m_taskQueue);
    224     if (taskQueue.isEmpty())
    225         return;
    226 
    227     for (auto& task : taskQueue) {
    228         size_t index = find(std::get<0>(task), std::get<1>(task));
    229 
    230         if (index == notFound)
    231             continue;
    232 
    233         std::get<2>(task)(*m_clientState[index]);
    234     }
     263    if (m_taskFlags & InitialConfigurationTask)
     264        configureNewClients();
     265    if (m_taskFlags & TargetClientsConfigurationTask)
     266        configurePlaybackTargetClients();
     267    if (m_taskFlags & TargetMonitoringConfigurationTask)
     268        configurePlaybackTargetMonitoring();
     269
     270    m_taskFlags = NoTask;
    235271}
    236272
     
    238274{
    239275    for (size_t i = 0; i < m_clientState.size(); ++i) {
    240         if (m_clientState[i]->contextId == contextId && m_clientState[i]->client == client)
     276        if (m_clientState[i]->contextId == contextId && &m_clientState[i]->client == client)
    241277            return i;
    242278    }
  • TabularUnified trunk/Source/WebCore/Modules/mediasession/WebMediaSessionManager.h

    r183096 r184204  
    6565
    6666    size_t find(WebMediaSessionManagerClient*, uint64_t);
     67    void configurePlaybackTargetClients();
     68    void configureNewClients();
    6769    void configurePlaybackTargetMonitoring();
     70
     71    enum ConfigurationTaskFlags {
     72        NoTask = 0,
     73        InitialConfigurationTask = 1 << 0,
     74        TargetClientsConfigurationTask = 1 << 1,
     75        TargetMonitoringConfigurationTask = 1 << 2,
     76    };
     77    typedef unsigned ConfigurationTasks;
     78
     79    void scheduleDelayedTask(ConfigurationTasks);
    6880    void taskTimerFired();
    69 
    70     typedef std::tuple<WebMediaSessionManagerClient*, uint64_t, std::function<void(ClientState&)>> TaskCallback;
    71     Vector<TaskCallback> m_taskQueue;
    7281    RunLoop::Timer<WebMediaSessionManager> m_taskTimer;
    7382
    7483    Vector<std::unique_ptr<ClientState>> m_clientState;
    7584    RefPtr<MediaPlaybackTarget> m_playbackTarget;
     85    ConfigurationTasks m_taskFlags { NoTask };
    7686    bool m_externalOutputDeviceAvailable { false };
    7787};
  • TabularUnified trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r184001 r184204  
    30353035
    30363036#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    3037         m_mediaSession->mediaStateDidChange(*this, mediaState());
     3037        updateMediaState();
    30383038#endif
    30393039    }
     
    46334633
    46344634#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    4635     m_mediaSession->mediaStateDidChange(*this, mediaState());
     4635    updateMediaState();
    46364636#endif
    46374637}
     
    48964896    configureMediaControls();
    48974897    scheduleEvent(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent);
    4898     m_mediaSession->mediaStateDidChange(*this, mediaState());
     4898    updateMediaState();
    48994899}
    49004900
     
    49474947void HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent()
    49484948{
    4949     LOG(Media, "HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent(%p)", this);
    4950     RefPtr<Event> event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, m_mediaSession->hasWirelessPlaybackTargets(*this));
     4949    bool hasTargets = m_mediaSession->hasWirelessPlaybackTargets(*this);
     4950    LOG(Media, "HTMLMediaElement::enqueuePlaybackTargetAvailabilityChangedEvent(%p) - hasTargets = %s", this, boolString(hasTargets));
     4951    RefPtr<Event> event = WebKitPlaybackTargetAvailabilityEvent::create(eventNames().webkitplaybacktargetavailabilitychangedEvent, hasTargets);
    49514952    event->setTarget(this);
    49524953    m_asyncEventQueue.enqueueEvent(event.release());
     
    62196220}
    62206221
     6222#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     6223void HTMLMediaElement::updateMediaState()
     6224{
     6225    MediaProducer::MediaStateFlags state = mediaState();
     6226    if (m_mediaState == state)
     6227        return;
     6228
     6229    m_mediaState = state;
     6230    m_mediaSession->mediaStateDidChange(*this, m_mediaState);
     6231}
     6232#endif
     6233
    62216234MediaProducer::MediaStateFlags HTMLMediaElement::mediaState() const
    62226235{
  • TabularUnified trunk/Source/WebCore/html/HTMLMediaElement.h

    r184001 r184204  
    741741    virtual void documentWillSuspendForPageCache() override final;
    742742    virtual void documentDidResumeFromPageCache() override final;
     743    void updateMediaState();
    743744#endif
    744745
     
    932933
    933934#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     935    MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
    934936    bool m_hasPlaybackTargetAvailabilityListeners { false };
    935937#endif
  • TabularUnified trunk/Source/WebCore/html/HTMLMediaSession.cpp

    r183509 r184204  
    306306        return;
    307307
    308     LOG(Media, "HTMLMediaSession::externalOutputDeviceAvailableDidChange - hasTargets %s", hasTargets ? "TRUE" : "FALSE");
     308    LOG(Media, "HTMLMediaSession::externalOutputDeviceAvailableDidChange(%p) - hasTargets %s", this, hasTargets ? "TRUE" : "FALSE");
    309309
    310310    m_hasPlaybackTargets = hasTargets;
    311     if (!m_targetAvailabilityChangedTimer.isActive())
    312         m_targetAvailabilityChangedTimer.startOneShot(0);
     311    m_targetAvailabilityChangedTimer.startOneShot(0);
    313312}
    314313
     
    331330void HTMLMediaSession::setShouldPlayToPlaybackTarget(bool shouldPlay)
    332331{
     332    LOG(Media, "HTMLMediaSession::setShouldPlayToPlaybackTarget - shouldPlay %s", shouldPlay ? "TRUE" : "FALSE");
    333333    m_shouldPlayToPlaybackTarget = shouldPlay;
    334334    client().setShouldPlayToPlaybackTarget(shouldPlay);
     
    387387        client().setWirelessPlaybackTarget(*m_playbackTarget.copyRef());
    388388    if (m_shouldPlayToPlaybackTarget)
    389         client().setShouldPlayToPlaybackTarget(m_shouldPlayToPlaybackTarget);
     389        client().setShouldPlayToPlaybackTarget(true);
    390390#else
    391391    UNUSED_PARAM(element);
  • TabularUnified trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm

    r183831 r184204  
    131131}
    132132
    133 #pragma clang diagnostic push
    134 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
    135133void MediaPlaybackTargetPickerMac::showPlaybackTargetPicker(const FloatRect& location, bool checkActiveRoute)
    136134{
     
    138136        return;
    139137
     138    AVOutputDeviceMenuControllerType *picker = devicePicker();
     139    if (![picker respondsToSelector:@selector(showMenuForRect:appearanceName:allowReselectionOfSelectedOutputDevice:)])
     140        return;
     141
    140142    m_showingMenu = true;
    141     AVOutputDeviceMenuControllerType *picker = devicePicker();
    142     if ([picker respondsToSelector:@selector(showMenuForRect:appearanceName:allowReselectionOfSelectedOutputDevice:)]) {
    143         if ([picker showMenuForRect:location appearanceName:NSAppearanceNameVibrantLight allowReselectionOfSelectedOutputDevice:!checkActiveRoute])
     143    if ([picker showMenuForRect:location appearanceName:NSAppearanceNameVibrantLight allowReselectionOfSelectedOutputDevice:!checkActiveRoute]) {
     144        if (!checkActiveRoute)
    144145            currentDeviceDidChange();
    145     } else
    146         [picker showMenuForRect:location appearanceName:NSAppearanceNameVibrantLight];
     146    }
    147147    m_showingMenu = false;
    148148}
    149 #pragma clang diagnostic pop
    150149
    151150void MediaPlaybackTargetPickerMac::addPendingAction(PendingActionFlags action)
Note: See TracChangeset for help on using the changeset viewer.