1 // Copyright (c) 2013 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 #include "chromeos/dbus/audio/fake_cras_audio_client.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10
11 namespace chromeos {
12
13 namespace {
14
15 FakeCrasAudioClient* g_instance = nullptr;
16
17 } // namespace
18
19 const uint32_t kInputMaxSupportedChannels = 1;
20 const uint32_t kOutputMaxSupportedChannels = 2;
21
FakeCrasAudioClient()22 FakeCrasAudioClient::FakeCrasAudioClient() {
23 CHECK(!g_instance);
24 g_instance = this;
25
26 VLOG(1) << "FakeCrasAudioClient is created";
27
28 // Fake audio output nodes.
29 AudioNode output_1;
30 output_1.is_input = false;
31 output_1.id = 10001;
32 output_1.stable_device_id_v1 = 10001;
33 output_1.max_supported_channels = kOutputMaxSupportedChannels;
34 output_1.device_name = "Fake Speaker";
35 output_1.type = "INTERNAL_SPEAKER";
36 output_1.name = "Speaker";
37 node_list_.push_back(output_1);
38
39 AudioNode output_2;
40 output_2.is_input = false;
41 output_2.id = 10002;
42 output_2.stable_device_id_v1 = 10002;
43 output_2.max_supported_channels = kOutputMaxSupportedChannels;
44 output_2.device_name = "Fake Headphone";
45 output_2.type = "HEADPHONE";
46 output_2.name = "Headphone";
47 node_list_.push_back(output_2);
48
49 AudioNode output_3;
50 output_3.is_input = false;
51 output_3.id = 10003;
52 output_3.stable_device_id_v1 = 10003;
53 output_3.max_supported_channels = kOutputMaxSupportedChannels;
54 output_3.device_name = "Fake Bluetooth Headphone";
55 output_3.type = "BLUETOOTH";
56 output_3.name = "Headphone";
57 node_list_.push_back(output_3);
58
59 AudioNode output_4;
60 output_4.is_input = false;
61 output_4.id = 10004;
62 output_4.stable_device_id_v1 = 10004;
63 output_4.max_supported_channels = kOutputMaxSupportedChannels;
64 output_4.device_name = "Fake HDMI Speaker";
65 output_4.type = "HDMI";
66 output_4.name = "HDMI Speaker";
67 node_list_.push_back(output_4);
68
69 // Fake audio input nodes
70 AudioNode input_1;
71 input_1.is_input = true;
72 input_1.id = 20001;
73 input_1.stable_device_id_v1 = 20001;
74 input_1.max_supported_channels = kInputMaxSupportedChannels;
75 input_1.device_name = "Fake Internal Mic";
76 input_1.type = "INTERNAL_MIC";
77 input_1.name = "Internal Mic";
78 node_list_.push_back(input_1);
79
80 AudioNode input_2;
81 input_2.is_input = true;
82 input_2.id = 20002;
83 input_2.stable_device_id_v1 = 20002;
84 input_2.max_supported_channels = kInputMaxSupportedChannels;
85 input_2.device_name = "Fake USB Mic";
86 input_2.type = "USB";
87 input_2.name = "Mic";
88 node_list_.push_back(input_2);
89
90 AudioNode input_3;
91 input_3.is_input = true;
92 input_3.id = 20003;
93 input_3.stable_device_id_v1 = 20003;
94 input_3.max_supported_channels = kInputMaxSupportedChannels;
95 input_3.device_name = "Fake Mic Jack";
96 input_3.type = "MIC";
97 input_3.name = "Some type of Mic";
98 node_list_.push_back(input_3);
99 }
100
~FakeCrasAudioClient()101 FakeCrasAudioClient::~FakeCrasAudioClient() {
102 CHECK_EQ(this, g_instance);
103 g_instance = nullptr;
104 }
105
106 // static
Get()107 FakeCrasAudioClient* FakeCrasAudioClient::Get() {
108 return g_instance;
109 }
110
AddObserver(Observer * observer)111 void FakeCrasAudioClient::AddObserver(Observer* observer) {
112 observers_.AddObserver(observer);
113 }
114
RemoveObserver(Observer * observer)115 void FakeCrasAudioClient::RemoveObserver(Observer* observer) {
116 observers_.RemoveObserver(observer);
117 }
118
HasObserver(const Observer * observer) const119 bool FakeCrasAudioClient::HasObserver(const Observer* observer) const {
120 return observers_.HasObserver(observer);
121 }
122
GetVolumeState(DBusMethodCallback<VolumeState> callback)123 void FakeCrasAudioClient::GetVolumeState(
124 DBusMethodCallback<VolumeState> callback) {
125 std::move(callback).Run(volume_state_);
126 }
127
GetDefaultOutputBufferSize(DBusMethodCallback<int> callback)128 void FakeCrasAudioClient::GetDefaultOutputBufferSize(
129 DBusMethodCallback<int> callback) {
130 std::move(callback).Run(512);
131 }
132
GetSystemAecSupported(DBusMethodCallback<bool> callback)133 void FakeCrasAudioClient::GetSystemAecSupported(
134 DBusMethodCallback<bool> callback) {
135 std::move(callback).Run(false);
136 }
137
GetSystemAecGroupId(DBusMethodCallback<int32_t> callback)138 void FakeCrasAudioClient::GetSystemAecGroupId(
139 DBusMethodCallback<int32_t> callback) {
140 std::move(callback).Run(1);
141 }
142
GetNodes(DBusMethodCallback<AudioNodeList> callback)143 void FakeCrasAudioClient::GetNodes(DBusMethodCallback<AudioNodeList> callback) {
144 std::move(callback).Run(node_list_);
145 }
146
GetNumberOfActiveOutputStreams(DBusMethodCallback<int> callback)147 void FakeCrasAudioClient::GetNumberOfActiveOutputStreams(
148 DBusMethodCallback<int> callback) {
149 std::move(callback).Run(0);
150 }
151
GetDeprioritizeBtWbsMic(DBusMethodCallback<bool> callback)152 void FakeCrasAudioClient::GetDeprioritizeBtWbsMic(
153 DBusMethodCallback<bool> callback) {
154 std::move(callback).Run(base::nullopt);
155 }
156
SetOutputNodeVolume(uint64_t node_id,int32_t volume)157 void FakeCrasAudioClient::SetOutputNodeVolume(uint64_t node_id,
158 int32_t volume) {
159 if (!notify_volume_change_with_delay_)
160 NotifyOutputNodeVolumeChangedForTesting(node_id, volume);
161 }
162
SetOutputUserMute(bool mute_on)163 void FakeCrasAudioClient::SetOutputUserMute(bool mute_on) {
164 volume_state_.output_user_mute = mute_on;
165 for (auto& observer : observers_)
166 observer.OutputMuteChanged(volume_state_.output_user_mute);
167 }
168
SetInputNodeGain(uint64_t node_id,int32_t input_gain)169 void FakeCrasAudioClient::SetInputNodeGain(uint64_t node_id,
170 int32_t input_gain) {}
171
SetInputMute(bool mute_on)172 void FakeCrasAudioClient::SetInputMute(bool mute_on) {
173 volume_state_.input_mute = mute_on;
174 for (auto& observer : observers_)
175 observer.InputMuteChanged(volume_state_.input_mute);
176 }
177
SetActiveOutputNode(uint64_t node_id)178 void FakeCrasAudioClient::SetActiveOutputNode(uint64_t node_id) {
179 if (active_output_node_id_ == node_id)
180 return;
181
182 for (size_t i = 0; i < node_list_.size(); ++i) {
183 if (node_list_[i].id == active_output_node_id_)
184 node_list_[i].active = false;
185 else if (node_list_[i].id == node_id)
186 node_list_[i].active = true;
187 }
188 active_output_node_id_ = node_id;
189 for (auto& observer : observers_)
190 observer.ActiveOutputNodeChanged(node_id);
191 }
192
SetActiveInputNode(uint64_t node_id)193 void FakeCrasAudioClient::SetActiveInputNode(uint64_t node_id) {
194 if (active_input_node_id_ == node_id)
195 return;
196
197 for (size_t i = 0; i < node_list_.size(); ++i) {
198 if (node_list_[i].id == active_input_node_id_)
199 node_list_[i].active = false;
200 else if (node_list_[i].id == node_id)
201 node_list_[i].active = true;
202 }
203 active_input_node_id_ = node_id;
204 for (auto& observer : observers_)
205 observer.ActiveInputNodeChanged(node_id);
206 }
207
SetHotwordModel(uint64_t node_id,const std::string & hotword_model,VoidDBusMethodCallback callback)208 void FakeCrasAudioClient::SetHotwordModel(uint64_t node_id,
209 const std::string& hotword_model,
210 VoidDBusMethodCallback callback) {}
211
SetFixA2dpPacketSize(bool enabled)212 void FakeCrasAudioClient::SetFixA2dpPacketSize(bool enabled) {}
213
AddActiveInputNode(uint64_t node_id)214 void FakeCrasAudioClient::AddActiveInputNode(uint64_t node_id) {
215 for (size_t i = 0; i < node_list_.size(); ++i) {
216 if (node_list_[i].id == node_id)
217 node_list_[i].active = true;
218 }
219 }
220
RemoveActiveInputNode(uint64_t node_id)221 void FakeCrasAudioClient::RemoveActiveInputNode(uint64_t node_id) {
222 for (size_t i = 0; i < node_list_.size(); ++i) {
223 if (node_list_[i].id == node_id)
224 node_list_[i].active = false;
225 }
226 }
227
SwapLeftRight(uint64_t node_id,bool swap)228 void FakeCrasAudioClient::SwapLeftRight(uint64_t node_id, bool swap) {}
229
SetGlobalOutputChannelRemix(int32_t channels,const std::vector<double> & mixer)230 void FakeCrasAudioClient::SetGlobalOutputChannelRemix(
231 int32_t channels,
232 const std::vector<double>& mixer) {}
233
SetPlayerPlaybackStatus(const std::string & playback_status)234 void FakeCrasAudioClient::SetPlayerPlaybackStatus(
235 const std::string& playback_status) {}
236
SetPlayerIdentity(const std::string & playback_identity)237 void FakeCrasAudioClient::SetPlayerIdentity(
238 const std::string& playback_identity) {}
239
SetPlayerPosition(const int64_t & position)240 void FakeCrasAudioClient::SetPlayerPosition(const int64_t& position) {}
241
SetPlayerDuration(const int64_t & duration)242 void FakeCrasAudioClient::SetPlayerDuration(const int64_t& duration) {}
243
SetPlayerMetadata(const std::map<std::string,std::string> & metadata)244 void FakeCrasAudioClient::SetPlayerMetadata(
245 const std::map<std::string, std::string>& metadata) {}
246
AddActiveOutputNode(uint64_t node_id)247 void FakeCrasAudioClient::AddActiveOutputNode(uint64_t node_id) {
248 for (size_t i = 0; i < node_list_.size(); ++i) {
249 if (node_list_[i].id == node_id)
250 node_list_[i].active = true;
251 }
252 }
253
ResendBluetoothBattery()254 void FakeCrasAudioClient::ResendBluetoothBattery() {
255 for (auto& observer : observers_)
256 observer.BluetoothBatteryChanged("11:22:33:44:55:66", battery_level_);
257 }
258
WaitForServiceToBeAvailable(WaitForServiceToBeAvailableCallback callback)259 void FakeCrasAudioClient::WaitForServiceToBeAvailable(
260 WaitForServiceToBeAvailableCallback callback) {
261 std::move(callback).Run(true);
262 }
263
RemoveActiveOutputNode(uint64_t node_id)264 void FakeCrasAudioClient::RemoveActiveOutputNode(uint64_t node_id) {
265 for (size_t i = 0; i < node_list_.size(); ++i) {
266 if (node_list_[i].id == node_id)
267 node_list_[i].active = false;
268 }
269 }
270
InsertAudioNodeToList(const AudioNode & audio_node)271 void FakeCrasAudioClient::InsertAudioNodeToList(const AudioNode& audio_node) {
272 auto iter = FindNode(audio_node.id);
273 if (iter != node_list_.end())
274 (*iter) = audio_node;
275 else
276 node_list_.push_back(audio_node);
277 for (auto& observer : observers_)
278 observer.NodesChanged();
279 }
280
RemoveAudioNodeFromList(const uint64_t & node_id)281 void FakeCrasAudioClient::RemoveAudioNodeFromList(const uint64_t& node_id) {
282 auto iter = FindNode(node_id);
283 if (iter != node_list_.end()) {
284 node_list_.erase(iter);
285 for (auto& observer : observers_)
286 observer.NodesChanged();
287 }
288 }
289
SetAudioNodesForTesting(const AudioNodeList & audio_nodes)290 void FakeCrasAudioClient::SetAudioNodesForTesting(
291 const AudioNodeList& audio_nodes) {
292 node_list_ = audio_nodes;
293 }
294
SetAudioNodesAndNotifyObserversForTesting(const AudioNodeList & new_nodes)295 void FakeCrasAudioClient::SetAudioNodesAndNotifyObserversForTesting(
296 const AudioNodeList& new_nodes) {
297 SetAudioNodesForTesting(new_nodes);
298 for (auto& observer : observers_)
299 observer.NodesChanged();
300 }
301
NotifyOutputNodeVolumeChangedForTesting(uint64_t node_id,int volume)302 void FakeCrasAudioClient::NotifyOutputNodeVolumeChangedForTesting(
303 uint64_t node_id,
304 int volume) {
305 for (auto& observer : observers_)
306 observer.OutputNodeVolumeChanged(node_id, volume);
307 }
308
NotifyHotwordTriggeredForTesting(uint64_t tv_sec,uint64_t tv_nsec)309 void FakeCrasAudioClient::NotifyHotwordTriggeredForTesting(uint64_t tv_sec,
310 uint64_t tv_nsec) {
311 for (auto& observer : observers_)
312 observer.HotwordTriggered(tv_sec, tv_nsec);
313 }
314
SetBluetoothBattteryLevelForTesting(uint32_t level)315 void FakeCrasAudioClient::SetBluetoothBattteryLevelForTesting(uint32_t level) {
316 battery_level_ = level;
317 }
318
FindNode(uint64_t node_id)319 AudioNodeList::iterator FakeCrasAudioClient::FindNode(uint64_t node_id) {
320 return std::find_if(
321 node_list_.begin(), node_list_.end(),
322 [node_id](const AudioNode& node) { return node_id == node.id; });
323 }
324
325 } // namespace chromeos
326