• 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 #include <gtest/gtest.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 
9 extern "C" {
10 #include "cras_a2dp_iodev.c"
11 
12 #include "audio_thread.h"
13 #include "audio_thread_log.h"
14 #include "cras_audio_area.h"
15 #include "cras_bt_transport.h"
16 #include "cras_iodev.h"
17 }
18 
19 #define FAKE_OBJECT_PATH "/fake/obj/path"
20 
21 #define MAX_A2DP_ENCODE_CALLS 8
22 #define MAX_A2DP_WRITE_CALLS 4
23 
24 /* Fake the codec to encode (512/4) frames into 128 bytes. */
25 #define FAKE_A2DP_CODE_SIZE 512
26 #define FAKE_A2DP_FRAME_LENGTH 128
27 
28 static struct cras_bt_transport* fake_transport;
29 static cras_audio_format format;
30 static size_t cras_bt_device_append_iodev_called;
31 static size_t cras_bt_device_rm_iodev_called;
32 static size_t cras_iodev_add_node_called;
33 static size_t cras_iodev_rm_node_called;
34 static size_t cras_iodev_set_active_node_called;
35 static size_t cras_bt_transport_acquire_called;
36 static size_t cras_bt_transport_configuration_called;
37 static size_t cras_bt_transport_release_called;
38 static size_t init_a2dp_called;
39 static int init_a2dp_return_val;
40 static size_t destroy_a2dp_called;
41 static size_t a2dp_reset_called;
42 static size_t cras_iodev_free_format_called;
43 static size_t cras_iodev_free_resources_called;
44 static int a2dp_write_return_val[MAX_A2DP_WRITE_CALLS];
45 static unsigned int a2dp_write_index;
46 static int a2dp_encode_called;
47 static cras_audio_area* mock_audio_area;
48 static thread_callback write_callback;
49 static void* write_callback_data;
50 static const char* fake_device_name = "fake device name";
51 static const char* cras_bt_device_name_ret;
52 static unsigned int cras_bt_transport_write_mtu_ret;
53 static int cras_iodev_fill_odev_zeros_called;
54 static unsigned int cras_iodev_fill_odev_zeros_frames;
55 static int audio_thread_config_events_callback_called;
56 static enum AUDIO_THREAD_EVENTS_CB_TRIGGER
57     audio_thread_config_events_callback_trigger;
58 
ResetStubData()59 void ResetStubData() {
60   cras_bt_device_append_iodev_called = 0;
61   cras_bt_device_rm_iodev_called = 0;
62   cras_iodev_add_node_called = 0;
63   cras_iodev_rm_node_called = 0;
64   cras_iodev_set_active_node_called = 0;
65   cras_bt_transport_acquire_called = 0;
66   cras_bt_transport_configuration_called = 0;
67   cras_bt_transport_release_called = 0;
68   init_a2dp_called = 0;
69   init_a2dp_return_val = 0;
70   destroy_a2dp_called = 0;
71   a2dp_reset_called = 0;
72   cras_iodev_free_format_called = 0;
73   cras_iodev_free_resources_called = 0;
74   a2dp_write_index = 0;
75   a2dp_encode_called = 0;
76   /* Fake the MTU value. min_buffer_level will be derived from this value. */
77   cras_bt_transport_write_mtu_ret = 950;
78   cras_iodev_fill_odev_zeros_called = 0;
79 
80   fake_transport = reinterpret_cast<struct cras_bt_transport*>(0x123);
81 
82   if (!mock_audio_area) {
83     mock_audio_area = (cras_audio_area*)calloc(
84         1, sizeof(*mock_audio_area) + sizeof(cras_channel_area) * 2);
85   }
86 
87   write_callback = NULL;
88 }
89 
iodev_set_format(struct cras_iodev * iodev,struct cras_audio_format * fmt)90 int iodev_set_format(struct cras_iodev* iodev, struct cras_audio_format* fmt) {
91   fmt->format = SND_PCM_FORMAT_S16_LE;
92   fmt->num_channels = 2;
93   fmt->frame_rate = 44100;
94   iodev->format = fmt;
95   return 0;
96 }
97 
98 namespace {
99 
100 static struct timespec time_now;
101 class A2dpIodev : public testing::Test {
102  protected:
SetUp()103   virtual void SetUp() {
104     ResetStubData();
105     time_now.tv_sec = 0;
106     time_now.tv_nsec = 0;
107     atlog = (audio_thread_event_log*)calloc(1, sizeof(audio_thread_event_log));
108   }
109 
TearDown()110   virtual void TearDown() {
111     free(mock_audio_area);
112     mock_audio_area = NULL;
113     free(atlog);
114   }
115 };
116 
TEST_F(A2dpIodev,InitializeA2dpIodev)117 TEST_F(A2dpIodev, InitializeA2dpIodev) {
118   struct cras_iodev* iodev;
119 
120   cras_bt_device_name_ret = NULL;
121   iodev = a2dp_iodev_create(fake_transport);
122 
123   ASSERT_NE(iodev, (void*)NULL);
124   ASSERT_EQ(iodev->direction, CRAS_STREAM_OUTPUT);
125   ASSERT_EQ(1, cras_bt_transport_configuration_called);
126   ASSERT_EQ(1, init_a2dp_called);
127   ASSERT_EQ(1, cras_bt_device_append_iodev_called);
128   ASSERT_EQ(1, cras_iodev_add_node_called);
129   ASSERT_EQ(1, cras_iodev_set_active_node_called);
130 
131   /* Assert iodev name matches the object path when bt device doesn't
132    * have its readable name populated. */
133   ASSERT_STREQ(FAKE_OBJECT_PATH, iodev->info.name);
134 
135   a2dp_iodev_destroy(iodev);
136 
137   ASSERT_EQ(1, cras_bt_device_rm_iodev_called);
138   ASSERT_EQ(1, cras_iodev_rm_node_called);
139   ASSERT_EQ(1, destroy_a2dp_called);
140   ASSERT_EQ(1, cras_iodev_free_resources_called);
141 
142   cras_bt_device_name_ret = fake_device_name;
143   /* Assert iodev name matches the bt device's name */
144   iodev = a2dp_iodev_create(fake_transport);
145   ASSERT_STREQ(fake_device_name, iodev->info.name);
146 
147   a2dp_iodev_destroy(iodev);
148 }
149 
TEST_F(A2dpIodev,InitializeFail)150 TEST_F(A2dpIodev, InitializeFail) {
151   struct cras_iodev* iodev;
152 
153   init_a2dp_return_val = -1;
154   iodev = a2dp_iodev_create(fake_transport);
155 
156   ASSERT_EQ(iodev, (void*)NULL);
157   ASSERT_EQ(1, cras_bt_transport_configuration_called);
158   ASSERT_EQ(1, init_a2dp_called);
159   ASSERT_EQ(0, cras_bt_device_append_iodev_called);
160   ASSERT_EQ(0, cras_iodev_add_node_called);
161   ASSERT_EQ(0, cras_iodev_set_active_node_called);
162   ASSERT_EQ(0, cras_iodev_rm_node_called);
163 }
164 
TEST_F(A2dpIodev,OpenIodev)165 TEST_F(A2dpIodev, OpenIodev) {
166   struct cras_iodev* iodev;
167 
168   iodev = a2dp_iodev_create(fake_transport);
169 
170   iodev_set_format(iodev, &format);
171   iodev->configure_dev(iodev);
172   iodev->start(iodev);
173   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
174 
175   ASSERT_EQ(1, cras_bt_transport_acquire_called);
176 
177   iodev->close_dev(iodev);
178   ASSERT_EQ(1, cras_bt_transport_release_called);
179   ASSERT_EQ(1, a2dp_reset_called);
180   ASSERT_EQ(1, cras_iodev_free_format_called);
181 
182   a2dp_iodev_destroy(iodev);
183 }
184 
TEST_F(A2dpIodev,GetPutBuffer)185 TEST_F(A2dpIodev, GetPutBuffer) {
186   struct cras_iodev* iodev;
187   struct cras_audio_area *area1, *area2, *area3;
188   uint8_t* last_buf_head;
189   unsigned frames;
190   struct timespec tstamp;
191   struct a2dp_io* a2dpio;
192 
193   iodev = a2dp_iodev_create(fake_transport);
194   a2dpio = (struct a2dp_io*)iodev;
195 
196   iodev_set_format(iodev, &format);
197   iodev->configure_dev(iodev);
198   ASSERT_NE(write_callback, (void*)NULL);
199 
200   iodev->start(iodev);
201   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
202 
203   /* (950 - 13) / 128 * 512 / 4 */
204   ASSERT_EQ(iodev->min_buffer_level, 896);
205 
206   frames = 1500;
207   iodev->get_buffer(iodev, &area1, &frames);
208   ASSERT_EQ(1500, frames);
209   ASSERT_EQ(1500, area1->frames);
210   last_buf_head = area1->channels[0].buf;
211   iodev->put_buffer(iodev, 1000);
212   /* 1000 frames takes 8 encode call, FAKE_A2DP_CODE_SIZE / 4 = 128
213    * and 7 * 128 < 1000 < 8 * 128
214    */
215   EXPECT_EQ(8, a2dp_encode_called);
216   /* Expect flushed one block, leaving 1000 - 896 = 104 queued and
217    * next_flush_time has shifted. */
218   EXPECT_EQ(1, a2dp_write_index);
219   EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
220   EXPECT_GT(a2dpio->next_flush_time.tv_nsec, 0);
221 
222   /* Assert buffer possition shifted 1000 * 4 bytes */
223   frames = 1000;
224   iodev->get_buffer(iodev, &area2, &frames);
225   ASSERT_EQ(1000, frames);
226   ASSERT_EQ(1000, area2->frames);
227   ASSERT_EQ(4000, area2->channels[0].buf - last_buf_head);
228   last_buf_head = area2->channels[0].buf;
229 
230   iodev->put_buffer(iodev, 700);
231   EXPECT_EQ(804, iodev->frames_queued(iodev, &tstamp));
232   /* Assert that even next_flush_time is not met, pcm data still processed.
233    * Expect to takes 7 more encode calls to process the 804 frames of data.
234    * and 6 * 128 < 804 < 7 * 128
235    */
236   EXPECT_EQ(15, a2dp_encode_called);
237   EXPECT_EQ(768, a2dpio->a2dp.samples);
238 
239   time_now.tv_nsec = 25000000;
240   frames = 50;
241   iodev->get_buffer(iodev, &area3, &frames);
242   ASSERT_EQ(50, frames);
243   /* Assert buffer possition shifted 700 * 4 bytes */
244   EXPECT_EQ(2800, area3->channels[0].buf - last_buf_head);
245 
246   iodev->put_buffer(iodev, 50);
247   /* 804 + 50 = 854 queued, 768 of them are encoded. */
248   EXPECT_EQ(854, iodev->frames_queued(iodev, &tstamp));
249   EXPECT_EQ(768, a2dpio->a2dp.samples);
250   /* Expect one a2dp encode call was executed for the left un-encoded frames.
251    * 854 - 768 = 86 < 128 */
252   EXPECT_EQ(16, a2dp_encode_called);
253   /* Even time now has passed next_flush_time, no a2dp write gets called
254    * because the number of encoded samples is not sufficient for a flush. */
255   EXPECT_EQ(1, a2dp_write_index);
256 
257   iodev->close_dev(iodev);
258   a2dp_iodev_destroy(iodev);
259 }
260 
TEST_F(A2dpIodev,FramesQueued)261 TEST_F(A2dpIodev, FramesQueued) {
262   struct cras_iodev* iodev;
263   struct cras_audio_area* area;
264   struct timespec tstamp;
265   unsigned frames;
266   struct a2dp_io* a2dpio;
267 
268   iodev = a2dp_iodev_create(fake_transport);
269   a2dpio = (struct a2dp_io*)iodev;
270 
271   iodev_set_format(iodev, &format);
272   time_now.tv_sec = 0;
273   time_now.tv_nsec = 0;
274   iodev->configure_dev(iodev);
275   ASSERT_NE(write_callback, (void*)NULL);
276   /* a2dp_block_size(mtu) / format_bytes
277    * (950 - 13) / 128 * 512 / 4 = 896 */
278   EXPECT_EQ(896, a2dpio->write_block);
279 
280   iodev->start(iodev);
281   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
282 
283   frames = 256;
284   iodev->get_buffer(iodev, &area, &frames);
285   ASSERT_EQ(256, frames);
286   ASSERT_EQ(256, area->frames);
287 
288   /* Data less than write_block hence not written. */
289   iodev->put_buffer(iodev, 200);
290   EXPECT_EQ(200, iodev->frames_queued(iodev, &tstamp));
291   EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
292   EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
293 
294   /* 200 + 800 - 896 = 104 */
295   a2dp_write_return_val[0] = 0;
296   frames = 800;
297   iodev->get_buffer(iodev, &area, &frames);
298   iodev->put_buffer(iodev, 800);
299   EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
300 
301   /* Some time has passed, same amount of frames are queued. */
302   time_now.tv_nsec = 15000000;
303   write_callback(write_callback_data, POLLOUT);
304   EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
305 
306   /* Put 900 more frames. next_flush_time not yet passed so expect
307    * total 900 + 104 = 1004 are queued. */
308   frames = 900;
309   iodev->get_buffer(iodev, &area, &frames);
310   iodev->put_buffer(iodev, 900);
311   EXPECT_EQ(1004, iodev->frames_queued(iodev, &tstamp));
312 
313   /* Time passes next_flush_time, 1004 + 300 - 896 = 408 */
314   time_now.tv_nsec = 25000000;
315   frames = 300;
316   iodev->get_buffer(iodev, &area, &frames);
317   iodev->put_buffer(iodev, 300);
318   EXPECT_EQ(408, iodev->frames_queued(iodev, &tstamp));
319 
320   iodev->close_dev(iodev);
321   a2dp_iodev_destroy(iodev);
322 }
323 
TEST_F(A2dpIodev,SleepTimeWithWriteThrottle)324 TEST_F(A2dpIodev, SleepTimeWithWriteThrottle) {
325   struct cras_iodev* iodev;
326   struct cras_audio_area* area;
327   unsigned frames;
328   unsigned int level;
329   unsigned long target;
330   struct timespec tstamp;
331   struct a2dp_io* a2dpio;
332 
333   iodev = a2dp_iodev_create(fake_transport);
334   a2dpio = (struct a2dp_io*)iodev;
335 
336   iodev_set_format(iodev, &format);
337   iodev->configure_dev(iodev);
338   ASSERT_NE(write_callback, (void*)NULL);
339   /* a2dp_block_size(mtu) / format_bytes
340    * 900 / 128 * 512 / 4 = 896 */
341   EXPECT_EQ(896, a2dpio->write_block);
342 
343   iodev->start(iodev);
344   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
345 
346   /* Both time now and next_flush_time are at 0. Expect write_block of
347    * time to sleep */
348   EXPECT_EQ(a2dpio->write_block,
349             iodev->frames_to_play_in_sleep(iodev, &level, &tstamp));
350 
351   /* Fake that 1000 frames are put and one block got flushed.
352    * Expect next_wake_time be fast forward by one flush_period. */
353   frames = 1000;
354   iodev->get_buffer(iodev, &area, &frames);
355   ASSERT_EQ(1000, frames);
356   ASSERT_EQ(1000, area->frames);
357 
358   /* Expect the first block be flushed at time 0. */
359   time_now.tv_nsec = 0;
360   a2dp_write_return_val[0] = 0;
361   EXPECT_EQ(0, iodev->put_buffer(iodev, 1000));
362   EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp)); /* 1000 - 896 */
363 
364   /* Same amount of frames are queued after some time has passed. */
365   time_now.tv_nsec = 10000000;
366   EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
367 
368   /* Expect to sleep the time between now(10ms) and next_flush_time(~20.3ms). */
369   frames = iodev->frames_to_play_in_sleep(iodev, &level, &tstamp);
370   target =
371       a2dpio->write_block - time_now.tv_nsec * format.frame_rate / 1000000000;
372   EXPECT_GE(frames + 1, target);
373   EXPECT_GE(target + 1, frames);
374 
375   /* Time now has passed the next flush time(~20.3ms), expect to return
376    * write_block of time to sleep. */
377   time_now.tv_nsec = 25000000;
378   EXPECT_EQ(a2dpio->write_block,
379             iodev->frames_to_play_in_sleep(iodev, &level, &tstamp));
380 
381   a2dp_write_return_val[1] = 0;
382   frames = 1000;
383   iodev->get_buffer(iodev, &area, &frames);
384   EXPECT_EQ(0, iodev->put_buffer(iodev, 1000));
385   EXPECT_EQ(208, iodev->frames_queued(iodev, &tstamp)); /* 104 + 1000 - 896 */
386 
387   /* Flush another write_block of data, next_wake_time fast forward by
388    * another flush_period. Expect to sleep the time between now(25ms)
389    * and next_flush_time(~40.6ms). */
390   frames = iodev->frames_to_play_in_sleep(iodev, &level, &tstamp);
391   target = a2dpio->write_block * 2 -
392            time_now.tv_nsec * format.frame_rate / 1000000000;
393   EXPECT_GE(frames + 1, target);
394   EXPECT_GE(target + 1, frames);
395 
396   /* Put 1000 more frames, and make a fake failure to this flush. */
397   time_now.tv_nsec = 45000000;
398   a2dp_write_return_val[2] = -EAGAIN;
399   frames = 1000;
400   iodev->get_buffer(iodev, &area, &frames);
401   EXPECT_EQ(0, iodev->put_buffer(iodev, 1000));
402 
403   /* Last a2dp write call failed with -EAGAIN, time now(45ms) is after
404    * next_flush_time. Expect to return exact |write_block| equivalant
405    * of time to sleep. */
406   EXPECT_EQ(1208, iodev->frames_queued(iodev, &tstamp)); /* 208 + 1000 */
407   EXPECT_EQ(a2dpio->write_block,
408             iodev->frames_to_play_in_sleep(iodev, &level, &tstamp));
409 
410   /* Fake the event that socket becomes writable so data continues to flush.
411    * next_flush_time fast forwards by another flush_period. */
412   a2dp_write_return_val[3] = 0;
413   write_callback(write_callback_data, POLLOUT);
414   EXPECT_EQ(312, iodev->frames_queued(iodev, &tstamp)); /* 1208 - 896 */
415 
416   /* Expect to sleep the time between now and next_flush_time(~60.9ms). */
417   frames = iodev->frames_to_play_in_sleep(iodev, &level, &tstamp);
418   target = a2dpio->write_block * 3 -
419            time_now.tv_nsec * format.frame_rate / 1000000000;
420   EXPECT_GE(frames + 1, target);
421   EXPECT_GE(target + 1, frames);
422 
423   iodev->close_dev(iodev);
424   a2dp_iodev_destroy(iodev);
425 }
426 
TEST_F(A2dpIodev,EnableThreadCallbackAtBufferFull)427 TEST_F(A2dpIodev, EnableThreadCallbackAtBufferFull) {
428   struct cras_iodev* iodev;
429   struct cras_audio_area* area;
430   struct timespec tstamp;
431   unsigned frames;
432   struct a2dp_io* a2dpio;
433 
434   iodev = a2dp_iodev_create(fake_transport);
435   a2dpio = (struct a2dp_io*)iodev;
436 
437   iodev_set_format(iodev, &format);
438   time_now.tv_sec = 0;
439   time_now.tv_nsec = 0;
440   iodev->configure_dev(iodev);
441   ASSERT_NE(write_callback, (void*)NULL);
442 
443   iodev->start(iodev);
444   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
445 
446   audio_thread_config_events_callback_called = 0;
447   a2dp_write_return_val[0] = 0;
448   frames = iodev->buffer_size;
449   iodev->get_buffer(iodev, &area, &frames);
450   EXPECT_LE(frames, iodev->buffer_size);
451   EXPECT_EQ(0, iodev->put_buffer(iodev, frames));
452   EXPECT_EQ(1, a2dp_write_index);
453   EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
454   EXPECT_EQ(1, audio_thread_config_events_callback_called);
455   EXPECT_EQ(TRIGGER_NONE, audio_thread_config_events_callback_trigger);
456 
457   /* Fastfoward time 1ms, not yet reaches the next flush time. */
458   time_now.tv_nsec = 1000000;
459 
460   /* Cram into iodev as much data as possible. Expect its buffer to
461    * be full because flush time does not yet met. */
462   frames = iodev->buffer_size;
463   iodev->get_buffer(iodev, &area, &frames);
464   EXPECT_LE(frames, iodev->buffer_size);
465   EXPECT_EQ(0, iodev->put_buffer(iodev, frames));
466   frames = iodev->frames_queued(iodev, &tstamp);
467   EXPECT_EQ(frames, iodev->buffer_size);
468 
469   /* Expect a2dp_write didn't get called in last get/put buffer. And
470    * audio thread callback has been enabled. */
471   EXPECT_EQ(1, a2dp_write_index);
472   EXPECT_EQ(2, audio_thread_config_events_callback_called);
473   EXPECT_EQ(TRIGGER_WAKEUP, audio_thread_config_events_callback_trigger);
474 
475   iodev->close_dev(iodev);
476   a2dp_iodev_destroy(iodev);
477 }
478 
TEST_F(A2dpIodev,FlushAtLowBufferLevel)479 TEST_F(A2dpIodev, FlushAtLowBufferLevel) {
480   struct cras_iodev* iodev;
481   struct cras_audio_area* area;
482   struct timespec tstamp;
483   unsigned frames;
484 
485   iodev = a2dp_iodev_create(fake_transport);
486 
487   iodev_set_format(iodev, &format);
488   iodev->configure_dev(iodev);
489   ASSERT_NE(write_callback, (void*)NULL);
490 
491   /* (950 - 13)/ 128 * 512 / 4 */
492   ASSERT_EQ(iodev->min_buffer_level, 896);
493 
494   iodev->start(iodev);
495   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
496 
497   frames = 1500;
498   iodev->get_buffer(iodev, &area, &frames);
499   ASSERT_EQ(1500, frames);
500   ASSERT_EQ(1500, area->frames);
501 
502   /*
503    * Assert put_buffer shouldn't trigger the 2nd call to a2dp_encode()
504    * because buffer is low: 896 < 1500 < 896 * 2
505    */
506   a2dp_write_return_val[0] = 0;
507   EXPECT_EQ(0, iodev->put_buffer(iodev, 1500));
508   EXPECT_EQ(1, a2dp_write_index);
509 
510   /* 1500 - 896 */
511   time_now.tv_nsec = 25000000;
512   EXPECT_EQ(604, iodev->frames_queued(iodev, &tstamp));
513   EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
514   EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
515   iodev->close_dev(iodev);
516   a2dp_iodev_destroy(iodev);
517 }
518 
TEST_F(A2dpIodev,HandleUnderrun)519 TEST_F(A2dpIodev, HandleUnderrun) {
520   struct cras_iodev* iodev;
521   struct cras_audio_area* area;
522   struct timespec tstamp;
523   unsigned frames;
524 
525   iodev = a2dp_iodev_create(fake_transport);
526 
527   iodev_set_format(iodev, &format);
528   time_now.tv_sec = 0;
529   time_now.tv_nsec = 0;
530   iodev->configure_dev(iodev);
531   /* (950 - 13) / 128 * 512 / 4 */
532   EXPECT_EQ(896, iodev->min_buffer_level);
533 
534   iodev->start(iodev);
535   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
536 
537   frames = 300;
538   iodev->get_buffer(iodev, &area, &frames);
539   ASSERT_EQ(300, frames);
540   ASSERT_EQ(300, area->frames);
541   a2dp_write_return_val[0] = -EAGAIN;
542 
543   time_now.tv_nsec = 10000000;
544   iodev->put_buffer(iodev, 300);
545 
546   time_now.tv_nsec = 20000000;
547   EXPECT_EQ(300, iodev->frames_queued(iodev, &tstamp));
548 
549   /* Frames queued below min_buffer_level, which is derived from transport MTU.
550    * Assert min_cb_level of zero frames are filled. */
551   iodev->min_cb_level = 150;
552   iodev->output_underrun(iodev);
553   ASSERT_EQ(1, cras_iodev_fill_odev_zeros_called);
554   EXPECT_EQ(150, cras_iodev_fill_odev_zeros_frames);
555 
556   iodev->close_dev(iodev);
557   a2dp_iodev_destroy(iodev);
558 }
559 
TEST_F(A2dpIodev,LeavingNoStreamStateWithSmallStreamDoesntUnderrun)560 TEST_F(A2dpIodev, LeavingNoStreamStateWithSmallStreamDoesntUnderrun) {
561   struct cras_iodev* iodev;
562   struct cras_audio_area* area;
563   struct timespec tstamp;
564   unsigned frames;
565   struct a2dp_io* a2dpio;
566 
567   iodev = a2dp_iodev_create(fake_transport);
568   a2dpio = (struct a2dp_io*)iodev;
569 
570   iodev_set_format(iodev, &format);
571   time_now.tv_sec = 0;
572   time_now.tv_nsec = 0;
573   iodev->configure_dev(iodev);
574   ASSERT_NE(write_callback, (void*)NULL);
575   /* (950 - 13)/ 128 * 512 / 4 */
576   ASSERT_EQ(896, iodev->min_buffer_level);
577 
578   iodev->start(iodev);
579   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
580 
581   /* Put iodev in no_stream state. Verify it doesn't underrun after each
582    * call of no_stream ops. */
583   a2dp_write_return_val[0] = 0;
584   iodev->no_stream(iodev, 1);
585   EXPECT_EQ(1, a2dp_write_index);
586   EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
587   frames = iodev->frames_queued(iodev, &tstamp);
588   EXPECT_LE(iodev->min_buffer_level, frames);
589 
590   /* Some time has passed and a small stream of 200 frames block is added.
591    * Verify leaving no_stream state doesn't underrun immediately. */
592   time_now.tv_nsec = 20000000;
593   iodev->no_stream(iodev, 1);
594   frames = 200;
595   iodev->get_buffer(iodev, &area, &frames);
596   iodev->put_buffer(iodev, 200);
597   frames = iodev->frames_queued(iodev, &tstamp);
598   EXPECT_LE(iodev->min_buffer_level, frames);
599 
600   iodev->close_dev(iodev);
601   a2dp_iodev_destroy(iodev);
602 }
603 
TEST_F(A2dpIodev,NoStreamStateFillZerosToTargetLevel)604 TEST_F(A2dpIodev, NoStreamStateFillZerosToTargetLevel) {
605   struct cras_iodev* iodev;
606   struct cras_audio_area* area;
607   struct timespec tstamp;
608   unsigned frames;
609   struct a2dp_io* a2dpio;
610 
611   iodev = a2dp_iodev_create(fake_transport);
612   a2dpio = (struct a2dp_io*)iodev;
613 
614   iodev_set_format(iodev, &format);
615   time_now.tv_sec = 0;
616   time_now.tv_nsec = 0;
617   iodev->configure_dev(iodev);
618   ASSERT_NE(write_callback, (void*)NULL);
619   /* (950 - 13)/ 128 * 512 / 4 */
620   ASSERT_EQ(896, iodev->min_buffer_level);
621 
622   iodev->start(iodev);
623   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
624 
625   iodev->min_cb_level = 480;
626   frames = 200;
627   iodev->get_buffer(iodev, &area, &frames);
628   iodev->put_buffer(iodev, 200);
629 
630   a2dp_write_return_val[0] = 0;
631   iodev->no_stream(iodev, 1);
632   EXPECT_EQ(1, a2dp_write_index);
633   EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
634 
635   /* Some time has passed but not yet reach next flush. Entering no_stream
636    * fills buffer to 3 times of min_buffer_level. */
637   time_now.tv_nsec = 10000000;
638   iodev->no_stream(iodev, 1);
639   frames = iodev->frames_queued(iodev, &tstamp);
640   EXPECT_EQ(3 * iodev->min_buffer_level, frames);
641 
642   /* Time has passed next flush time, expect one block is flushed.  */
643   a2dp_write_return_val[1] = 0;
644   time_now.tv_nsec = 25000000;
645   iodev->no_stream(iodev, 1);
646   frames = iodev->frames_queued(iodev, &tstamp);
647   ASSERT_EQ(2 * iodev->min_buffer_level, frames);
648   EXPECT_EQ(2, a2dp_write_index);
649 
650   /* Leaving no_stream state fills buffer level back to  2 * min_buffer_level.
651    */
652   a2dp_write_return_val[2] = 0;
653   time_now.tv_nsec = 30000000;
654   iodev->no_stream(iodev, 0);
655   frames = iodev->frames_queued(iodev, &tstamp);
656   ASSERT_EQ(2 * iodev->min_buffer_level, frames);
657   EXPECT_EQ(2, a2dp_write_index);
658 
659   iodev->close_dev(iodev);
660   a2dp_iodev_destroy(iodev);
661 }
662 
TEST_F(A2dpIodev,EnterNoStreamStateAtHighBufferLevelDoesntFillMore)663 TEST_F(A2dpIodev, EnterNoStreamStateAtHighBufferLevelDoesntFillMore) {
664   struct cras_iodev* iodev;
665   struct cras_audio_area* area;
666   struct timespec tstamp;
667   unsigned frames, start_level;
668   struct a2dp_io* a2dpio;
669 
670   iodev = a2dp_iodev_create(fake_transport);
671   a2dpio = (struct a2dp_io*)iodev;
672 
673   iodev_set_format(iodev, &format);
674   time_now.tv_sec = 0;
675   time_now.tv_nsec = 0;
676   iodev->configure_dev(iodev);
677   ASSERT_NE(write_callback, (void*)NULL);
678   /* (950 - 13)/ 128 * 512 / 4 */
679   ASSERT_EQ(896, iodev->min_buffer_level);
680 
681   iodev->start(iodev);
682   iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
683 
684   a2dp_write_return_val[0] = 0;
685   start_level = 6000;
686   frames = start_level;
687   iodev->get_buffer(iodev, &area, &frames);
688   iodev->put_buffer(iodev, frames);
689   frames = iodev->frames_queued(iodev, &tstamp);
690   /* Assert one block has fluxhed */
691   EXPECT_EQ(start_level - iodev->min_buffer_level, frames);
692   EXPECT_EQ(1, a2dp_write_index);
693   EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
694 
695   a2dp_write_return_val[1] = 0;
696   time_now.tv_nsec = 25000000;
697   iodev->no_stream(iodev, 1);
698   frames = iodev->frames_queued(iodev, &tstamp);
699   /* Next flush time meets requirement so another block is flushed. */
700   ASSERT_EQ(start_level - 2 * iodev->min_buffer_level, frames);
701 
702   a2dp_write_return_val[2] = 0;
703   time_now.tv_nsec = 50000000;
704   iodev->no_stream(iodev, 1);
705   frames = iodev->frames_queued(iodev, &tstamp);
706   /* Another block flushed at leaving no stream state. No more data
707    * filled because level is high. */
708   ASSERT_EQ(start_level - 3 * iodev->min_buffer_level, frames);
709 
710   iodev->close_dev(iodev);
711   a2dp_iodev_destroy(iodev);
712 }
713 }  // namespace
714 
main(int argc,char ** argv)715 int main(int argc, char** argv) {
716   ::testing::InitGoogleTest(&argc, argv);
717   return RUN_ALL_TESTS();
718 }
719 
720 extern "C" {
721 
cras_bt_transport_configuration(const struct cras_bt_transport * transport,void * configuration,int len)722 int cras_bt_transport_configuration(const struct cras_bt_transport* transport,
723                                     void* configuration,
724                                     int len) {
725   memset(configuration, 0, len);
726   cras_bt_transport_configuration_called++;
727   return 0;
728 }
729 
cras_bt_transport_acquire(struct cras_bt_transport * transport)730 int cras_bt_transport_acquire(struct cras_bt_transport* transport) {
731   cras_bt_transport_acquire_called++;
732   return 0;
733 }
734 
cras_bt_transport_release(struct cras_bt_transport * transport,unsigned int blocking)735 int cras_bt_transport_release(struct cras_bt_transport* transport,
736                               unsigned int blocking) {
737   cras_bt_transport_release_called++;
738   return 0;
739 }
740 
cras_bt_transport_fd(const struct cras_bt_transport * transport)741 int cras_bt_transport_fd(const struct cras_bt_transport* transport) {
742   return 0;
743 }
744 
cras_bt_transport_object_path(const struct cras_bt_transport * transport)745 const char* cras_bt_transport_object_path(
746     const struct cras_bt_transport* transport) {
747   return FAKE_OBJECT_PATH;
748 }
749 
cras_bt_transport_write_mtu(const struct cras_bt_transport * transport)750 uint16_t cras_bt_transport_write_mtu(
751     const struct cras_bt_transport* transport) {
752   return cras_bt_transport_write_mtu_ret;
753 }
754 
cras_bt_transport_set_volume(struct cras_bt_transport * transport,uint16_t volume)755 int cras_bt_transport_set_volume(struct cras_bt_transport* transport,
756                                  uint16_t volume) {
757   return 0;
758 }
759 
cras_iodev_free_format(struct cras_iodev * iodev)760 void cras_iodev_free_format(struct cras_iodev* iodev) {
761   cras_iodev_free_format_called++;
762 }
763 
cras_iodev_free_resources(struct cras_iodev * iodev)764 void cras_iodev_free_resources(struct cras_iodev* iodev) {
765   cras_iodev_free_resources_called++;
766 }
767 
768 // Cras iodev
cras_iodev_add_node(struct cras_iodev * iodev,struct cras_ionode * node)769 void cras_iodev_add_node(struct cras_iodev* iodev, struct cras_ionode* node) {
770   cras_iodev_add_node_called++;
771   iodev->nodes = node;
772 }
773 
cras_iodev_rm_node(struct cras_iodev * iodev,struct cras_ionode * node)774 void cras_iodev_rm_node(struct cras_iodev* iodev, struct cras_ionode* node) {
775   cras_iodev_rm_node_called++;
776   iodev->nodes = NULL;
777 }
778 
cras_iodev_set_active_node(struct cras_iodev * iodev,struct cras_ionode * node)779 void cras_iodev_set_active_node(struct cras_iodev* iodev,
780                                 struct cras_ionode* node) {
781   cras_iodev_set_active_node_called++;
782   iodev->active_node = node;
783 }
784 
785 // From cras_bt_transport
cras_bt_transport_device(const struct cras_bt_transport * transport)786 struct cras_bt_device* cras_bt_transport_device(
787     const struct cras_bt_transport* transport) {
788   return reinterpret_cast<struct cras_bt_device*>(0x456);
789   ;
790 }
791 
cras_bt_transport_profile(const struct cras_bt_transport * transport)792 enum cras_bt_device_profile cras_bt_transport_profile(
793     const struct cras_bt_transport* transport) {
794   return CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
795 }
796 
797 // From cras_bt_device
cras_bt_device_name(const struct cras_bt_device * device)798 const char* cras_bt_device_name(const struct cras_bt_device* device) {
799   return cras_bt_device_name_ret;
800 }
801 
cras_bt_device_object_path(const struct cras_bt_device * device)802 const char* cras_bt_device_object_path(const struct cras_bt_device* device) {
803   return "/org/bluez/hci0/dev_1A_2B_3C_4D_5E_6F";
804 }
805 
cras_bt_device_get_stable_id(const struct cras_bt_device * device)806 int cras_bt_device_get_stable_id(const struct cras_bt_device* device) {
807   return 123;
808 }
809 
cras_bt_device_append_iodev(struct cras_bt_device * device,struct cras_iodev * iodev,enum cras_bt_device_profile profile)810 void cras_bt_device_append_iodev(struct cras_bt_device* device,
811                                  struct cras_iodev* iodev,
812                                  enum cras_bt_device_profile profile) {
813   cras_bt_device_append_iodev_called++;
814 }
815 
cras_bt_device_rm_iodev(struct cras_bt_device * device,struct cras_iodev * iodev)816 void cras_bt_device_rm_iodev(struct cras_bt_device* device,
817                              struct cras_iodev* iodev) {
818   cras_bt_device_rm_iodev_called++;
819 }
820 
cras_bt_device_get_use_hardware_volume(struct cras_bt_device * device)821 int cras_bt_device_get_use_hardware_volume(struct cras_bt_device* device) {
822   return 0;
823 }
824 
cras_bt_device_cancel_suspend(struct cras_bt_device * device)825 int cras_bt_device_cancel_suspend(struct cras_bt_device* device) {
826   return 0;
827 }
828 
cras_bt_device_schedule_suspend(struct cras_bt_device * device,unsigned int msec,enum cras_bt_device_suspend_reason suspend_reason)829 int cras_bt_device_schedule_suspend(
830     struct cras_bt_device* device,
831     unsigned int msec,
832     enum cras_bt_device_suspend_reason suspend_reason) {
833   return 0;
834 }
835 
init_a2dp(struct a2dp_info * a2dp,a2dp_sbc_t * sbc)836 int init_a2dp(struct a2dp_info* a2dp, a2dp_sbc_t* sbc) {
837   init_a2dp_called++;
838   memset(a2dp, 0, sizeof(*a2dp));
839   a2dp->frame_length = FAKE_A2DP_FRAME_LENGTH;
840   a2dp->codesize = FAKE_A2DP_CODE_SIZE;
841   return init_a2dp_return_val;
842 }
843 
destroy_a2dp(struct a2dp_info * a2dp)844 void destroy_a2dp(struct a2dp_info* a2dp) {
845   destroy_a2dp_called++;
846 }
847 
a2dp_codesize(struct a2dp_info * a2dp)848 int a2dp_codesize(struct a2dp_info* a2dp) {
849   return a2dp->codesize;
850 }
851 
a2dp_block_size(struct a2dp_info * a2dp,int encoded_bytes)852 int a2dp_block_size(struct a2dp_info* a2dp, int encoded_bytes) {
853   return encoded_bytes / a2dp->frame_length * a2dp->codesize;
854 }
855 
a2dp_queued_frames(const struct a2dp_info * a2dp)856 int a2dp_queued_frames(const struct a2dp_info* a2dp) {
857   return a2dp->samples;
858 }
859 
a2dp_reset(struct a2dp_info * a2dp)860 void a2dp_reset(struct a2dp_info* a2dp) {
861   a2dp_reset_called++;
862   a2dp->samples = 0;
863 }
864 
a2dp_encode(struct a2dp_info * a2dp,const void * pcm_buf,int pcm_buf_size,int format_bytes,size_t link_mtu)865 int a2dp_encode(struct a2dp_info* a2dp,
866                 const void* pcm_buf,
867                 int pcm_buf_size,
868                 int format_bytes,
869                 size_t link_mtu) {
870   int processed = 0;
871   a2dp_encode_called++;
872 
873   if (a2dp->a2dp_buf_used + a2dp->frame_length > link_mtu)
874     return 0;
875   if (pcm_buf_size < a2dp->codesize)
876     return 0;
877 
878   processed += a2dp->codesize;
879   a2dp->a2dp_buf_used += a2dp->frame_length;
880   a2dp->samples += processed / format_bytes;
881 
882   return processed;
883 }
884 
a2dp_write(struct a2dp_info * a2dp,int stream_fd,size_t link_mtu)885 int a2dp_write(struct a2dp_info* a2dp, int stream_fd, size_t link_mtu) {
886   int ret, samples;
887   if (a2dp->frame_length + a2dp->a2dp_buf_used < link_mtu)
888     return 0;
889 
890   ret = a2dp_write_return_val[a2dp_write_index++];
891   if (ret < 0)
892     return ret;
893 
894   samples = a2dp->samples;
895   a2dp->samples = 0;
896   a2dp->a2dp_buf_used = 0;
897   return samples;
898 }
899 
clock_gettime(clockid_t clk_id,struct timespec * tp)900 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
901   *tp = time_now;
902   return 0;
903 }
904 
cras_iodev_init_audio_area(struct cras_iodev * iodev,int num_channels)905 void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {
906   iodev->area = mock_audio_area;
907 }
908 
cras_iodev_free_audio_area(struct cras_iodev * iodev)909 void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
910 
cras_iodev_fill_odev_zeros(struct cras_iodev * odev,unsigned int frames)911 int cras_iodev_fill_odev_zeros(struct cras_iodev* odev, unsigned int frames) {
912   struct cras_audio_area* area;
913   cras_iodev_fill_odev_zeros_called++;
914   cras_iodev_fill_odev_zeros_frames = frames;
915 
916   odev->get_buffer(odev, &area, &frames);
917   odev->put_buffer(odev, frames);
918   return 0;
919 }
920 
cras_audio_area_config_buf_pointers(struct cras_audio_area * area,const struct cras_audio_format * fmt,uint8_t * base_buffer)921 void cras_audio_area_config_buf_pointers(struct cras_audio_area* area,
922                                          const struct cras_audio_format* fmt,
923                                          uint8_t* base_buffer) {
924   mock_audio_area->channels[0].buf = base_buffer;
925 }
926 
cras_iodev_list_get_audio_thread()927 struct audio_thread* cras_iodev_list_get_audio_thread() {
928   return NULL;
929 }
930 // From ewma_power
ewma_power_disable(struct ewma_power * ewma)931 void ewma_power_disable(struct ewma_power* ewma) {}
932 
933 // From audio_thread
934 struct audio_thread_event_log* atlog;
935 
audio_thread_add_events_callback(int fd,thread_callback cb,void * data,int events)936 void audio_thread_add_events_callback(int fd,
937                                       thread_callback cb,
938                                       void* data,
939                                       int events) {
940   write_callback = cb;
941   write_callback_data = data;
942 }
943 
audio_thread_rm_callback_sync(struct audio_thread * thread,int fd)944 int audio_thread_rm_callback_sync(struct audio_thread* thread, int fd) {
945   return 0;
946 }
947 
audio_thread_config_events_callback(int fd,enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger)948 void audio_thread_config_events_callback(
949     int fd,
950     enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger) {
951   audio_thread_config_events_callback_called++;
952   audio_thread_config_events_callback_trigger = trigger;
953 }
954 }
955 
cras_audio_thread_event_a2dp_overrun()956 int cras_audio_thread_event_a2dp_overrun() {
957   return 0;
958 }
959 
cras_audio_thread_event_a2dp_throttle()960 int cras_audio_thread_event_a2dp_throttle() {
961   return 0;
962 }
963