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