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