• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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