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