1 /* Copyright (c) 2013 The Chromium OS 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
6 #include <gtest/gtest.h>
7
8 extern "C" {
9 #include "cras_audio_area.h"
10 #include "cras_hfp_iodev.h"
11 #include "cras_iodev.h"
12 #include "cras_hfp_info.h"
13 }
14
15 static struct cras_iodev *iodev;
16 static struct cras_bt_device *fake_device;
17 static struct hfp_slc_handle *fake_slc;
18 static struct hfp_info *fake_info;
19 struct cras_audio_format fake_format;
20 static size_t cras_bt_device_append_iodev_called;
21 static size_t cras_bt_device_rm_iodev_called;
22 static size_t cras_iodev_add_node_called;
23 static size_t cras_iodev_rm_node_called;
24 static size_t cras_iodev_set_active_node_called;
25 static size_t cras_iodev_free_format_called;
26 static size_t cras_iodev_free_resources_called;
27 static size_t cras_bt_device_sco_connect_called;
28 static int cras_bt_transport_sco_connect_return_val;
29 static size_t hfp_info_add_iodev_called;
30 static size_t hfp_info_rm_iodev_called;
31 static size_t hfp_info_running_called;
32 static int hfp_info_running_return_val;
33 static size_t hfp_info_has_iodev_called;
34 static int hfp_info_has_iodev_return_val;
35 static size_t hfp_info_start_called;
36 static size_t hfp_info_stop_called;
37 static size_t hfp_buf_acquire_called;
38 static unsigned hfp_buf_acquire_return_val;
39 static size_t hfp_buf_release_called;
40 static unsigned hfp_buf_release_nwritten_val;
41 static cras_audio_area *dummy_audio_area;
42
ResetStubData()43 void ResetStubData() {
44 cras_bt_device_append_iodev_called = 0;
45 cras_bt_device_rm_iodev_called = 0;
46 cras_iodev_add_node_called = 0;
47 cras_iodev_rm_node_called = 0;
48 cras_iodev_set_active_node_called = 0;
49 cras_iodev_free_format_called = 0;
50 cras_iodev_free_resources_called = 0;
51 cras_bt_device_sco_connect_called = 0;
52 cras_bt_transport_sco_connect_return_val = 0;
53 hfp_info_add_iodev_called = 0;
54 hfp_info_rm_iodev_called = 0;
55 hfp_info_running_called = 0;
56 hfp_info_running_return_val = 1;
57 hfp_info_has_iodev_called = 0;
58 hfp_info_has_iodev_return_val = 0;
59 hfp_info_start_called = 0;
60 hfp_info_stop_called = 0;
61 hfp_buf_acquire_called = 0;
62 hfp_buf_acquire_return_val = 0;
63 hfp_buf_release_called = 0;
64 hfp_buf_release_nwritten_val = 0;
65
66 fake_info = reinterpret_cast<struct hfp_info *>(0x123);
67
68 if (!dummy_audio_area) {
69 dummy_audio_area = (cras_audio_area*)calloc(1,
70 sizeof(*dummy_audio_area) + sizeof(cras_channel_area) * 2);
71 }
72 }
73
74 namespace {
75
76 class HfpIodev: public testing::Test {
77 protected:
SetUp()78 virtual void SetUp() {
79 ResetStubData();
80 }
81
TearDown()82 virtual void TearDown() {
83 free(dummy_audio_area);
84 dummy_audio_area = NULL;
85 }
86 };
87
TEST_F(HfpIodev,CreateHfpOutputIodev)88 TEST_F(HfpIodev, CreateHfpOutputIodev) {
89 iodev = hfp_iodev_create(CRAS_STREAM_OUTPUT, fake_device, fake_slc,
90 CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY,
91 fake_info);
92
93 ASSERT_EQ(CRAS_STREAM_OUTPUT, iodev->direction);
94 ASSERT_EQ(1, cras_bt_device_append_iodev_called);
95 ASSERT_EQ(1, cras_iodev_add_node_called);
96 ASSERT_EQ(1, cras_iodev_set_active_node_called);
97
98 hfp_iodev_destroy(iodev);
99
100 ASSERT_EQ(1, cras_bt_device_rm_iodev_called);
101 ASSERT_EQ(1, cras_iodev_rm_node_called);
102 ASSERT_EQ(1, cras_iodev_free_resources_called);
103 }
104
TEST_F(HfpIodev,CreateHfpInputIodev)105 TEST_F(HfpIodev, CreateHfpInputIodev) {
106 iodev = hfp_iodev_create(CRAS_STREAM_INPUT, fake_device, fake_slc,
107 CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY, fake_info);
108
109 ASSERT_EQ(CRAS_STREAM_INPUT, iodev->direction);
110 ASSERT_EQ(1, cras_bt_device_append_iodev_called);
111 ASSERT_EQ(1, cras_iodev_add_node_called);
112 ASSERT_EQ(1, cras_iodev_set_active_node_called);
113 /* Input device does not use software gain. */
114 ASSERT_EQ(0, iodev->software_volume_needed);
115
116 hfp_iodev_destroy(iodev);
117
118 ASSERT_EQ(1, cras_bt_device_rm_iodev_called);
119 ASSERT_EQ(1, cras_iodev_rm_node_called);
120 ASSERT_EQ(1, cras_iodev_free_resources_called);
121 }
122
TEST_F(HfpIodev,OpenHfpIodev)123 TEST_F(HfpIodev, OpenHfpIodev) {
124 iodev = hfp_iodev_create(CRAS_STREAM_OUTPUT, fake_device, fake_slc,
125 CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY,
126 fake_info);
127 iodev->format = &fake_format;
128
129 /* hfp_info not start yet */
130 hfp_info_running_return_val = 0;
131 iodev->configure_dev(iodev);
132
133 ASSERT_EQ(1, cras_bt_device_sco_connect_called);
134 ASSERT_EQ(1, hfp_info_start_called);
135 ASSERT_EQ(1, hfp_info_add_iodev_called);
136
137 /* hfp_info is running now */
138 hfp_info_running_return_val = 1;
139
140 iodev->close_dev(iodev);
141 hfp_iodev_destroy(iodev);
142 ASSERT_EQ(1, hfp_info_rm_iodev_called);
143 ASSERT_EQ(1, hfp_info_stop_called);
144 ASSERT_EQ(1, cras_iodev_free_format_called);
145 ASSERT_EQ(1, cras_iodev_free_resources_called);
146 }
147
TEST_F(HfpIodev,OpenIodevWithHfpInfoAlreadyRunning)148 TEST_F(HfpIodev, OpenIodevWithHfpInfoAlreadyRunning) {
149 iodev = hfp_iodev_create(CRAS_STREAM_INPUT, fake_device, fake_slc,
150 CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY,
151 fake_info);
152
153 iodev->format = &fake_format;
154
155 /* hfp_info already started by another device */
156 hfp_info_running_return_val = 1;
157 iodev->configure_dev(iodev);
158
159 ASSERT_EQ(0, cras_bt_device_sco_connect_called);
160 ASSERT_EQ(0, hfp_info_start_called);
161 ASSERT_EQ(1, hfp_info_add_iodev_called);
162
163 hfp_info_has_iodev_return_val = 1;
164 iodev->close_dev(iodev);
165 hfp_iodev_destroy(iodev);
166 ASSERT_EQ(1, hfp_info_rm_iodev_called);
167 ASSERT_EQ(0, hfp_info_stop_called);
168 ASSERT_EQ(1, cras_iodev_free_format_called);
169 ASSERT_EQ(1, cras_iodev_free_resources_called);
170 }
171
TEST_F(HfpIodev,PutGetBuffer)172 TEST_F(HfpIodev, PutGetBuffer) {
173 cras_audio_area *area;
174 unsigned frames;
175
176 ResetStubData();
177 iodev = hfp_iodev_create(CRAS_STREAM_OUTPUT, fake_device, fake_slc,
178 CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY,
179 fake_info);
180 iodev->format = &fake_format;
181 iodev->configure_dev(iodev);
182
183 hfp_buf_acquire_return_val = 100;
184 iodev->get_buffer(iodev, &area, &frames);
185
186 ASSERT_EQ(1, hfp_buf_acquire_called);
187 ASSERT_EQ(100, frames);
188
189 iodev->put_buffer(iodev, 40);
190 ASSERT_EQ(1, hfp_buf_release_called);
191 ASSERT_EQ(40, hfp_buf_release_nwritten_val);
192 hfp_iodev_destroy(iodev);
193 ASSERT_EQ(1, cras_iodev_free_resources_called);
194 }
195
196 } // namespace
197
198 extern "C" {
cras_iodev_free_format(struct cras_iodev * iodev)199 void cras_iodev_free_format(struct cras_iodev *iodev)
200 {
201 cras_iodev_free_format_called++;
202 }
203
cras_iodev_add_node(struct cras_iodev * iodev,struct cras_ionode * node)204 void cras_iodev_add_node(struct cras_iodev *iodev, struct cras_ionode *node)
205 {
206 cras_iodev_add_node_called++;
207 iodev->nodes = node;
208 }
209
cras_iodev_rm_node(struct cras_iodev * iodev,struct cras_ionode * node)210 void cras_iodev_rm_node(struct cras_iodev *iodev, struct cras_ionode *node)
211 {
212 cras_iodev_rm_node_called++;
213 iodev->nodes = NULL;
214 }
215
cras_iodev_set_active_node(struct cras_iodev * iodev,struct cras_ionode * node)216 void cras_iodev_set_active_node(struct cras_iodev *iodev,
217 struct cras_ionode *node)
218 {
219 cras_iodev_set_active_node_called++;
220 iodev->active_node = node;
221 }
222
223 // From system_state.
cras_system_get_volume()224 size_t cras_system_get_volume()
225 {
226 return 0;
227 }
228
229 // From bt device
cras_bt_device_sco_connect(struct cras_bt_device * device)230 int cras_bt_device_sco_connect(struct cras_bt_device *device)
231 {
232 cras_bt_device_sco_connect_called++;
233 return cras_bt_transport_sco_connect_return_val;
234 }
235
cras_bt_device_name(const struct cras_bt_device * device)236 const char *cras_bt_device_name(const struct cras_bt_device *device)
237 {
238 return "fake-device-name";
239 }
240
cras_bt_device_address(const struct cras_bt_device * device)241 const char *cras_bt_device_address(const struct cras_bt_device *device) {
242 return "1A:2B:3C:4D:5E:6F";
243 }
244
cras_bt_device_append_iodev(struct cras_bt_device * device,struct cras_iodev * iodev,enum cras_bt_device_profile profile)245 void cras_bt_device_append_iodev(struct cras_bt_device *device,
246 struct cras_iodev *iodev,
247 enum cras_bt_device_profile profile)
248 {
249 cras_bt_device_append_iodev_called++;
250 }
251
cras_bt_device_rm_iodev(struct cras_bt_device * device,struct cras_iodev * iodev)252 void cras_bt_device_rm_iodev(struct cras_bt_device *device,
253 struct cras_iodev *iodev)
254 {
255 cras_bt_device_rm_iodev_called++;
256 }
257
cras_bt_device_sco_mtu(struct cras_bt_device * device,int sco_socket)258 int cras_bt_device_sco_mtu(struct cras_bt_device *device, int sco_socket)
259 {
260 return 48;
261 }
cras_bt_device_iodev_buffer_size_changed(struct cras_bt_device * device)262 void cras_bt_device_iodev_buffer_size_changed(struct cras_bt_device *device)
263 {
264 }
cras_bt_device_object_path(const struct cras_bt_device * device)265 const char *cras_bt_device_object_path(const struct cras_bt_device *device)
266 {
267 return "/fake/object/path";
268 }
269
270 // From cras_hfp_info
hfp_info_add_iodev(struct hfp_info * info,struct cras_iodev * dev)271 int hfp_info_add_iodev(struct hfp_info *info, struct cras_iodev *dev)
272 {
273 hfp_info_add_iodev_called++;
274 return 0;
275 }
276
hfp_info_rm_iodev(struct hfp_info * info,struct cras_iodev * dev)277 int hfp_info_rm_iodev(struct hfp_info *info, struct cras_iodev *dev)
278 {
279 hfp_info_rm_iodev_called++;
280 return 0;
281 }
282
hfp_info_has_iodev(struct hfp_info * info)283 int hfp_info_has_iodev(struct hfp_info *info)
284 {
285 hfp_info_has_iodev_called++;
286 return hfp_info_has_iodev_return_val;
287 }
288
hfp_info_running(struct hfp_info * info)289 int hfp_info_running(struct hfp_info *info)
290 {
291 hfp_info_running_called++;
292 return hfp_info_running_return_val;
293 }
294
hfp_info_start(int fd,unsigned int mtu,struct hfp_info * info)295 int hfp_info_start(int fd, unsigned int mtu, struct hfp_info *info)
296 {
297 hfp_info_start_called++;
298 return 0;
299 }
300
hfp_info_stop(struct hfp_info * info)301 int hfp_info_stop(struct hfp_info *info)
302 {
303 hfp_info_stop_called++;
304 return 0;
305 }
306
hfp_buf_queued(struct hfp_info * info,const struct cras_iodev * dev)307 int hfp_buf_queued(struct hfp_info *info, const struct cras_iodev *dev)
308 {
309 return 0;
310 }
311
hfp_buf_size(struct hfp_info * info,struct cras_iodev * dev)312 int hfp_buf_size(struct hfp_info *info, struct cras_iodev *dev)
313 {
314 /* 1008 / 2 */
315 return 504;
316 }
317
hfp_buf_acquire(struct hfp_info * info,struct cras_iodev * dev,uint8_t ** buf,unsigned * count)318 void hfp_buf_acquire(struct hfp_info *info, struct cras_iodev *dev,
319 uint8_t **buf, unsigned *count)
320 {
321 hfp_buf_acquire_called++;
322 *count = hfp_buf_acquire_return_val;
323 }
324
hfp_buf_release(struct hfp_info * info,struct cras_iodev * dev,unsigned written_bytes)325 void hfp_buf_release(struct hfp_info *info, struct cras_iodev *dev,
326 unsigned written_bytes)
327 {
328 hfp_buf_release_called++;
329 hfp_buf_release_nwritten_val = written_bytes;
330 }
331
hfp_register_packet_size_changed_callback(struct hfp_info * info,void (* cb)(void * data),void * data)332 void hfp_register_packet_size_changed_callback(struct hfp_info *info,
333 void (*cb)(void *data),
334 void *data)
335 {
336 }
337
hfp_unregister_packet_size_changed_callback(struct hfp_info * info,void * data)338 void hfp_unregister_packet_size_changed_callback(struct hfp_info *info,
339 void *data)
340 {
341 }
342
cras_iodev_init_audio_area(struct cras_iodev * iodev,int num_channels)343 void cras_iodev_init_audio_area(struct cras_iodev *iodev,
344 int num_channels) {
345 iodev->area = dummy_audio_area;
346 }
347
cras_iodev_free_audio_area(struct cras_iodev * iodev)348 void cras_iodev_free_audio_area(struct cras_iodev *iodev) {
349 }
350
cras_iodev_free_resources(struct cras_iodev * iodev)351 void cras_iodev_free_resources(struct cras_iodev *iodev) {
352 cras_iodev_free_resources_called++;
353 }
354
cras_audio_area_config_buf_pointers(struct cras_audio_area * area,const struct cras_audio_format * fmt,uint8_t * base_buffer)355 void cras_audio_area_config_buf_pointers(struct cras_audio_area *area,
356 const struct cras_audio_format *fmt,
357 uint8_t *base_buffer)
358 {
359 dummy_audio_area->channels[0].buf = base_buffer;
360 }
361
hfp_set_call_status(struct hfp_slc_handle * handle,int call)362 int hfp_set_call_status(struct hfp_slc_handle *handle, int call)
363 {
364 return 0;
365 }
366
hfp_event_speaker_gain(struct hfp_slc_handle * handle,int gain)367 int hfp_event_speaker_gain(struct hfp_slc_handle *handle, int gain)
368 {
369 return 0;
370 }
371
372 } // extern "C"
373
main(int argc,char ** argv)374 int main(int argc, char **argv) {
375 ::testing::InitGoogleTest(&argc, argv);
376 return RUN_ALL_TESTS();
377 }
378