summaryrefslogtreecommitdiff
path: root/cras/src/tests/hfp_info_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/tests/hfp_info_unittest.cc')
-rw-r--r--cras/src/tests/hfp_info_unittest.cc586
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();
-}