1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_AUDIO_WIN_AUDIO_DEVICE_LISTENER_WIN_H_ 6 #define MEDIA_AUDIO_WIN_AUDIO_DEVICE_LISTENER_WIN_H_ 7 8 #include <MMDeviceAPI.h> 9 #include <wrl/client.h> 10 11 #include <memory> 12 #include <string> 13 14 #include "base/callback.h" 15 #include "base/macros.h" 16 #include "base/threading/thread_checker.h" 17 #include "base/time/time.h" 18 #include "media/base/media_export.h" 19 20 namespace base { 21 class TickClock; 22 } 23 24 namespace media { 25 26 // IMMNotificationClient implementation for listening for default device changes 27 // and forwarding to AudioManagerWin so it can notify downstream clients. Only 28 // output (eRender) device changes are supported currently. Core Audio support 29 // is required to construct this object. Must be constructed and destructed on 30 // a single COM initialized thread. 31 // TODO(dalecurtis, henrika): Support input device changes. 32 class MEDIA_EXPORT AudioDeviceListenerWin : public IMMNotificationClient { 33 public: 34 // The listener callback will be called from a system level multimedia thread, 35 // thus the callee must be thread safe. |listener_cb| is a permanent callback 36 // and must outlive AudioDeviceListenerWin. 37 explicit AudioDeviceListenerWin(base::RepeatingClosure listener_cb); 38 virtual ~AudioDeviceListenerWin(); 39 40 private: 41 friend class AudioDeviceListenerWinTest; 42 43 // Minimum allowed time between device change notifications. 44 static constexpr base::TimeDelta kDeviceChangeLimit = 45 base::TimeDelta::FromMilliseconds(250); 46 47 // IMMNotificationClient implementation. 48 IFACEMETHODIMP_(ULONG) AddRef() override; 49 IFACEMETHODIMP_(ULONG) Release() override; 50 IFACEMETHODIMP QueryInterface(REFIID iid, void** object) override; 51 IFACEMETHODIMP OnPropertyValueChanged(LPCWSTR device_id, 52 const PROPERTYKEY key) override; 53 IFACEMETHODIMP OnDeviceAdded(LPCWSTR device_id) override; 54 IFACEMETHODIMP OnDeviceRemoved(LPCWSTR device_id) override; 55 IFACEMETHODIMP OnDeviceStateChanged(LPCWSTR device_id, 56 DWORD new_state) override; 57 IFACEMETHODIMP OnDefaultDeviceChanged(EDataFlow flow, 58 ERole role, 59 LPCWSTR new_default_device_id) override; 60 61 const base::RepeatingClosure listener_cb_; 62 Microsoft::WRL::ComPtr<IMMDeviceEnumerator> device_enumerator_; 63 64 // Used to rate limit device change events. 65 base::TimeTicks last_device_change_time_; 66 std::string last_device_id_; 67 68 // AudioDeviceListenerWin must be constructed and destructed on one thread. 69 THREAD_CHECKER(thread_checker_); 70 71 const base::TickClock* tick_clock_; 72 73 DISALLOW_COPY_AND_ASSIGN(AudioDeviceListenerWin); 74 }; 75 76 } // namespace media 77 78 #endif // MEDIA_AUDIO_WIN_AUDIO_DEVICE_LISTENER_WIN_H_ 79