1 /* Copyright 2013 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <gmock/gmock.h>
7 #include <gtest/gtest.h>
8 #include <stdint.h>
9 #include <time.h>
10
11 using testing::MatchesRegex;
12 using testing::internal::CaptureStdout;
13 using testing::internal::GetCapturedStdout;
14
15 extern "C" {
16 #include "cras_hfp_info.c"
17 #include "sbc_codec_stub.h"
18 }
19 static struct hfp_info* info;
20 static struct cras_iodev dev;
21 static cras_audio_format format;
22
23 static int cras_msbc_plc_create_called;
24 static int cras_msbc_plc_handle_good_frames_called;
25 static int cras_msbc_plc_handle_bad_frames_called;
26
27 static thread_callback thread_cb;
28 static void* cb_data;
29 static timespec ts;
30
ResetStubData()31 void ResetStubData() {
32 sbc_codec_stub_reset();
33 cras_msbc_plc_create_called = 0;
34
35 format.format = SND_PCM_FORMAT_S16_LE;
36 format.num_channels = 1;
37 format.frame_rate = 8000;
38 dev.format = &format;
39 }
40
41 namespace {
42
TEST(HfpInfo,AddRmDev)43 TEST(HfpInfo, AddRmDev) {
44 ResetStubData();
45
46 info = hfp_info_create();
47 ASSERT_NE(info, (void*)NULL);
48 dev.direction = CRAS_STREAM_OUTPUT;
49
50 /* Test add dev */
51 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
52 ASSERT_TRUE(hfp_info_has_iodev(info));
53
54 /* Test remove dev */
55 ASSERT_EQ(0, hfp_info_rm_iodev(info, dev.direction));
56 ASSERT_FALSE(hfp_info_has_iodev(info));
57
58 hfp_info_destroy(info);
59 }
60
TEST(HfpInfo,AddRmDevInvalid)61 TEST(HfpInfo, AddRmDevInvalid) {
62 ResetStubData();
63
64 info = hfp_info_create();
65 ASSERT_NE(info, (void*)NULL);
66
67 dev.direction = CRAS_STREAM_OUTPUT;
68
69 /* Remove an iodev which doesn't exist */
70 ASSERT_NE(0, hfp_info_rm_iodev(info, dev.direction));
71
72 /* Adding an iodev twice returns error code */
73 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
74 ASSERT_NE(0, hfp_info_add_iodev(info, dev.direction, dev.format));
75
76 hfp_info_destroy(info);
77 }
78
TEST(HfpInfo,AcquirePlaybackBuffer)79 TEST(HfpInfo, AcquirePlaybackBuffer) {
80 unsigned buffer_frames, buffer_frames2, queued;
81 uint8_t* samples;
82
83 ResetStubData();
84
85 info = hfp_info_create();
86 ASSERT_NE(info, (void*)NULL);
87
88 hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info);
89 dev.direction = CRAS_STREAM_OUTPUT;
90 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
91
92 buffer_frames = 500;
93 hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
94 ASSERT_EQ(500, buffer_frames);
95
96 hfp_buf_release(info, dev.direction, 500);
97 ASSERT_EQ(500, hfp_buf_queued(info, dev.direction));
98
99 /* Assert the amount of frames of available buffer + queued buf is
100 * greater than or equal to the buffer size, 2 bytes per frame
101 */
102 queued = hfp_buf_queued(info, dev.direction);
103 buffer_frames = 500;
104 hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
105 ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + queued);
106
107 /* Consume all queued data from read buffer */
108 buf_increment_read(info->playback_buf, queued * 2);
109
110 queued = hfp_buf_queued(info, dev.direction);
111 ASSERT_EQ(0, queued);
112
113 /* Assert consecutive acquire buffer will acquire full used size of buffer */
114 buffer_frames = 500;
115 hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
116 hfp_buf_release(info, dev.direction, buffer_frames);
117
118 buffer_frames2 = 500;
119 hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames2);
120 hfp_buf_release(info, dev.direction, buffer_frames2);
121
122 ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + buffer_frames2);
123
124 hfp_info_destroy(info);
125 }
126
TEST(HfpInfo,AcquireCaptureBuffer)127 TEST(HfpInfo, AcquireCaptureBuffer) {
128 unsigned buffer_frames, buffer_frames2;
129 uint8_t* samples;
130
131 ResetStubData();
132
133 info = hfp_info_create();
134 ASSERT_NE(info, (void*)NULL);
135
136 hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info);
137 dev.direction = CRAS_STREAM_INPUT;
138 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
139
140 /* Put fake data 100 bytes(50 frames) in capture buf for test */
141 buf_increment_write(info->capture_buf, 100);
142
143 /* Assert successfully acquire and release 100 bytes of data */
144 buffer_frames = 50;
145 hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
146 ASSERT_EQ(50, buffer_frames);
147
148 hfp_buf_release(info, dev.direction, buffer_frames);
149 ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));
150
151 /* Push fake data to capture buffer */
152 buf_increment_write(info->capture_buf, info->capture_buf->used_size - 100);
153 buf_increment_write(info->capture_buf, 100);
154
155 /* Assert consecutive acquire call will consume the whole buffer */
156 buffer_frames = 1000;
157 hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames);
158 hfp_buf_release(info, dev.direction, buffer_frames);
159 ASSERT_GE(1000, buffer_frames);
160
161 buffer_frames2 = 1000;
162 hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames2);
163 hfp_buf_release(info, dev.direction, buffer_frames2);
164
165 ASSERT_GE(info->capture_buf->used_size / 2, buffer_frames + buffer_frames2);
166
167 hfp_info_destroy(info);
168 }
169
TEST(HfpInfo,HfpReadWriteFD)170 TEST(HfpInfo, HfpReadWriteFD) {
171 int rc;
172 int sock[2];
173 uint8_t sample[480];
174 uint8_t* buf;
175 unsigned buffer_count;
176
177 ResetStubData();
178
179 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
180
181 info = hfp_info_create();
182 ASSERT_NE(info, (void*)NULL);
183
184 dev.direction = CRAS_STREAM_INPUT;
185 hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
186 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
187
188 /* Mock the sco fd and send some fake data */
189 send(sock[0], sample, 48, 0);
190
191 rc = hfp_read(info);
192 ASSERT_EQ(48, rc);
193
194 rc = hfp_buf_queued(info, dev.direction);
195 ASSERT_EQ(48 / 2, rc);
196
197 /* Fill the write buffer*/
198 buffer_count = info->capture_buf->used_size;
199 buf = buf_write_pointer_size(info->capture_buf, &buffer_count);
200 buf_increment_write(info->capture_buf, buffer_count);
201 ASSERT_NE((void*)NULL, buf);
202
203 rc = hfp_read(info);
204 ASSERT_EQ(0, rc);
205
206 ASSERT_EQ(0, hfp_info_rm_iodev(info, dev.direction));
207 dev.direction = CRAS_STREAM_OUTPUT;
208 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
209
210 /* Initial buffer is empty */
211 rc = hfp_write(info);
212 ASSERT_EQ(0, rc);
213
214 buffer_count = 1024;
215 buf = buf_write_pointer_size(info->playback_buf, &buffer_count);
216 buf_increment_write(info->playback_buf, buffer_count);
217
218 rc = hfp_write(info);
219 ASSERT_EQ(48, rc);
220
221 rc = recv(sock[0], sample, 48, 0);
222 ASSERT_EQ(48, rc);
223
224 hfp_info_destroy(info);
225 }
226
TEST(HfpInfo,StartHfpInfo)227 TEST(HfpInfo, StartHfpInfo) {
228 int sock[2];
229
230 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
231
232 info = hfp_info_create();
233 ASSERT_NE(info, (void*)NULL);
234
235 hfp_info_start(sock[0], 48, HFP_CODEC_ID_CVSD, info);
236 ASSERT_EQ(1, hfp_info_running(info));
237 ASSERT_EQ(cb_data, (void*)info);
238
239 hfp_info_stop(info);
240 ASSERT_EQ(0, hfp_info_running(info));
241 ASSERT_EQ(NULL, cb_data);
242
243 hfp_info_destroy(info);
244 }
245
TEST(HfpInfo,StartHfpInfoAndRead)246 TEST(HfpInfo, StartHfpInfoAndRead) {
247 int rc;
248 int sock[2];
249 uint8_t sample[480];
250
251 ResetStubData();
252
253 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
254
255 info = hfp_info_create();
256 ASSERT_NE(info, (void*)NULL);
257
258 /* Start and send two chunk of fake data */
259 hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
260 send(sock[0], sample, 48, 0);
261 send(sock[0], sample, 48, 0);
262
263 /* Trigger thread callback */
264 thread_cb((struct hfp_info*)cb_data, POLLIN);
265
266 dev.direction = CRAS_STREAM_INPUT;
267 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
268
269 /* Expect no data read, since no idev present at previous thread callback */
270 rc = hfp_buf_queued(info, dev.direction);
271 ASSERT_EQ(0, rc);
272
273 /* Trigger thread callback after idev added. */
274 ts.tv_sec = 0;
275 ts.tv_nsec = 5000000;
276 thread_cb((struct hfp_info*)cb_data, POLLIN);
277
278 rc = hfp_buf_queued(info, dev.direction);
279 ASSERT_EQ(48 / 2, rc);
280
281 /* Assert wait time is unchanged. */
282 ASSERT_EQ(0, ts.tv_sec);
283 ASSERT_EQ(5000000, ts.tv_nsec);
284
285 hfp_info_stop(info);
286 ASSERT_EQ(0, hfp_info_running(info));
287
288 hfp_info_destroy(info);
289 }
290
TEST(HfpInfo,StartHfpInfoAndWrite)291 TEST(HfpInfo, StartHfpInfoAndWrite) {
292 int rc;
293 int sock[2];
294 uint8_t sample[480];
295
296 ResetStubData();
297
298 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
299
300 info = hfp_info_create();
301 ASSERT_NE(info, (void*)NULL);
302
303 hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
304 send(sock[0], sample, 48, 0);
305 send(sock[0], sample, 48, 0);
306
307 /* Trigger thread callback */
308 thread_cb((struct hfp_info*)cb_data, POLLIN);
309
310 /* Without odev in presence, zero packet should be sent. */
311 rc = recv(sock[0], sample, 48, 0);
312 ASSERT_EQ(48, rc);
313
314 dev.direction = CRAS_STREAM_OUTPUT;
315 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
316
317 /* Assert queued samples unchanged before output device added */
318 ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));
319
320 /* Put some fake data and trigger thread callback again */
321 buf_increment_write(info->playback_buf, 1008);
322 thread_cb((struct hfp_info*)cb_data, POLLIN);
323
324 /* Assert some samples written */
325 rc = recv(sock[0], sample, 48, 0);
326 ASSERT_EQ(48, rc);
327 ASSERT_EQ(480, hfp_buf_queued(info, dev.direction));
328
329 hfp_info_stop(info);
330 hfp_info_destroy(info);
331 }
332
send_mSBC_packet(int fd,unsigned seq,int broken_pkt)333 void send_mSBC_packet(int fd, unsigned seq, int broken_pkt) {
334 /* The first three bytes of hci_sco_buf are h2 header, frame count and mSBC
335 * sync word. The second octet of H2 header is composed by 4 bits fixed 0x8
336 * and 4 bits sequence number 0000, 0011, 1100, 1111.
337 */
338 uint8_t headers[4] = {0x08, 0x38, 0xc8, 0xf8};
339 uint8_t hci_sco_buf[] = {
340 0x01, 0x00, 0xAD, 0xad, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x77,
341 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb,
342 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6,
343 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd,
344 0xb6, 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c};
345 struct msghdr msg = {0};
346 struct iovec iov;
347 struct cmsghdr* cmsg;
348 const unsigned int control_size = CMSG_SPACE(sizeof(int));
349 char control[control_size] = {0};
350 uint8_t pkt_status = 0;
351
352 hci_sco_buf[1] = headers[seq % 4];
353
354 /* Assume typical 60 bytes case. */
355 msg.msg_iov = &iov;
356 msg.msg_iovlen = 1;
357 iov.iov_base = hci_sco_buf;
358 iov.iov_len = 60;
359 msg.msg_control = control;
360 msg.msg_controllen = control_size;
361
362 if (broken_pkt)
363 pkt_status = 0x11;
364
365 cmsg = CMSG_FIRSTHDR(&msg);
366 cmsg->cmsg_level = SOL_BLUETOOTH;
367 cmsg->cmsg_type = BT_SCM_PKT_STATUS;
368 cmsg->cmsg_len = CMSG_LEN(sizeof(pkt_status));
369 memcpy(CMSG_DATA(cmsg), &pkt_status, sizeof(pkt_status));
370
371 sendmsg(fd, &msg, 0);
372 }
373
TEST(HfpInfo,StartHfpInfoAndReadMsbc)374 TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
375 int sock[2];
376 int pkt_count = 0;
377 int rc;
378 uint8_t sample[480];
379 ResetStubData();
380
381 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
382
383 set_sbc_codec_decoded_out(MSBC_CODE_SIZE);
384
385 info = hfp_info_create();
386 ASSERT_NE(info, (void*)NULL);
387 ASSERT_EQ(0, get_msbc_codec_create_called());
388 ASSERT_EQ(0, cras_msbc_plc_create_called);
389
390 /* Start and send an mSBC packets with all zero samples */
391 hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info);
392 ASSERT_EQ(2, get_msbc_codec_create_called());
393 ASSERT_EQ(1, cras_msbc_plc_create_called);
394 send_mSBC_packet(sock[0], pkt_count++, 0);
395
396 /* Trigger thread callback */
397 thread_cb((struct hfp_info*)cb_data, POLLIN);
398
399 /* Expect one empty mSBC packet is send, because no odev in presence. */
400 rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
401 ASSERT_EQ(MSBC_PKT_SIZE, rc);
402
403 dev.direction = CRAS_STREAM_INPUT;
404 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
405
406 /* Expect no data read, since no idev present at previous thread callback */
407 ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));
408
409 send_mSBC_packet(sock[0], pkt_count, 0);
410
411 /* Trigger thread callback after idev added. */
412 thread_cb((struct hfp_info*)cb_data, POLLIN);
413 rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
414 ASSERT_EQ(MSBC_PKT_SIZE, rc);
415
416 ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
417 hfp_buf_queued(info, dev.direction));
418 ASSERT_EQ(2, cras_msbc_plc_handle_good_frames_called);
419 pkt_count++;
420 /* When the third packet is lost, we should call the handle_bad_packet and
421 * still have right size of samples queued
422 */
423 pkt_count++;
424 send_mSBC_packet(sock[0], pkt_count, 0);
425 thread_cb((struct hfp_info*)cb_data, POLLIN);
426 rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
427 ASSERT_EQ(MSBC_PKT_SIZE, rc);
428
429 /* Packet 1, 2, 4 are all good frames */
430 ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called);
431 ASSERT_EQ(1, cras_msbc_plc_handle_bad_frames_called);
432 ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
433 hfp_buf_queued(info, dev.direction));
434 pkt_count++;
435 /* If the erroneous data reporting marks the packet as broken, we should
436 * also call the handle_bad_packet and have the right size of samples queued.
437 */
438 send_mSBC_packet(sock[0], pkt_count, 1);
439
440 set_sbc_codec_decoded_fail(1);
441
442 thread_cb((struct hfp_info*)cb_data, POLLIN);
443 rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
444 ASSERT_EQ(MSBC_PKT_SIZE, rc);
445
446 ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called);
447 ASSERT_EQ(2, cras_msbc_plc_handle_bad_frames_called);
448 ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
449 hfp_buf_queued(info, dev.direction));
450 pkt_count++;
451 /* If we can't decode the packet, we should also call the handle_bad_packet
452 * and have the right size of samples queued
453 */
454 send_mSBC_packet(sock[0], pkt_count, 0);
455
456 set_sbc_codec_decoded_fail(1);
457
458 thread_cb((struct hfp_info*)cb_data, POLLIN);
459 rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
460 ASSERT_EQ(MSBC_PKT_SIZE, rc);
461
462 ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called);
463 ASSERT_EQ(3, cras_msbc_plc_handle_bad_frames_called);
464 ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2,
465 hfp_buf_queued(info, dev.direction));
466
467 hfp_info_stop(info);
468 ASSERT_EQ(0, hfp_info_running(info));
469
470 hfp_info_destroy(info);
471 }
472
TEST(HfpInfo,StartHfpInfoAndWriteMsbc)473 TEST(HfpInfo, StartHfpInfoAndWriteMsbc) {
474 int rc;
475 int sock[2];
476 uint8_t sample[480];
477
478 ResetStubData();
479
480 set_sbc_codec_encoded_out(57);
481 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
482
483 info = hfp_info_create();
484 ASSERT_NE(info, (void*)NULL);
485
486 hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info);
487 send(sock[0], sample, 63, 0);
488
489 /* Trigger thread callback */
490 thread_cb((struct hfp_info*)cb_data, POLLIN);
491
492 dev.direction = CRAS_STREAM_OUTPUT;
493 ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
494
495 /* Assert queued samples unchanged before output device added */
496 ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));
497
498 /* Put some fake data and trigger thread callback again */
499 send(sock[0], sample, 63, 0);
500 buf_increment_write(info->playback_buf, 240);
501 thread_cb((struct hfp_info*)cb_data, POLLIN);
502
503 /* Assert some samples written */
504 rc = recv(sock[0], sample, 60, 0);
505 ASSERT_EQ(60, rc);
506 ASSERT_EQ(0, hfp_buf_queued(info, dev.direction));
507
508 hfp_info_stop(info);
509 hfp_info_destroy(info);
510 }
511
TEST(HfpInfo,WBSLoggerPacketStatusDumpBinary)512 TEST(HfpInfo, WBSLoggerPacketStatusDumpBinary) {
513 struct packet_status_logger logger;
514 char log_regex[64];
515 int num_wraps[5] = {0, 0, 0, 1, 1};
516 int wp[5] = {40, 150, 162, 100, 32};
517
518 /* Expect the log line wraps at correct length to avoid feedback redact. */
519 snprintf(log_regex, 64, "([01D]{%d}\n)*", PACKET_STATUS_LOG_LINE_WRAP);
520
521 packet_status_logger_init(&logger);
522 logger.size = PACKET_STATUS_LEN_BYTES * 8;
523 for (int i = 0; i < 5; i++) {
524 CaptureStdout();
525 logger.num_wraps = num_wraps[i];
526 logger.wp = wp[i];
527 packet_status_logger_dump_binary(&logger);
528 EXPECT_THAT(GetCapturedStdout(), MatchesRegex(log_regex));
529 }
530 }
531
532 } // namespace
533
534 extern "C" {
535
cras_iodev_list_get_audio_thread()536 struct audio_thread* cras_iodev_list_get_audio_thread() {
537 return NULL;
538 }
539
audio_thread_add_events_callback(int fd,thread_callback cb,void * data,int events)540 void audio_thread_add_events_callback(int fd,
541 thread_callback cb,
542 void* data,
543 int events) {
544 thread_cb = cb;
545 cb_data = data;
546 return;
547 }
548
audio_thread_rm_callback_sync(struct audio_thread * thread,int fd)549 int audio_thread_rm_callback_sync(struct audio_thread* thread, int fd) {
550 thread_cb = NULL;
551 cb_data = NULL;
552 return 0;
553 }
554
audio_thread_rm_callback(int fd)555 void audio_thread_rm_callback(int fd) {}
556
cras_msbc_plc_create()557 struct cras_msbc_plc* cras_msbc_plc_create() {
558 cras_msbc_plc_create_called++;
559 return NULL;
560 }
561
cras_msbc_plc_destroy(struct cras_msbc_plc * plc)562 void cras_msbc_plc_destroy(struct cras_msbc_plc* plc) {}
563
cras_msbc_plc_handle_bad_frames(struct cras_msbc_plc * plc,struct cras_audio_codec * codec,uint8_t * output)564 int cras_msbc_plc_handle_bad_frames(struct cras_msbc_plc* plc,
565 struct cras_audio_codec* codec,
566 uint8_t* output) {
567 cras_msbc_plc_handle_bad_frames_called++;
568 return MSBC_CODE_SIZE;
569 }
570
cras_msbc_plc_handle_good_frames(struct cras_msbc_plc * plc,const uint8_t * input,uint8_t * output)571 int cras_msbc_plc_handle_good_frames(struct cras_msbc_plc* plc,
572 const uint8_t* input,
573 uint8_t* output) {
574 cras_msbc_plc_handle_good_frames_called++;
575 return MSBC_CODE_SIZE;
576 }
packet_status_logger_init(struct packet_status_logger * logger)577 void packet_status_logger_init(struct packet_status_logger* logger) {}
578
packet_status_logger_update(struct packet_status_logger * logger,bool val)579 void packet_status_logger_update(struct packet_status_logger* logger,
580 bool val) {}
581 }
582
main(int argc,char ** argv)583 int main(int argc, char** argv) {
584 ::testing::InitGoogleTest(&argc, argv);
585 return RUN_ALL_TESTS();
586 }
587