1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
media / audio / mac / audio_device_listener_mac.h [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_AUDIO_MAC_AUDIO_DEVICE_LISTENER_MAC_H_
#define MEDIA_AUDIO_MAC_AUDIO_DEVICE_LISTENER_MAC_H_
#include <CoreAudio/AudioHardware.h>
#include <map>
#include <memory>
#include <optional>
#include <utility>
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/threading/thread_checker.h"
#include "media/base/media_export.h"
namespace media {
// AudioDeviceListenerMac facilitates execution of device listener callbacks
// issued via CoreAudio.
class MEDIA_EXPORT AudioDeviceListenerMac {
public:
// |listener_cb| will be called when a device change occurs; it's a permanent
// callback and must outlive AudioDeviceListenerMac. Note that |listener_cb|
// might not be executed on the same thread as construction.
static std::unique_ptr<AudioDeviceListenerMac> Create(
base::RepeatingClosure listener_cb,
bool monitor_output_sample_rate_changes,
bool monitor_default_input,
bool monitor_addition_removal,
bool monitor_sources);
AudioDeviceListenerMac(const AudioDeviceListenerMac&) = delete;
AudioDeviceListenerMac& operator=(const AudioDeviceListenerMac&) = delete;
// Virtual for overriding in tests.
virtual ~AudioDeviceListenerMac();
private:
friend class AudioDeviceListenerMacTest;
friend class AudioDeviceListenerMacUnderTest;
class PropertyListener;
struct PropertyListenerDeleter {
void operator()(PropertyListener* listener);
};
using PropertyListenerPtr =
std::unique_ptr<PropertyListener, PropertyListenerDeleter>;
static const AudioObjectPropertyAddress
kDefaultOutputDeviceChangePropertyAddress;
static const AudioObjectPropertyAddress
kDefaultInputDeviceChangePropertyAddress;
static const AudioObjectPropertyAddress kDevicesPropertyAddress;
static const AudioObjectPropertyAddress kPropertyOutputSampleRateChanged;
static const AudioObjectPropertyAddress kPropertyOutputSourceChanged;
static const AudioObjectPropertyAddress kPropertyInputSourceChanged;
AudioDeviceListenerMac(base::RepeatingClosure listener_cb,
bool monitor_output_sample_rate_changes,
bool monitor_default_input,
bool monitor_addition_removal,
bool monitor_sources);
// Must be called only once after constructor.
void CreatePropertyListeners();
void RunCallback();
void UpdateDevicePropertyListeners();
void OnDevicesAddedOrRemoved();
void UpdateSourceListeners(const std::vector<AudioObjectID>& device_ids);
void UpdateOutputSampleRateListeners(
const std::vector<AudioObjectID>& device_ids);
PropertyListenerPtr CreatePropertyListener(
AudioObjectID monitored_object,
const AudioObjectPropertyAddress* property,
base::RepeatingClosure listener_cb);
// Virtual for testing.
virtual std::vector<AudioObjectID> GetAllAudioDeviceIDs();
virtual bool IsOutputDevice(AudioObjectID id);
virtual std::optional<uint32_t> GetDeviceSource(AudioObjectID device_id,
bool is_input);
virtual OSStatus AddPropertyListener(
AudioObjectID inObjectID,
const AudioObjectPropertyAddress* inAddress,
AudioObjectPropertyListenerProc inListener,
void* inClientData);
virtual OSStatus RemovePropertyListener(
AudioObjectID inObjectID,
const AudioObjectPropertyAddress* inAddress,
AudioObjectPropertyListenerProc inListener,
void* inClientData);
std::vector<void*> GetPropertyListenersForTesting() const;
static OSStatus SimulateEventForTesting(
AudioObjectID object,
UInt32 num_addresses,
const AudioObjectPropertyAddress addresses[],
void* context);
const base::RepeatingClosure listener_cb_;
PropertyListenerPtr default_output_listener_;
const bool monitor_default_input_;
PropertyListenerPtr default_input_listener_;
const bool monitor_addition_removal_;
PropertyListenerPtr addition_removal_listener_;
const bool monitor_output_sample_rate_changes_;
using OutputSampleRateListenerMap =
base::flat_map<AudioObjectID, PropertyListenerPtr>;
OutputSampleRateListenerMap output_sample_rate_listeners_;
const bool monitor_sources_;
using SourceListenerKey = std::pair<AudioObjectID, bool>;
using SourceListenerMap =
base::flat_map<SourceListenerKey, PropertyListenerPtr>;
SourceListenerMap source_listeners_;
THREAD_CHECKER(thread_checker_);
};
} // namespace media
#endif // MEDIA_AUDIO_MAC_AUDIO_DEVICE_LISTENER_MAC_H_