diff options
Diffstat (limited to 'cras/src/tests/hfp_info_unittest.cc')
-rw-r--r-- | cras/src/tests/hfp_info_unittest.cc | 586 |
1 files changed, 0 insertions, 586 deletions
diff --git a/cras/src/tests/hfp_info_unittest.cc b/cras/src/tests/hfp_info_unittest.cc deleted file mode 100644 index 24f536ae..00000000 --- a/cras/src/tests/hfp_info_unittest.cc +++ /dev/null @@ -1,586 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <gmock/gmock.h> -#include <gtest/gtest.h> -#include <stdint.h> -#include <time.h> - -using testing::MatchesRegex; -using testing::internal::CaptureStdout; -using testing::internal::GetCapturedStdout; - -extern "C" { -#include "cras_hfp_info.c" -#include "sbc_codec_stub.h" -} -static struct hfp_info* info; -static struct cras_iodev dev; -static cras_audio_format format; - -static int cras_msbc_plc_create_called; -static int cras_msbc_plc_handle_good_frames_called; -static int cras_msbc_plc_handle_bad_frames_called; - -static thread_callback thread_cb; -static void* cb_data; -static timespec ts; - -void ResetStubData() { - sbc_codec_stub_reset(); - cras_msbc_plc_create_called = 0; - - format.format = SND_PCM_FORMAT_S16_LE; - format.num_channels = 1; - format.frame_rate = 8000; - dev.format = &format; -} - -namespace { - -TEST(HfpInfo, AddRmDev) { - ResetStubData(); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - dev.direction = CRAS_STREAM_OUTPUT; - - /* Test add dev */ - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - ASSERT_TRUE(hfp_info_has_iodev(info)); - - /* Test remove dev */ - ASSERT_EQ(0, hfp_info_rm_iodev(info, dev.direction)); - ASSERT_FALSE(hfp_info_has_iodev(info)); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, AddRmDevInvalid) { - ResetStubData(); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - dev.direction = CRAS_STREAM_OUTPUT; - - /* Remove an iodev which doesn't exist */ - ASSERT_NE(0, hfp_info_rm_iodev(info, dev.direction)); - - /* Adding an iodev twice returns error code */ - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - ASSERT_NE(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, AcquirePlaybackBuffer) { - unsigned buffer_frames, buffer_frames2, queued; - uint8_t* samples; - - ResetStubData(); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info); - dev.direction = CRAS_STREAM_OUTPUT; - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - buffer_frames = 500; - hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames); - ASSERT_EQ(500, buffer_frames); - - hfp_buf_release(info, dev.direction, 500); - ASSERT_EQ(500, hfp_buf_queued(info, dev.direction)); - - /* Assert the amount of frames of available buffer + queued buf is - * greater than or equal to the buffer size, 2 bytes per frame - */ - queued = hfp_buf_queued(info, dev.direction); - buffer_frames = 500; - hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames); - ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + queued); - - /* Consume all queued data from read buffer */ - buf_increment_read(info->playback_buf, queued * 2); - - queued = hfp_buf_queued(info, dev.direction); - ASSERT_EQ(0, queued); - - /* Assert consecutive acquire buffer will acquire full used size of buffer */ - buffer_frames = 500; - hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames); - hfp_buf_release(info, dev.direction, buffer_frames); - - buffer_frames2 = 500; - hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames2); - hfp_buf_release(info, dev.direction, buffer_frames2); - - ASSERT_GE(info->playback_buf->used_size / 2, buffer_frames + buffer_frames2); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, AcquireCaptureBuffer) { - unsigned buffer_frames, buffer_frames2; - uint8_t* samples; - - ResetStubData(); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info); - dev.direction = CRAS_STREAM_INPUT; - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - /* Put fake data 100 bytes(50 frames) in capture buf for test */ - buf_increment_write(info->capture_buf, 100); - - /* Assert successfully acquire and release 100 bytes of data */ - buffer_frames = 50; - hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames); - ASSERT_EQ(50, buffer_frames); - - hfp_buf_release(info, dev.direction, buffer_frames); - ASSERT_EQ(0, hfp_buf_queued(info, dev.direction)); - - /* Push fake data to capture buffer */ - buf_increment_write(info->capture_buf, info->capture_buf->used_size - 100); - buf_increment_write(info->capture_buf, 100); - - /* Assert consecutive acquire call will consume the whole buffer */ - buffer_frames = 1000; - hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames); - hfp_buf_release(info, dev.direction, buffer_frames); - ASSERT_GE(1000, buffer_frames); - - buffer_frames2 = 1000; - hfp_buf_acquire(info, dev.direction, &samples, &buffer_frames2); - hfp_buf_release(info, dev.direction, buffer_frames2); - - ASSERT_GE(info->capture_buf->used_size / 2, buffer_frames + buffer_frames2); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, HfpReadWriteFD) { - int rc; - int sock[2]; - uint8_t sample[480]; - uint8_t* buf; - unsigned buffer_count; - - ResetStubData(); - - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - dev.direction = CRAS_STREAM_INPUT; - hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info); - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - /* Mock the sco fd and send some fake data */ - send(sock[0], sample, 48, 0); - - rc = hfp_read(info); - ASSERT_EQ(48, rc); - - rc = hfp_buf_queued(info, dev.direction); - ASSERT_EQ(48 / 2, rc); - - /* Fill the write buffer*/ - buffer_count = info->capture_buf->used_size; - buf = buf_write_pointer_size(info->capture_buf, &buffer_count); - buf_increment_write(info->capture_buf, buffer_count); - ASSERT_NE((void*)NULL, buf); - - rc = hfp_read(info); - ASSERT_EQ(0, rc); - - ASSERT_EQ(0, hfp_info_rm_iodev(info, dev.direction)); - dev.direction = CRAS_STREAM_OUTPUT; - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - /* Initial buffer is empty */ - rc = hfp_write(info); - ASSERT_EQ(0, rc); - - buffer_count = 1024; - buf = buf_write_pointer_size(info->playback_buf, &buffer_count); - buf_increment_write(info->playback_buf, buffer_count); - - rc = hfp_write(info); - ASSERT_EQ(48, rc); - - rc = recv(sock[0], sample, 48, 0); - ASSERT_EQ(48, rc); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, StartHfpInfo) { - int sock[2]; - - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - hfp_info_start(sock[0], 48, HFP_CODEC_ID_CVSD, info); - ASSERT_EQ(1, hfp_info_running(info)); - ASSERT_EQ(cb_data, (void*)info); - - hfp_info_stop(info); - ASSERT_EQ(0, hfp_info_running(info)); - ASSERT_EQ(NULL, cb_data); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, StartHfpInfoAndRead) { - int rc; - int sock[2]; - uint8_t sample[480]; - - ResetStubData(); - - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - /* Start and send two chunk of fake data */ - hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info); - send(sock[0], sample, 48, 0); - send(sock[0], sample, 48, 0); - - /* Trigger thread callback */ - thread_cb((struct hfp_info*)cb_data, POLLIN); - - dev.direction = CRAS_STREAM_INPUT; - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - /* Expect no data read, since no idev present at previous thread callback */ - rc = hfp_buf_queued(info, dev.direction); - ASSERT_EQ(0, rc); - - /* Trigger thread callback after idev added. */ - ts.tv_sec = 0; - ts.tv_nsec = 5000000; - thread_cb((struct hfp_info*)cb_data, POLLIN); - - rc = hfp_buf_queued(info, dev.direction); - ASSERT_EQ(48 / 2, rc); - - /* Assert wait time is unchanged. */ - ASSERT_EQ(0, ts.tv_sec); - ASSERT_EQ(5000000, ts.tv_nsec); - - hfp_info_stop(info); - ASSERT_EQ(0, hfp_info_running(info)); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, StartHfpInfoAndWrite) { - int rc; - int sock[2]; - uint8_t sample[480]; - - ResetStubData(); - - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info); - send(sock[0], sample, 48, 0); - send(sock[0], sample, 48, 0); - - /* Trigger thread callback */ - thread_cb((struct hfp_info*)cb_data, POLLIN); - - /* Without odev in presence, zero packet should be sent. */ - rc = recv(sock[0], sample, 48, 0); - ASSERT_EQ(48, rc); - - dev.direction = CRAS_STREAM_OUTPUT; - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - /* Assert queued samples unchanged before output device added */ - ASSERT_EQ(0, hfp_buf_queued(info, dev.direction)); - - /* Put some fake data and trigger thread callback again */ - buf_increment_write(info->playback_buf, 1008); - thread_cb((struct hfp_info*)cb_data, POLLIN); - - /* Assert some samples written */ - rc = recv(sock[0], sample, 48, 0); - ASSERT_EQ(48, rc); - ASSERT_EQ(480, hfp_buf_queued(info, dev.direction)); - - hfp_info_stop(info); - hfp_info_destroy(info); -} - -void send_mSBC_packet(int fd, unsigned seq, int broken_pkt) { - /* The first three bytes of hci_sco_buf are h2 header, frame count and mSBC - * sync word. The second octet of H2 header is composed by 4 bits fixed 0x8 - * and 4 bits sequence number 0000, 0011, 1100, 1111. - */ - uint8_t headers[4] = {0x08, 0x38, 0xc8, 0xf8}; - uint8_t hci_sco_buf[] = { - 0x01, 0x00, 0xAD, 0xad, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, - 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, - 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, - 0xb6, 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c}; - struct msghdr msg = {0}; - struct iovec iov; - struct cmsghdr* cmsg; - const unsigned int control_size = CMSG_SPACE(sizeof(int)); - char control[control_size] = {0}; - uint8_t pkt_status = 0; - - hci_sco_buf[1] = headers[seq % 4]; - - /* Assume typical 60 bytes case. */ - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - iov.iov_base = hci_sco_buf; - iov.iov_len = 60; - msg.msg_control = control; - msg.msg_controllen = control_size; - - if (broken_pkt) - pkt_status = 0x11; - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_BLUETOOTH; - cmsg->cmsg_type = BT_SCM_PKT_STATUS; - cmsg->cmsg_len = CMSG_LEN(sizeof(pkt_status)); - memcpy(CMSG_DATA(cmsg), &pkt_status, sizeof(pkt_status)); - - sendmsg(fd, &msg, 0); -} - -TEST(HfpInfo, StartHfpInfoAndReadMsbc) { - int sock[2]; - int pkt_count = 0; - int rc; - uint8_t sample[480]; - ResetStubData(); - - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); - - set_sbc_codec_decoded_out(MSBC_CODE_SIZE); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - ASSERT_EQ(0, get_msbc_codec_create_called()); - ASSERT_EQ(0, cras_msbc_plc_create_called); - - /* Start and send an mSBC packets with all zero samples */ - hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info); - ASSERT_EQ(2, get_msbc_codec_create_called()); - ASSERT_EQ(1, cras_msbc_plc_create_called); - send_mSBC_packet(sock[0], pkt_count++, 0); - - /* Trigger thread callback */ - thread_cb((struct hfp_info*)cb_data, POLLIN); - - /* Expect one empty mSBC packet is send, because no odev in presence. */ - rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0); - ASSERT_EQ(MSBC_PKT_SIZE, rc); - - dev.direction = CRAS_STREAM_INPUT; - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - /* Expect no data read, since no idev present at previous thread callback */ - ASSERT_EQ(0, hfp_buf_queued(info, dev.direction)); - - send_mSBC_packet(sock[0], pkt_count, 0); - - /* Trigger thread callback after idev added. */ - thread_cb((struct hfp_info*)cb_data, POLLIN); - rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0); - ASSERT_EQ(MSBC_PKT_SIZE, rc); - - ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2, - hfp_buf_queued(info, dev.direction)); - ASSERT_EQ(2, cras_msbc_plc_handle_good_frames_called); - pkt_count++; - /* When the third packet is lost, we should call the handle_bad_packet and - * still have right size of samples queued - */ - pkt_count++; - send_mSBC_packet(sock[0], pkt_count, 0); - thread_cb((struct hfp_info*)cb_data, POLLIN); - rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0); - ASSERT_EQ(MSBC_PKT_SIZE, rc); - - /* Packet 1, 2, 4 are all good frames */ - ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called); - ASSERT_EQ(1, cras_msbc_plc_handle_bad_frames_called); - ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2, - hfp_buf_queued(info, dev.direction)); - pkt_count++; - /* If the erroneous data reporting marks the packet as broken, we should - * also call the handle_bad_packet and have the right size of samples queued. - */ - send_mSBC_packet(sock[0], pkt_count, 1); - - set_sbc_codec_decoded_fail(1); - - thread_cb((struct hfp_info*)cb_data, POLLIN); - rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0); - ASSERT_EQ(MSBC_PKT_SIZE, rc); - - ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called); - ASSERT_EQ(2, cras_msbc_plc_handle_bad_frames_called); - ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2, - hfp_buf_queued(info, dev.direction)); - pkt_count++; - /* If we can't decode the packet, we should also call the handle_bad_packet - * and have the right size of samples queued - */ - send_mSBC_packet(sock[0], pkt_count, 0); - - set_sbc_codec_decoded_fail(1); - - thread_cb((struct hfp_info*)cb_data, POLLIN); - rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0); - ASSERT_EQ(MSBC_PKT_SIZE, rc); - - ASSERT_EQ(3, cras_msbc_plc_handle_good_frames_called); - ASSERT_EQ(3, cras_msbc_plc_handle_bad_frames_called); - ASSERT_EQ(pkt_count * MSBC_CODE_SIZE / 2, - hfp_buf_queued(info, dev.direction)); - - hfp_info_stop(info); - ASSERT_EQ(0, hfp_info_running(info)); - - hfp_info_destroy(info); -} - -TEST(HfpInfo, StartHfpInfoAndWriteMsbc) { - int rc; - int sock[2]; - uint8_t sample[480]; - - ResetStubData(); - - set_sbc_codec_encoded_out(57); - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); - - info = hfp_info_create(); - ASSERT_NE(info, (void*)NULL); - - hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info); - send(sock[0], sample, 63, 0); - - /* Trigger thread callback */ - thread_cb((struct hfp_info*)cb_data, POLLIN); - - dev.direction = CRAS_STREAM_OUTPUT; - ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format)); - - /* Assert queued samples unchanged before output device added */ - ASSERT_EQ(0, hfp_buf_queued(info, dev.direction)); - - /* Put some fake data and trigger thread callback again */ - send(sock[0], sample, 63, 0); - buf_increment_write(info->playback_buf, 240); - thread_cb((struct hfp_info*)cb_data, POLLIN); - - /* Assert some samples written */ - rc = recv(sock[0], sample, 60, 0); - ASSERT_EQ(60, rc); - ASSERT_EQ(0, hfp_buf_queued(info, dev.direction)); - - hfp_info_stop(info); - hfp_info_destroy(info); -} - -TEST(HfpInfo, WBSLoggerPacketStatusDumpBinary) { - struct packet_status_logger logger; - char log_regex[64]; - int num_wraps[5] = {0, 0, 0, 1, 1}; - int wp[5] = {40, 150, 162, 100, 32}; - - /* Expect the log line wraps at correct length to avoid feedback redact. */ - snprintf(log_regex, 64, "([01D]{%d}\n)*", PACKET_STATUS_LOG_LINE_WRAP); - - packet_status_logger_init(&logger); - logger.size = PACKET_STATUS_LEN_BYTES * 8; - for (int i = 0; i < 5; i++) { - CaptureStdout(); - logger.num_wraps = num_wraps[i]; - logger.wp = wp[i]; - packet_status_logger_dump_binary(&logger); - EXPECT_THAT(GetCapturedStdout(), MatchesRegex(log_regex)); - } -} - -} // namespace - -extern "C" { - -struct audio_thread* cras_iodev_list_get_audio_thread() { - return NULL; -} - -void audio_thread_add_events_callback(int fd, - thread_callback cb, - void* data, - int events) { - thread_cb = cb; - cb_data = data; - return; -} - -int audio_thread_rm_callback_sync(struct audio_thread* thread, int fd) { - thread_cb = NULL; - cb_data = NULL; - return 0; -} - -void audio_thread_rm_callback(int fd) {} - -struct cras_msbc_plc* cras_msbc_plc_create() { - cras_msbc_plc_create_called++; - return NULL; -} - -void cras_msbc_plc_destroy(struct cras_msbc_plc* plc) {} - -int cras_msbc_plc_handle_bad_frames(struct cras_msbc_plc* plc, - struct cras_audio_codec* codec, - uint8_t* output) { - cras_msbc_plc_handle_bad_frames_called++; - return MSBC_CODE_SIZE; -} - -int cras_msbc_plc_handle_good_frames(struct cras_msbc_plc* plc, - const uint8_t* input, - uint8_t* output) { - cras_msbc_plc_handle_good_frames_called++; - return MSBC_CODE_SIZE; -} -void packet_status_logger_init(struct packet_status_logger* logger) {} - -void packet_status_logger_update(struct packet_status_logger* logger, - bool val) {} -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} |