blob: 500774f18a04c3e0f13477ffe4101da8b83467a4 [file] [log] [blame]
// Copyright 2015 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 <gtest/gtest.h>
#include <stdio.h>
extern "C" {
#include "cras_rstream.h"
#include "stream_list.h"
}
namespace {
static unsigned int add_called;
static int added_cb(struct cras_rstream* rstream) {
add_called++;
return 0;
}
static unsigned int rm_called;
static struct cras_rstream* rmed_stream;
static int removed_cb(struct cras_rstream* rstream) {
rm_called++;
rmed_stream = rstream;
return 0;
}
static unsigned int create_called;
static struct cras_rstream_config* create_config;
static int create_rstream_cb(struct cras_rstream_config* stream_config,
struct cras_rstream** stream) {
create_called++;
create_config = stream_config;
*stream = (struct cras_rstream*)malloc(sizeof(struct cras_rstream));
(*stream)->stream_id = stream_config->stream_id;
(*stream)->direction = stream_config->direction;
if (stream_config->format)
(*stream)->format = *(stream_config->format);
(*stream)->cb_threshold = stream_config->cb_threshold;
(*stream)->client_type = stream_config->client_type;
(*stream)->stream_type = stream_config->stream_type;
clock_gettime(CLOCK_MONOTONIC_RAW, &(*stream)->start_ts);
return 0;
}
static unsigned int destroy_called;
static struct cras_rstream* destroyed_stream;
static void destroy_rstream_cb(struct cras_rstream* rstream) {
destroy_called++;
destroyed_stream = rstream;
free(rstream);
}
static void reset_test_data() {
add_called = 0;
rm_called = 0;
create_called = 0;
destroy_called = 0;
}
TEST(StreamList, AddRemove) {
struct stream_list* l;
struct cras_rstream* s1;
struct cras_rstream_config s1_config;
s1_config.stream_id = 0x3003;
s1_config.direction = CRAS_STREAM_OUTPUT;
s1_config.format = NULL;
reset_test_data();
l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
destroy_rstream_cb, NULL);
stream_list_add(l, &s1_config, &s1);
EXPECT_EQ(1, add_called);
EXPECT_EQ(1, create_called);
EXPECT_EQ(&s1_config, create_config);
EXPECT_EQ(0, stream_list_rm(l, 0x3003));
EXPECT_EQ(1, rm_called);
EXPECT_EQ(s1, rmed_stream);
EXPECT_EQ(1, destroy_called);
EXPECT_EQ(s1, destroyed_stream);
stream_list_destroy(l);
}
TEST(StreamList, AddInDescendingOrderByChannels) {
struct stream_list* l;
struct cras_rstream* s1;
struct cras_rstream* s2;
struct cras_rstream* s3;
struct cras_audio_format s1_format, s2_format, s3_format;
struct cras_rstream_config s1_config, s2_config, s3_config;
s1_config.stream_id = 0x4001;
s1_config.direction = CRAS_STREAM_INPUT;
s1_format.num_channels = 6;
s1_config.format = &s1_format;
s2_config.stream_id = 0x4002;
s2_config.direction = CRAS_STREAM_OUTPUT;
s2_format.num_channels = 8;
s2_config.format = &s2_format;
s3_config.stream_id = 0x4003;
s3_config.direction = CRAS_STREAM_OUTPUT;
s3_format.num_channels = 2;
s3_config.format = &s3_format;
reset_test_data();
l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
destroy_rstream_cb, NULL);
stream_list_add(l, &s1_config, &s1);
EXPECT_EQ(1, add_called);
EXPECT_EQ(1, create_called);
EXPECT_EQ(6, stream_list_get(l)->format.num_channels);
stream_list_add(l, &s2_config, &s2);
EXPECT_EQ(2, add_called);
EXPECT_EQ(2, create_called);
EXPECT_EQ(8, stream_list_get(l)->format.num_channels);
EXPECT_EQ(6, stream_list_get(l)->next->format.num_channels);
stream_list_add(l, &s3_config, &s3);
EXPECT_EQ(3, add_called);
EXPECT_EQ(3, create_called);
EXPECT_EQ(8, stream_list_get(l)->format.num_channels);
EXPECT_EQ(6, stream_list_get(l)->next->format.num_channels);
EXPECT_EQ(2, stream_list_get(l)->next->next->format.num_channels);
EXPECT_EQ(0, stream_list_rm(l, 0x4001));
EXPECT_EQ(0, stream_list_rm(l, 0x4002));
EXPECT_EQ(0, stream_list_rm(l, 0x4003));
stream_list_destroy(l);
}
TEST(StreamList, DetectRtcStreamPair) {
struct stream_list* l;
struct cras_rstream *s1, *s2, *s3, *s4;
struct cras_rstream_config s1_config, s2_config, s3_config, s4_config;
s1_config.stream_id = 0x5001;
s1_config.direction = CRAS_STREAM_OUTPUT;
s1_config.cb_threshold = 480;
s1_config.client_type = CRAS_CLIENT_TYPE_CHROME;
s1_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
s1_config.format = NULL;
s2_config.stream_id = 0x5002;
s2_config.direction = CRAS_STREAM_INPUT;
s2_config.cb_threshold = 480;
s2_config.client_type = CRAS_CLIENT_TYPE_CHROME;
s2_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
s2_config.format = NULL;
// s3 is not a RTC stream because the cb threshold is not 480.
s3_config.stream_id = 0x5003;
s3_config.direction = CRAS_STREAM_INPUT;
s3_config.cb_threshold = 500;
s3_config.client_type = CRAS_CLIENT_TYPE_CHROME;
s3_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
s3_config.format = NULL;
// s4 is not a RTC stream because it is not from the same client with s1.
s4_config.stream_id = 0x5004;
s4_config.direction = CRAS_STREAM_INPUT;
s4_config.cb_threshold = 480;
s4_config.client_type = CRAS_CLIENT_TYPE_LACROS;
s4_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
s4_config.format = NULL;
reset_test_data();
l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
destroy_rstream_cb, NULL);
stream_list_add(l, &s1_config, &s1);
EXPECT_EQ(1, add_called);
EXPECT_EQ(1, create_called);
EXPECT_EQ(&s1_config, create_config);
stream_list_add(l, &s2_config, &s2);
detect_rtc_stream_pair(l, s2);
stream_list_add(l, &s3_config, &s3);
detect_rtc_stream_pair(l, s3);
stream_list_add(l, &s4_config, &s4);
detect_rtc_stream_pair(l, s4);
EXPECT_EQ(CRAS_STREAM_TYPE_VOICE_COMMUNICATION, s1->stream_type);
EXPECT_EQ(CRAS_STREAM_TYPE_VOICE_COMMUNICATION, s2->stream_type);
EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, s3->stream_type);
EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, s4->stream_type);
EXPECT_EQ(0, stream_list_rm(l, 0x5001));
EXPECT_EQ(0, stream_list_rm(l, 0x5002));
EXPECT_EQ(0, stream_list_rm(l, 0x5003));
EXPECT_EQ(0, stream_list_rm(l, 0x5004));
stream_list_destroy(l);
}
extern "C" {
struct cras_timer* cras_tm_create_timer(struct cras_tm* tm,
unsigned int ms,
void (*cb)(struct cras_timer* t,
void* data),
void* cb_data) {
return reinterpret_cast<struct cras_timer*>(0x404);
}
void cras_tm_cancel_timer(struct cras_tm* tm, struct cras_timer* t) {}
}
} // namespace
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}