• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2014 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 #include <gtest/gtest.h>
6 
7 extern "C" {
8 
9 // To test static functions.
10 #include "cras_bt_io.c"
11 }
12 
13 static struct cras_bt_device *fake_device =
14     reinterpret_cast<struct cras_bt_device*>(0x123);
15 static unsigned int cras_iodev_add_node_called;
16 static unsigned int cras_iodev_rm_node_called;
17 static unsigned int cras_iodev_free_format_called;
18 static unsigned int cras_iodev_set_active_node_called;
19 static unsigned int cras_iodev_list_add_output_called;
20 static unsigned int cras_iodev_list_rm_output_called;
21 static unsigned int cras_iodev_list_add_input_called;
22 static unsigned int cras_iodev_list_rm_input_called;
23 static unsigned int cras_bt_device_set_active_profile_called;
24 static unsigned int cras_bt_device_set_active_profile_val;
25 static int cras_bt_device_get_active_profile_ret;
26 static int cras_bt_device_switch_profile_enable_dev_called;
27 static int cras_bt_device_switch_profile_called;
28 static int cras_bt_device_can_switch_to_a2dp_ret;
29 static int cras_bt_device_has_a2dp_ret;
30 static int is_utf8_string_ret_value;
31 
ResetStubData()32 void ResetStubData() {
33   cras_iodev_add_node_called = 0;
34   cras_iodev_rm_node_called = 0;
35   cras_iodev_free_format_called = 0;
36   cras_iodev_set_active_node_called = 0;
37   cras_iodev_list_add_output_called = 0;
38   cras_iodev_list_rm_output_called = 0;
39   cras_iodev_list_add_input_called = 0;
40   cras_iodev_list_rm_input_called = 0;
41   cras_bt_device_set_active_profile_called = 0;
42   cras_bt_device_set_active_profile_val = 0;
43   cras_bt_device_get_active_profile_ret = 0;
44   cras_bt_device_switch_profile_enable_dev_called= 0;
45   cras_bt_device_switch_profile_called = 0;
46   cras_bt_device_can_switch_to_a2dp_ret = 0;
47   cras_bt_device_has_a2dp_ret = 0;
48   is_utf8_string_ret_value = 1;
49 }
50 
51 namespace {
52 
53 class BtIoBasicSuite : public testing::Test {
54   protected:
SetUp()55     virtual void SetUp() {
56       ResetStubData();
57       SetUpIodev(&iodev_, CRAS_STREAM_OUTPUT);
58       SetUpIodev(&iodev2_, CRAS_STREAM_OUTPUT);
59 
60       update_supported_formats_called_ = 0;
61       frames_queued_called_ = 0;
62       delay_frames_called_ = 0;
63       get_buffer_called_ = 0;
64       put_buffer_called_ = 0;
65       open_dev_called_ = 0;
66       close_dev_called_ = 0;
67     }
68 
TearDown()69     virtual void TearDown() {
70     }
71 
SetUpIodev(struct cras_iodev * d,enum CRAS_STREAM_DIRECTION dir)72     static void SetUpIodev(struct cras_iodev *d,
73                            enum CRAS_STREAM_DIRECTION dir) {
74       d->direction = dir;
75       d->update_supported_formats = update_supported_formats;
76       d->frames_queued = frames_queued;
77       d->delay_frames = delay_frames;
78       d->get_buffer = get_buffer;
79       d->put_buffer = put_buffer;
80       d->open_dev = open_dev;
81       d->close_dev = close_dev;
82     }
83 
84     // Stub functions for the iodev structure.
update_supported_formats(struct cras_iodev * iodev)85     static int update_supported_formats(struct cras_iodev *iodev) {
86       iodev->supported_rates = (size_t *)calloc(
87           2, sizeof(*iodev->supported_rates));
88       iodev->supported_rates[0] = 48000;
89       iodev->supported_rates[1] = 0;
90       iodev->supported_channel_counts = (size_t *)calloc(
91           2, sizeof(*iodev->supported_channel_counts));
92       iodev->supported_channel_counts[0] = 2;
93       iodev->supported_channel_counts[1] = 0;
94       iodev->supported_formats = (snd_pcm_format_t *)calloc(
95           2, sizeof(*iodev->supported_formats));
96       iodev->supported_formats[0] = SND_PCM_FORMAT_S16_LE;
97       iodev->supported_formats[1] = (snd_pcm_format_t)0;
98       update_supported_formats_called_++;
99       return 0;
100     }
frames_queued(const cras_iodev * iodev,struct timespec * tstamp)101     static int frames_queued(const cras_iodev* iodev,
102                              struct timespec *tstamp) {
103       frames_queued_called_++;
104       return 0;
105     }
delay_frames(const cras_iodev * iodev)106     static int delay_frames(const cras_iodev* iodev) {
107       delay_frames_called_++;
108       return 0;
109     }
get_buffer(cras_iodev * iodev,struct cras_audio_area ** area,unsigned int * num)110     static int get_buffer(cras_iodev* iodev,
111                           struct cras_audio_area** area,
112                           unsigned int* num) {
113       get_buffer_called_++;
114       return 0;
115     }
put_buffer(cras_iodev * iodev,unsigned int num)116     static int put_buffer(cras_iodev* iodev,
117                           unsigned int num) {
118       put_buffer_called_++;
119       return 0;
120     }
open_dev(cras_iodev * iodev)121     static int open_dev(cras_iodev* iodev) {
122       open_dev_called_++;
123       return 0;
124     }
close_dev(cras_iodev * iodev)125     static int close_dev(cras_iodev* iodev) {
126       close_dev_called_++;
127       return 0;
128     }
129 
130   static struct cras_iodev *bt_iodev;
131   static struct cras_iodev iodev_;
132   static struct cras_iodev iodev2_;
133   static unsigned int update_supported_formats_called_;
134   static unsigned int frames_queued_called_;
135   static unsigned int delay_frames_called_;
136   static unsigned int get_buffer_called_;
137   static unsigned int put_buffer_called_;
138   static unsigned int open_dev_called_;
139   static unsigned int close_dev_called_;
140 };
141 
142 struct cras_iodev *BtIoBasicSuite::bt_iodev;
143 struct cras_iodev BtIoBasicSuite::iodev_;
144 struct cras_iodev BtIoBasicSuite::iodev2_;
145 unsigned int BtIoBasicSuite::update_supported_formats_called_;
146 unsigned int BtIoBasicSuite::frames_queued_called_;
147 unsigned int BtIoBasicSuite::delay_frames_called_;
148 unsigned int BtIoBasicSuite::get_buffer_called_;
149 unsigned int BtIoBasicSuite::put_buffer_called_;
150 unsigned int BtIoBasicSuite::open_dev_called_;
151 unsigned int BtIoBasicSuite::close_dev_called_;
152 
TEST_F(BtIoBasicSuite,CreateBtIo)153 TEST_F(BtIoBasicSuite, CreateBtIo) {
154   struct cras_audio_area *fake_area;
155   struct cras_audio_format fake_fmt;
156   struct timespec tstamp;
157   unsigned fr;
158   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
159       CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
160   EXPECT_NE((void *)NULL, bt_iodev);
161   EXPECT_EQ(&iodev_, active_profile_dev(bt_iodev));
162   EXPECT_EQ(1, cras_iodev_list_add_output_called);
163   bt_iodev->format = &fake_fmt;
164   bt_iodev->update_supported_formats(bt_iodev);
165   EXPECT_EQ(1, update_supported_formats_called_);
166 
167   bt_iodev->open_dev(bt_iodev);
168   EXPECT_EQ(1, open_dev_called_);
169   bt_iodev->frames_queued(bt_iodev, &tstamp);
170   EXPECT_EQ(1, frames_queued_called_);
171   bt_iodev->get_buffer(bt_iodev, &fake_area, &fr);
172   EXPECT_EQ(1, get_buffer_called_);
173   bt_iodev->put_buffer(bt_iodev, fr);
174   EXPECT_EQ(1, put_buffer_called_);
175   bt_iodev->close_dev(bt_iodev);
176   EXPECT_EQ(1, close_dev_called_);
177   EXPECT_EQ(1, cras_iodev_free_format_called);
178   cras_bt_io_destroy(bt_iodev);
179   EXPECT_EQ(1, cras_iodev_list_rm_output_called);
180 }
181 
TEST_F(BtIoBasicSuite,SwitchProfileOnUpdateFormatForInputDev)182 TEST_F(BtIoBasicSuite, SwitchProfileOnUpdateFormatForInputDev) {
183   ResetStubData();
184   iodev_.direction = CRAS_STREAM_INPUT;
185   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
186       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
187 
188   cras_bt_device_get_active_profile_ret = CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
189   bt_iodev->update_supported_formats(bt_iodev);
190 
191   EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY |
192             CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY,
193             cras_bt_device_set_active_profile_val);
194   EXPECT_EQ(1, cras_bt_device_switch_profile_enable_dev_called);
195 }
196 
TEST_F(BtIoBasicSuite,NoSwitchProfileOnUpdateFormatForInputDevAlreadyOnHfp)197 TEST_F(BtIoBasicSuite, NoSwitchProfileOnUpdateFormatForInputDevAlreadyOnHfp) {
198   ResetStubData();
199   iodev_.direction = CRAS_STREAM_INPUT;
200   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
201       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
202 
203   /* No need to switch profile if already on HFP. */
204   cras_bt_device_get_active_profile_ret =
205       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY;
206   bt_iodev->update_supported_formats(bt_iodev);
207 
208   EXPECT_EQ(0, cras_bt_device_switch_profile_enable_dev_called);
209 }
210 
TEST_F(BtIoBasicSuite,SwitchProfileOnCloseInputDev)211 TEST_F(BtIoBasicSuite, SwitchProfileOnCloseInputDev) {
212   ResetStubData();
213   iodev_.direction = CRAS_STREAM_INPUT;
214   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
215       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
216 
217   cras_bt_device_get_active_profile_ret =
218       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY |
219       CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
220   cras_bt_device_has_a2dp_ret = 1;
221   bt_iodev->close_dev(bt_iodev);
222 
223   EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE,
224             cras_bt_device_set_active_profile_val);
225   EXPECT_EQ(1, cras_bt_device_switch_profile_called);
226 }
227 
TEST_F(BtIoBasicSuite,NoSwitchProfileOnCloseInputDevNoSupportA2dp)228 TEST_F(BtIoBasicSuite, NoSwitchProfileOnCloseInputDevNoSupportA2dp) {
229   ResetStubData();
230   iodev_.direction = CRAS_STREAM_INPUT;
231   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
232       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
233 
234   cras_bt_device_get_active_profile_ret =
235       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY |
236       CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
237   cras_bt_device_has_a2dp_ret = 0;
238   bt_iodev->close_dev(bt_iodev);
239 
240   EXPECT_EQ(0, cras_bt_device_switch_profile_called);
241 }
242 
TEST_F(BtIoBasicSuite,SwitchProfileOnAppendA2dpDev)243 TEST_F(BtIoBasicSuite, SwitchProfileOnAppendA2dpDev) {
244   ResetStubData();
245   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
246       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
247 
248   cras_bt_device_can_switch_to_a2dp_ret = 1;
249   cras_bt_io_append(bt_iodev, &iodev2_,
250       CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
251 
252   EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE,
253             cras_bt_device_set_active_profile_val);
254   EXPECT_EQ(0, cras_bt_device_switch_profile_enable_dev_called);
255   EXPECT_EQ(1, cras_bt_device_switch_profile_called);
256 }
257 
TEST_F(BtIoBasicSuite,NoSwitchProfileOnAppendHfpDev)258 TEST_F(BtIoBasicSuite, NoSwitchProfileOnAppendHfpDev) {
259   ResetStubData();
260   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
261       CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
262 
263   cras_bt_device_can_switch_to_a2dp_ret = 1;
264   cras_bt_io_append(bt_iodev, &iodev2_,
265       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
266 
267   EXPECT_EQ(0, cras_bt_device_switch_profile_enable_dev_called);
268 }
269 
TEST_F(BtIoBasicSuite,CreateSetDeviceActiveProfileToA2DP)270 TEST_F(BtIoBasicSuite, CreateSetDeviceActiveProfileToA2DP) {
271   ResetStubData();
272   cras_bt_device_get_active_profile_ret =
273       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY;
274   cras_bt_device_can_switch_to_a2dp_ret = 1;
275   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
276       CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
277 
278   EXPECT_EQ(1, cras_bt_device_set_active_profile_called);
279   EXPECT_EQ(CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE,
280       cras_bt_device_set_active_profile_val);
281   cras_bt_io_destroy(bt_iodev);
282 }
283 
TEST_F(BtIoBasicSuite,CreateNoSetDeviceActiveProfileToA2DP)284 TEST_F(BtIoBasicSuite, CreateNoSetDeviceActiveProfileToA2DP) {
285   ResetStubData();
286   cras_bt_device_get_active_profile_ret =
287       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY;
288   cras_bt_device_can_switch_to_a2dp_ret = 0;
289   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
290       CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
291 
292   EXPECT_EQ(0, cras_bt_device_set_active_profile_called);
293   cras_bt_io_destroy(bt_iodev);
294 }
295 
TEST_F(BtIoBasicSuite,CreateSetDeviceActiveProfileToHFP)296 TEST_F(BtIoBasicSuite, CreateSetDeviceActiveProfileToHFP) {
297   ResetStubData();
298   cras_bt_device_get_active_profile_ret = 0;
299   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
300       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
301 
302   EXPECT_EQ(
303       CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY |
304           CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY,
305       cras_bt_device_set_active_profile_val);
306   cras_bt_io_destroy(bt_iodev);
307 }
308 
TEST_F(BtIoBasicSuite,CreateDeviceWithInvalidUTF8Name)309 TEST_F(BtIoBasicSuite, CreateDeviceWithInvalidUTF8Name) {
310   ResetStubData();
311   strcpy(iodev_.info.name, "Something BT");
312   iodev_.info.name[0] = 0xfe;
313   is_utf8_string_ret_value = 0;
314   bt_iodev = cras_bt_io_create(fake_device, &iodev_,
315       CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
316 
317   ASSERT_STREQ("BLUETOOTH", bt_iodev->active_node->name);
318 }
319 
320 } // namespace
321 
main(int argc,char ** argv)322 int main(int argc, char **argv) {
323   ::testing::InitGoogleTest(&argc, argv);
324   return RUN_ALL_TESTS();
325 }
326 
327 extern "C" {
328 
329 // Cras iodev
cras_iodev_add_node(struct cras_iodev * iodev,struct cras_ionode * node)330 void cras_iodev_add_node(struct cras_iodev *iodev, struct cras_ionode *node)
331 {
332   cras_iodev_add_node_called++;
333   iodev->nodes = node;
334 }
335 
cras_iodev_rm_node(struct cras_iodev * iodev,struct cras_ionode * node)336 void cras_iodev_rm_node(struct cras_iodev *iodev, struct cras_ionode *node)
337 {
338   cras_iodev_rm_node_called++;
339   iodev->nodes = NULL;
340 }
341 
cras_iodev_free_format(struct cras_iodev * iodev)342 void cras_iodev_free_format(struct cras_iodev *iodev)
343 {
344   cras_iodev_free_format_called++;
345 }
346 
cras_iodev_set_active_node(struct cras_iodev * iodev,struct cras_ionode * node)347 void cras_iodev_set_active_node(struct cras_iodev *iodev,
348         struct cras_ionode *node)
349 {
350   cras_iodev_set_active_node_called++;
351   iodev->active_node = node;
352 }
353 
cras_iodev_set_node_attr(struct cras_ionode * ionode,enum ionode_attr attr,int value)354 int cras_iodev_set_node_attr(struct cras_ionode *ionode,
355            enum ionode_attr attr, int value)
356 {
357   return 0;
358 }
359 
360 //  From iodev list.
cras_iodev_list_add_output(struct cras_iodev * output)361 int cras_iodev_list_add_output(struct cras_iodev *output)
362 {
363   cras_iodev_list_add_output_called++;
364   return 0;
365 }
366 
cras_iodev_list_rm_output(struct cras_iodev * dev)367 int cras_iodev_list_rm_output(struct cras_iodev *dev)
368 {
369   cras_iodev_list_rm_output_called++;
370   return 0;
371 }
372 
cras_iodev_list_add_input(struct cras_iodev * output)373 int cras_iodev_list_add_input(struct cras_iodev *output)
374 {
375   cras_iodev_list_add_input_called++;
376   return 0;
377 }
378 
cras_iodev_list_rm_input(struct cras_iodev * dev)379 int cras_iodev_list_rm_input(struct cras_iodev *dev)
380 {
381   cras_iodev_list_rm_input_called++;
382   return 0;
383 }
384 
385 // From bt device
cras_bt_device_get_active_profile(const struct cras_bt_device * device)386 int cras_bt_device_get_active_profile(const struct cras_bt_device *device)
387 {
388   return cras_bt_device_get_active_profile_ret;
389 }
390 
cras_bt_device_set_active_profile(struct cras_bt_device * device,unsigned int profile)391 void cras_bt_device_set_active_profile(struct cras_bt_device *device,
392                                        unsigned int profile)
393 {
394   cras_bt_device_set_active_profile_called++;
395   cras_bt_device_set_active_profile_val = profile;
396 }
397 
cras_bt_device_has_a2dp(struct cras_bt_device * device)398 int cras_bt_device_has_a2dp(struct cras_bt_device *device)
399 {
400   return cras_bt_device_has_a2dp_ret;
401 }
402 
cras_bt_device_can_switch_to_a2dp(struct cras_bt_device * device)403 int cras_bt_device_can_switch_to_a2dp(struct cras_bt_device *device)
404 {
405   return cras_bt_device_can_switch_to_a2dp_ret;
406 }
407 
cras_bt_device_switch_profile(struct cras_bt_device * device,struct cras_iodev * bt_iodev)408 int cras_bt_device_switch_profile(struct cras_bt_device *device,
409             struct cras_iodev *bt_iodev)
410 {
411   cras_bt_device_switch_profile_called++;
412   return 0;
413 }
414 
cras_bt_device_switch_profile_enable_dev(struct cras_bt_device * device,struct cras_iodev * bt_iodev)415 int cras_bt_device_switch_profile_enable_dev(struct cras_bt_device *device,
416             struct cras_iodev *bt_iodev)
417 {
418   cras_bt_device_switch_profile_enable_dev_called++;
419   return 0;
420 }
421 
cras_bt_device_object_path(const struct cras_bt_device * device)422 const char *cras_bt_device_object_path(const struct cras_bt_device *device)
423 {
424   return "/fake/object/path";
425 }
426 
is_utf8_string(const char * string)427 int is_utf8_string(const char* string)
428 {
429   return is_utf8_string_ret_value;
430 }
431 
cras_iodev_default_no_stream_playback(struct cras_iodev * odev,int enable)432 int cras_iodev_default_no_stream_playback(struct cras_iodev *odev, int enable)
433 {
434   return 0;
435 }
436 
437 } // extern "C"
438