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