• 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 
11 #include "a2dp-codecs.h"
12 #include "audio_thread.h"
13 #include "audio_thread_log.h"
14 #include "cras_a2dp_iodev.h"
15 #include "cras_audio_area.h"
16 #include "cras_bt_transport.h"
17 #include "cras_iodev.h"
18 }
19 
20 #define FAKE_OBJECT_PATH "/fake/obj/path"
21 
22 #define MAX_A2DP_ENCODE_CALLS 8
23 #define MAX_A2DP_WRITE_CALLS 4
24 
25 static struct cras_bt_transport* fake_transport;
26 static cras_audio_format format;
27 static size_t cras_bt_device_append_iodev_called;
28 static size_t cras_bt_device_rm_iodev_called;
29 static size_t cras_iodev_add_node_called;
30 static int cras_iodev_frames_queued_called;
31 static size_t cras_iodev_rm_node_called;
32 static size_t cras_iodev_set_active_node_called;
33 static size_t cras_bt_transport_acquire_called;
34 static size_t cras_bt_transport_configuration_called;
35 static size_t cras_bt_transport_release_called;
36 static size_t init_a2dp_called;
37 static int init_a2dp_return_val;
38 static size_t destroy_a2dp_called;
39 static size_t drain_a2dp_called;
40 static size_t a2dp_block_size_called;
41 static size_t a2dp_queued_frames_val;
42 static size_t cras_iodev_free_format_called;
43 static size_t cras_iodev_free_resources_called;
44 static int pcm_buf_size_val[MAX_A2DP_ENCODE_CALLS];
45 static unsigned int a2dp_encode_processed_bytes_val[MAX_A2DP_ENCODE_CALLS];
46 static unsigned int a2dp_encode_index;
47 static int a2dp_write_return_val[MAX_A2DP_WRITE_CALLS];
48 static unsigned int a2dp_write_index;
49 static cras_audio_area* dummy_audio_area;
50 static thread_callback write_callback;
51 static void* write_callback_data;
52 static const char* fake_device_name = "fake device name";
53 static const char* cras_bt_device_name_ret;
54 static unsigned int cras_bt_transport_write_mtu_ret;
55 
ResetStubData()56 void ResetStubData() {
57   cras_bt_device_append_iodev_called = 0;
58   cras_bt_device_rm_iodev_called = 0;
59   cras_iodev_add_node_called = 0;
60   cras_iodev_frames_queued_called = 0;
61   cras_iodev_rm_node_called = 0;
62   cras_iodev_set_active_node_called = 0;
63   cras_bt_transport_acquire_called = 0;
64   cras_bt_transport_configuration_called = 0;
65   cras_bt_transport_release_called = 0;
66   init_a2dp_called = 0;
67   init_a2dp_return_val = 0;
68   destroy_a2dp_called = 0;
69   drain_a2dp_called = 0;
70   a2dp_block_size_called = 0;
71   a2dp_queued_frames_val = 0;
72   cras_iodev_free_format_called = 0;
73   cras_iodev_free_resources_called = 0;
74   memset(a2dp_encode_processed_bytes_val, 0,
75          sizeof(a2dp_encode_processed_bytes_val));
76   a2dp_encode_index = 0;
77   a2dp_write_index = 0;
78   cras_bt_transport_write_mtu_ret = 800;
79 
80   fake_transport = reinterpret_cast<struct cras_bt_transport*>(0x123);
81 
82   if (!dummy_audio_area) {
83     dummy_audio_area = (cras_audio_area*)calloc(
84         1, sizeof(*dummy_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     atlog = (audio_thread_event_log*)calloc(1, sizeof(audio_thread_event_log));
106   }
107 
TearDown()108   virtual void TearDown() {
109     free(dummy_audio_area);
110     dummy_audio_area = NULL;
111     free(atlog);
112   }
113 };
114 
TEST_F(A2dpIodev,InitializeA2dpIodev)115 TEST_F(A2dpIodev, InitializeA2dpIodev) {
116   struct cras_iodev* iodev;
117 
118   cras_bt_device_name_ret = NULL;
119   iodev = a2dp_iodev_create(fake_transport);
120 
121   ASSERT_NE(iodev, (void*)NULL);
122   ASSERT_EQ(iodev->direction, CRAS_STREAM_OUTPUT);
123   ASSERT_EQ(1, cras_bt_transport_configuration_called);
124   ASSERT_EQ(1, init_a2dp_called);
125   ASSERT_EQ(1, cras_bt_device_append_iodev_called);
126   ASSERT_EQ(1, cras_iodev_add_node_called);
127   ASSERT_EQ(1, cras_iodev_set_active_node_called);
128 
129   /* Assert iodev name matches the object path when bt device doesn't
130    * have its readable name populated. */
131   ASSERT_STREQ(FAKE_OBJECT_PATH, iodev->info.name);
132 
133   a2dp_iodev_destroy(iodev);
134 
135   ASSERT_EQ(1, cras_bt_device_rm_iodev_called);
136   ASSERT_EQ(1, cras_iodev_rm_node_called);
137   ASSERT_EQ(1, destroy_a2dp_called);
138   ASSERT_EQ(1, cras_iodev_free_resources_called);
139 
140   cras_bt_device_name_ret = fake_device_name;
141   /* Assert iodev name matches the bt device's name */
142   iodev = a2dp_iodev_create(fake_transport);
143   ASSERT_STREQ(fake_device_name, iodev->info.name);
144 
145   a2dp_iodev_destroy(iodev);
146 }
147 
TEST_F(A2dpIodev,InitializeFail)148 TEST_F(A2dpIodev, InitializeFail) {
149   struct cras_iodev* iodev;
150 
151   init_a2dp_return_val = -1;
152   iodev = a2dp_iodev_create(fake_transport);
153 
154   ASSERT_EQ(iodev, (void*)NULL);
155   ASSERT_EQ(1, cras_bt_transport_configuration_called);
156   ASSERT_EQ(1, init_a2dp_called);
157   ASSERT_EQ(0, cras_bt_device_append_iodev_called);
158   ASSERT_EQ(0, cras_iodev_add_node_called);
159   ASSERT_EQ(0, cras_iodev_set_active_node_called);
160   ASSERT_EQ(0, cras_iodev_rm_node_called);
161 }
162 
TEST_F(A2dpIodev,OpenIodev)163 TEST_F(A2dpIodev, OpenIodev) {
164   struct cras_iodev* iodev;
165 
166   iodev = a2dp_iodev_create(fake_transport);
167 
168   iodev_set_format(iodev, &format);
169   iodev->configure_dev(iodev);
170 
171   ASSERT_EQ(1, cras_bt_transport_acquire_called);
172 
173   iodev->close_dev(iodev);
174   ASSERT_EQ(1, cras_bt_transport_release_called);
175   ASSERT_EQ(1, drain_a2dp_called);
176   ASSERT_EQ(1, cras_iodev_free_format_called);
177 
178   a2dp_iodev_destroy(iodev);
179 }
180 
TEST_F(A2dpIodev,GetPutBuffer)181 TEST_F(A2dpIodev, GetPutBuffer) {
182   struct cras_iodev* iodev;
183   struct cras_audio_area *area1, *area2, *area3;
184   uint8_t* area1_buf;
185   unsigned frames;
186 
187   iodev = a2dp_iodev_create(fake_transport);
188 
189   iodev_set_format(iodev, &format);
190   iodev->configure_dev(iodev);
191   ASSERT_NE(write_callback, (void*)NULL);
192 
193   frames = 256;
194   iodev->get_buffer(iodev, &area1, &frames);
195   ASSERT_EQ(256, frames);
196   ASSERT_EQ(256, area1->frames);
197   area1_buf = area1->channels[0].buf;
198 
199   /* Test 100 frames(400 bytes) put and all processed. */
200   a2dp_encode_processed_bytes_val[0] = 400;
201   a2dp_write_index = 0;
202   a2dp_write_return_val[0] = 400;
203   iodev->put_buffer(iodev, 100);
204   write_callback(write_callback_data);
205   // Start with 4k frames.
206   EXPECT_EQ(400, pcm_buf_size_val[0]);
207 
208   iodev->get_buffer(iodev, &area2, &frames);
209   ASSERT_EQ(256, frames);
210   ASSERT_EQ(256, area2->frames);
211 
212   /* Assert buf2 points to the same position as buf1 */
213   ASSERT_EQ(400, area2->channels[0].buf - area1_buf);
214 
215   /* Test 100 frames(400 bytes) put, only 360 bytes processed,
216    * 40 bytes left in pcm buffer.
217    */
218   a2dp_encode_index = 0;
219   a2dp_encode_processed_bytes_val[0] = 360;
220   a2dp_encode_processed_bytes_val[1] = 0;
221   a2dp_write_index = 0;
222   a2dp_write_return_val[0] = 360;
223   a2dp_write_return_val[1] = 0;
224   iodev->put_buffer(iodev, 100);
225   write_callback(write_callback_data);
226   EXPECT_EQ(400, pcm_buf_size_val[0]);
227   ASSERT_EQ(40, pcm_buf_size_val[1]);
228 
229   iodev->get_buffer(iodev, &area3, &frames);
230 
231   /* Existing buffer not completed processed, assert new buffer starts from
232    * current write pointer.
233    */
234   ASSERT_EQ(256, frames);
235   EXPECT_EQ(800, area3->channels[0].buf - area1_buf);
236 
237   iodev->close_dev(iodev);
238   a2dp_iodev_destroy(iodev);
239 }
240 
TEST_F(A2dpIodev,FramesQueued)241 TEST_F(A2dpIodev, FramesQueued) {
242   struct cras_iodev* iodev;
243   struct cras_audio_area* area;
244   struct timespec tstamp;
245   unsigned frames;
246 
247   iodev = a2dp_iodev_create(fake_transport);
248 
249   iodev_set_format(iodev, &format);
250   time_now.tv_sec = 0;
251   time_now.tv_nsec = 0;
252   iodev->configure_dev(iodev);
253   ASSERT_NE(write_callback, (void*)NULL);
254 
255   frames = 256;
256   iodev->get_buffer(iodev, &area, &frames);
257   ASSERT_EQ(256, frames);
258   ASSERT_EQ(256, area->frames);
259 
260   /* Put 100 frames, proccessed 400 bytes to a2dp buffer.
261    * Assume 200 bytes written out, queued 50 frames in a2dp buffer.
262    */
263   a2dp_encode_processed_bytes_val[0] = 400;
264   a2dp_write_return_val[0] = 50;
265   a2dp_queued_frames_val = 50;
266   time_now.tv_sec = 0;
267   time_now.tv_nsec = 1000000;
268   iodev->put_buffer(iodev, 200);
269   write_callback(write_callback_data);
270   EXPECT_EQ(200, iodev->frames_queued(iodev, &tstamp));
271   EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
272   EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
273 
274   /* After writing another 200 frames, check for correct buffer level. */
275   time_now.tv_sec = 0;
276   time_now.tv_nsec = 2000000;
277   a2dp_encode_index = 0;
278   a2dp_write_index = 0;
279   a2dp_encode_processed_bytes_val[0] = 400;
280   write_callback(write_callback_data);
281   /* 1000000 nsec has passed, estimated queued frames adjusted by 44 */
282   EXPECT_EQ(156, iodev->frames_queued(iodev, &tstamp));
283   EXPECT_EQ(400, pcm_buf_size_val[0]);
284   EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
285   EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
286 
287   /* Queued frames and new put buffer are all written */
288   a2dp_encode_processed_bytes_val[0] = 400;
289   a2dp_encode_processed_bytes_val[1] = 0;
290   a2dp_encode_index = 0;
291   a2dp_write_return_val[0] = 400;
292   a2dp_write_return_val[1] = -EAGAIN;
293   a2dp_write_index = 0;
294 
295   /* Add wnother 200 samples, get back to the original level. */
296   time_now.tv_sec = 0;
297   time_now.tv_nsec = 50000000;
298   a2dp_encode_processed_bytes_val[0] = 600;
299   a2dp_queued_frames_val = 50;
300   iodev->put_buffer(iodev, 200);
301   EXPECT_EQ(800, pcm_buf_size_val[0]);
302   EXPECT_EQ(100, iodev->frames_queued(iodev, &tstamp));
303   EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
304   EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
305   iodev->close_dev(iodev);
306   a2dp_iodev_destroy(iodev);
307 }
308 
TEST_F(A2dpIodev,FlushAtLowBufferLevel)309 TEST_F(A2dpIodev, FlushAtLowBufferLevel) {
310   struct cras_iodev* iodev;
311   struct cras_audio_area* area;
312   struct timespec tstamp;
313   unsigned frames;
314 
315   iodev = a2dp_iodev_create(fake_transport);
316 
317   iodev_set_format(iodev, &format);
318   time_now.tv_sec = 0;
319   time_now.tv_nsec = 0;
320   iodev->configure_dev(iodev);
321   ASSERT_NE(write_callback, (void*)NULL);
322 
323   ASSERT_EQ(iodev->min_buffer_level, 400);
324 
325   frames = 700;
326   iodev->get_buffer(iodev, &area, &frames);
327   ASSERT_EQ(700, frames);
328   ASSERT_EQ(700, area->frames);
329 
330   /* First call to a2dp_encode() processed 800 bytes. */
331   a2dp_encode_processed_bytes_val[0] = 800;
332   a2dp_encode_processed_bytes_val[1] = 0;
333   a2dp_write_return_val[0] = 200;
334 
335   /* put_buffer shouldn't trigger the 2nd call to a2dp_encode() because
336    * buffer is low. Fake some data to make sure this test case will fail
337    * when a2dp_encode() called twice.
338    */
339   a2dp_encode_processed_bytes_val[2] = 800;
340   a2dp_encode_processed_bytes_val[3] = 0;
341   a2dp_write_return_val[1] = -EAGAIN;
342 
343   time_now.tv_nsec = 10000000;
344   iodev->put_buffer(iodev, 700);
345 
346   time_now.tv_nsec = 20000000;
347   EXPECT_EQ(500, iodev->frames_queued(iodev, &tstamp));
348   EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
349   EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
350   iodev->close_dev(iodev);
351   a2dp_iodev_destroy(iodev);
352 }
353 
TEST_F(A2dpIodev,NoStreamState)354 TEST_F(A2dpIodev, NoStreamState) {
355   struct cras_iodev* iodev;
356   struct cras_audio_area* area;
357   struct timespec tstamp;
358   unsigned frames;
359 
360   iodev = a2dp_iodev_create(fake_transport);
361   iodev_set_format(iodev, &format);
362   time_now.tv_sec = 0;
363   time_now.tv_nsec = 0;
364   iodev->configure_dev(iodev);
365   ASSERT_NE(write_callback, (void*)NULL);
366   ASSERT_EQ(400, iodev->min_buffer_level);
367 
368   iodev->min_cb_level = 480;
369   frames = 200;
370   iodev->get_buffer(iodev, &area, &frames);
371   iodev->put_buffer(iodev, 200);
372 
373   iodev->no_stream(iodev, 1);
374   EXPECT_EQ(1, cras_iodev_frames_queued_called);
375 
376   /* no_stream will fill the buffer to hw_level = (441 (44100 * 0.01)) * 2
377    * frames, but 200 < min_buffer_level so cras_iodev_frames_queued will return
378    * 0 in no_stream and no_stream will fill 882 frames to device buffer.
379    */
380   frames = iodev->frames_queued(iodev, &tstamp);
381   ASSERT_EQ(1082, frames);
382 
383   /* After leaving no stream state, output buffer won't be adjusted */
384   iodev->no_stream(iodev, 0);
385   frames = iodev->frames_queued(iodev, &tstamp);
386   ASSERT_EQ(1082, frames);
387 }
388 
389 }  // namespace
390 
main(int argc,char ** argv)391 int main(int argc, char** argv) {
392   ::testing::InitGoogleTest(&argc, argv);
393   return RUN_ALL_TESTS();
394 }
395 
396 extern "C" {
397 
cras_bt_transport_configuration(const struct cras_bt_transport * transport,void * configuration,int len)398 int cras_bt_transport_configuration(const struct cras_bt_transport* transport,
399                                     void* configuration,
400                                     int len) {
401   cras_bt_transport_configuration_called++;
402   return 0;
403 }
404 
cras_bt_transport_acquire(struct cras_bt_transport * transport)405 int cras_bt_transport_acquire(struct cras_bt_transport* transport) {
406   cras_bt_transport_acquire_called++;
407   return 0;
408 }
409 
cras_bt_transport_release(struct cras_bt_transport * transport,unsigned int blocking)410 int cras_bt_transport_release(struct cras_bt_transport* transport,
411                               unsigned int blocking) {
412   cras_bt_transport_release_called++;
413   return 0;
414 }
415 
cras_bt_transport_fd(const struct cras_bt_transport * transport)416 int cras_bt_transport_fd(const struct cras_bt_transport* transport) {
417   return 0;
418 }
419 
cras_bt_transport_object_path(const struct cras_bt_transport * transport)420 const char* cras_bt_transport_object_path(
421     const struct cras_bt_transport* transport) {
422   return FAKE_OBJECT_PATH;
423 }
424 
cras_bt_transport_write_mtu(const struct cras_bt_transport * transport)425 uint16_t cras_bt_transport_write_mtu(
426     const struct cras_bt_transport* transport) {
427   return cras_bt_transport_write_mtu_ret;
428 }
429 
cras_bt_transport_set_volume(struct cras_bt_transport * transport,uint16_t volume)430 int cras_bt_transport_set_volume(struct cras_bt_transport* transport,
431                                  uint16_t volume) {
432   return 0;
433 }
434 
cras_iodev_free_format(struct cras_iodev * iodev)435 void cras_iodev_free_format(struct cras_iodev* iodev) {
436   cras_iodev_free_format_called++;
437 }
438 
cras_iodev_free_resources(struct cras_iodev * iodev)439 void cras_iodev_free_resources(struct cras_iodev* iodev) {
440   cras_iodev_free_resources_called++;
441 }
442 
443 // Cras iodev
cras_iodev_add_node(struct cras_iodev * iodev,struct cras_ionode * node)444 void cras_iodev_add_node(struct cras_iodev* iodev, struct cras_ionode* node) {
445   cras_iodev_add_node_called++;
446   iodev->nodes = node;
447 }
448 
cras_iodev_rm_node(struct cras_iodev * iodev,struct cras_ionode * node)449 void cras_iodev_rm_node(struct cras_iodev* iodev, struct cras_ionode* node) {
450   cras_iodev_rm_node_called++;
451   iodev->nodes = NULL;
452 }
453 
cras_iodev_set_active_node(struct cras_iodev * iodev,struct cras_ionode * node)454 void cras_iodev_set_active_node(struct cras_iodev* iodev,
455                                 struct cras_ionode* node) {
456   cras_iodev_set_active_node_called++;
457   iodev->active_node = node;
458 }
459 
460 // From cras_bt_transport
cras_bt_transport_device(const struct cras_bt_transport * transport)461 struct cras_bt_device* cras_bt_transport_device(
462     const struct cras_bt_transport* transport) {
463   return reinterpret_cast<struct cras_bt_device*>(0x456);
464   ;
465 }
466 
cras_bt_transport_profile(const struct cras_bt_transport * transport)467 enum cras_bt_device_profile cras_bt_transport_profile(
468     const struct cras_bt_transport* transport) {
469   return CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
470 }
471 
472 // From cras_bt_device
cras_bt_device_name(const struct cras_bt_device * device)473 const char* cras_bt_device_name(const struct cras_bt_device* device) {
474   return cras_bt_device_name_ret;
475 }
476 
cras_bt_device_object_path(const struct cras_bt_device * device)477 const char* cras_bt_device_object_path(const struct cras_bt_device* device) {
478   return "/org/bluez/hci0/dev_1A_2B_3C_4D_5E_6F";
479 }
480 
cras_bt_device_append_iodev(struct cras_bt_device * device,struct cras_iodev * iodev,enum cras_bt_device_profile profile)481 void cras_bt_device_append_iodev(struct cras_bt_device* device,
482                                  struct cras_iodev* iodev,
483                                  enum cras_bt_device_profile profile) {
484   cras_bt_device_append_iodev_called++;
485 }
486 
cras_bt_device_rm_iodev(struct cras_bt_device * device,struct cras_iodev * iodev)487 void cras_bt_device_rm_iodev(struct cras_bt_device* device,
488                              struct cras_iodev* iodev) {
489   cras_bt_device_rm_iodev_called++;
490 }
491 
cras_bt_device_get_use_hardware_volume(struct cras_bt_device * device)492 int cras_bt_device_get_use_hardware_volume(struct cras_bt_device* device) {
493   return 0;
494 }
495 
cras_bt_device_cancel_suspend(struct cras_bt_device * device)496 int cras_bt_device_cancel_suspend(struct cras_bt_device* device) {
497   return 0;
498 }
499 
cras_bt_device_schedule_suspend(struct cras_bt_device * device,unsigned int msec)500 int cras_bt_device_schedule_suspend(struct cras_bt_device* device,
501                                     unsigned int msec) {
502   return 0;
503 }
504 
init_a2dp(struct a2dp_info * a2dp,a2dp_sbc_t * sbc)505 int init_a2dp(struct a2dp_info* a2dp, a2dp_sbc_t* sbc) {
506   init_a2dp_called++;
507   return init_a2dp_return_val;
508 }
509 
destroy_a2dp(struct a2dp_info * a2dp)510 void destroy_a2dp(struct a2dp_info* a2dp) {
511   destroy_a2dp_called++;
512 }
513 
a2dp_codesize(struct a2dp_info * a2dp)514 int a2dp_codesize(struct a2dp_info* a2dp) {
515   return 512;
516 }
517 
a2dp_block_size(struct a2dp_info * a2dp,int encoded_bytes)518 int a2dp_block_size(struct a2dp_info* a2dp, int encoded_bytes) {
519   a2dp_block_size_called++;
520 
521   // Assumes a2dp block size is 1:1 before/after encode.
522   return encoded_bytes;
523 }
524 
a2dp_queued_frames(struct a2dp_info * a2dp)525 int a2dp_queued_frames(struct a2dp_info* a2dp) {
526   return a2dp_queued_frames_val;
527 }
528 
a2dp_drain(struct a2dp_info * a2dp)529 void a2dp_drain(struct a2dp_info* a2dp) {
530   drain_a2dp_called++;
531 }
532 
a2dp_encode(struct a2dp_info * a2dp,const void * pcm_buf,int pcm_buf_size,int format_bytes,size_t link_mtu)533 int a2dp_encode(struct a2dp_info* a2dp,
534                 const void* pcm_buf,
535                 int pcm_buf_size,
536                 int format_bytes,
537                 size_t link_mtu) {
538   unsigned int processed;
539 
540   if (a2dp_encode_index == MAX_A2DP_ENCODE_CALLS)
541     return 0;
542   processed = a2dp_encode_processed_bytes_val[a2dp_encode_index];
543   pcm_buf_size_val[a2dp_encode_index] = pcm_buf_size;
544   a2dp_encode_index++;
545   return processed;
546 }
547 
a2dp_write(struct a2dp_info * a2dp,int stream_fd,size_t link_mtu)548 int a2dp_write(struct a2dp_info* a2dp, int stream_fd, size_t link_mtu) {
549   return a2dp_write_return_val[a2dp_write_index++];
550   ;
551 }
552 
clock_gettime(clockid_t clk_id,struct timespec * tp)553 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
554   *tp = time_now;
555   return 0;
556 }
557 
cras_iodev_init_audio_area(struct cras_iodev * iodev,int num_channels)558 void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {
559   iodev->area = dummy_audio_area;
560 }
561 
cras_iodev_free_audio_area(struct cras_iodev * iodev)562 void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
563 
cras_iodev_frames_queued(struct cras_iodev * iodev,struct timespec * hw_tstamp)564 int cras_iodev_frames_queued(struct cras_iodev* iodev,
565                              struct timespec* hw_tstamp) {
566   int rc;
567   cras_iodev_frames_queued_called++;
568   rc = iodev->frames_queued(iodev, hw_tstamp);
569   if (rc < 0)
570     return 0;
571   unsigned int num_queued = (unsigned int)rc;
572   if (num_queued < iodev->min_buffer_level)
573     return 0;
574 
575   return num_queued - iodev->min_buffer_level;
576 }
577 
cras_audio_area_config_buf_pointers(struct cras_audio_area * area,const struct cras_audio_format * fmt,uint8_t * base_buffer)578 void cras_audio_area_config_buf_pointers(struct cras_audio_area* area,
579                                          const struct cras_audio_format* fmt,
580                                          uint8_t* base_buffer) {
581   dummy_audio_area->channels[0].buf = base_buffer;
582 }
583 
cras_iodev_list_get_audio_thread()584 struct audio_thread* cras_iodev_list_get_audio_thread() {
585   return NULL;
586 }
587 // From audio_thread
588 struct audio_thread_event_log* atlog;
589 
audio_thread_add_write_callback(int fd,thread_callback cb,void * data)590 void audio_thread_add_write_callback(int fd, thread_callback cb, void* data) {
591   write_callback = cb;
592   write_callback_data = data;
593 }
594 
audio_thread_rm_callback_sync(struct audio_thread * thread,int fd)595 int audio_thread_rm_callback_sync(struct audio_thread* thread, int fd) {
596   return 0;
597 }
598 
audio_thread_enable_callback(int fd,int enabled)599 void audio_thread_enable_callback(int fd, int enabled) {}
600 }
601