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