1 // Copyright 2015 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 <stdio.h>
7
8 extern "C" {
9 #include "cras_rstream.h"
10 #include "stream_list.h"
11 }
12
13 namespace {
14
15 static unsigned int add_called;
added_cb(struct cras_rstream * rstream)16 static int added_cb(struct cras_rstream* rstream) {
17 add_called++;
18 return 0;
19 }
20
21 static unsigned int rm_called;
22 static struct cras_rstream* rmed_stream;
removed_cb(struct cras_rstream * rstream)23 static int removed_cb(struct cras_rstream* rstream) {
24 rm_called++;
25 rmed_stream = rstream;
26 return 0;
27 }
28
29 static unsigned int create_called;
30 static struct cras_rstream_config* create_config;
create_rstream_cb(struct cras_rstream_config * stream_config,struct cras_rstream ** stream)31 static int create_rstream_cb(struct cras_rstream_config* stream_config,
32 struct cras_rstream** stream) {
33 create_called++;
34 create_config = stream_config;
35 *stream = (struct cras_rstream*)malloc(sizeof(struct cras_rstream));
36 (*stream)->stream_id = stream_config->stream_id;
37 (*stream)->direction = stream_config->direction;
38 if (stream_config->format)
39 (*stream)->format = *(stream_config->format);
40 (*stream)->cb_threshold = stream_config->cb_threshold;
41 (*stream)->client_type = stream_config->client_type;
42 (*stream)->stream_type = stream_config->stream_type;
43 clock_gettime(CLOCK_MONOTONIC_RAW, &(*stream)->start_ts);
44
45 return 0;
46 }
47
48 static unsigned int destroy_called;
49 static struct cras_rstream* destroyed_stream;
destroy_rstream_cb(struct cras_rstream * rstream)50 static void destroy_rstream_cb(struct cras_rstream* rstream) {
51 destroy_called++;
52 destroyed_stream = rstream;
53 free(rstream);
54 }
55
reset_test_data()56 static void reset_test_data() {
57 add_called = 0;
58 rm_called = 0;
59 create_called = 0;
60 destroy_called = 0;
61 }
62
TEST(StreamList,AddRemove)63 TEST(StreamList, AddRemove) {
64 struct stream_list* l;
65 struct cras_rstream* s1;
66 struct cras_rstream_config s1_config;
67
68 s1_config.stream_id = 0x3003;
69 s1_config.direction = CRAS_STREAM_OUTPUT;
70 s1_config.format = NULL;
71
72 reset_test_data();
73 l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
74 destroy_rstream_cb, NULL);
75 stream_list_add(l, &s1_config, &s1);
76 EXPECT_EQ(1, add_called);
77 EXPECT_EQ(1, create_called);
78 EXPECT_EQ(&s1_config, create_config);
79 EXPECT_EQ(0, stream_list_rm(l, 0x3003));
80 EXPECT_EQ(1, rm_called);
81 EXPECT_EQ(s1, rmed_stream);
82 EXPECT_EQ(1, destroy_called);
83 EXPECT_EQ(s1, destroyed_stream);
84 stream_list_destroy(l);
85 }
86
TEST(StreamList,AddInDescendingOrderByChannels)87 TEST(StreamList, AddInDescendingOrderByChannels) {
88 struct stream_list* l;
89 struct cras_rstream* s1;
90 struct cras_rstream* s2;
91 struct cras_rstream* s3;
92 struct cras_audio_format s1_format, s2_format, s3_format;
93 struct cras_rstream_config s1_config, s2_config, s3_config;
94
95 s1_config.stream_id = 0x4001;
96 s1_config.direction = CRAS_STREAM_INPUT;
97 s1_format.num_channels = 6;
98 s1_config.format = &s1_format;
99
100 s2_config.stream_id = 0x4002;
101 s2_config.direction = CRAS_STREAM_OUTPUT;
102 s2_format.num_channels = 8;
103 s2_config.format = &s2_format;
104
105 s3_config.stream_id = 0x4003;
106 s3_config.direction = CRAS_STREAM_OUTPUT;
107 s3_format.num_channels = 2;
108 s3_config.format = &s3_format;
109
110 reset_test_data();
111 l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
112 destroy_rstream_cb, NULL);
113 stream_list_add(l, &s1_config, &s1);
114 EXPECT_EQ(1, add_called);
115 EXPECT_EQ(1, create_called);
116 EXPECT_EQ(6, stream_list_get(l)->format.num_channels);
117
118 stream_list_add(l, &s2_config, &s2);
119 EXPECT_EQ(2, add_called);
120 EXPECT_EQ(2, create_called);
121 EXPECT_EQ(8, stream_list_get(l)->format.num_channels);
122 EXPECT_EQ(6, stream_list_get(l)->next->format.num_channels);
123
124 stream_list_add(l, &s3_config, &s3);
125 EXPECT_EQ(3, add_called);
126 EXPECT_EQ(3, create_called);
127 EXPECT_EQ(8, stream_list_get(l)->format.num_channels);
128 EXPECT_EQ(6, stream_list_get(l)->next->format.num_channels);
129 EXPECT_EQ(2, stream_list_get(l)->next->next->format.num_channels);
130 EXPECT_EQ(0, stream_list_rm(l, 0x4001));
131 EXPECT_EQ(0, stream_list_rm(l, 0x4002));
132 EXPECT_EQ(0, stream_list_rm(l, 0x4003));
133 stream_list_destroy(l);
134 }
135
TEST(StreamList,DetectRtcStreamPair)136 TEST(StreamList, DetectRtcStreamPair) {
137 struct stream_list* l;
138 struct cras_rstream *s1, *s2, *s3, *s4;
139 struct cras_rstream_config s1_config, s2_config, s3_config, s4_config;
140
141 s1_config.stream_id = 0x5001;
142 s1_config.direction = CRAS_STREAM_OUTPUT;
143 s1_config.cb_threshold = 480;
144 s1_config.client_type = CRAS_CLIENT_TYPE_CHROME;
145 s1_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
146 s1_config.format = NULL;
147
148 s2_config.stream_id = 0x5002;
149 s2_config.direction = CRAS_STREAM_INPUT;
150 s2_config.cb_threshold = 480;
151 s2_config.client_type = CRAS_CLIENT_TYPE_CHROME;
152 s2_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
153 s2_config.format = NULL;
154
155 // s3 is not a RTC stream because the cb threshold is not 480.
156 s3_config.stream_id = 0x5003;
157 s3_config.direction = CRAS_STREAM_INPUT;
158 s3_config.cb_threshold = 500;
159 s3_config.client_type = CRAS_CLIENT_TYPE_CHROME;
160 s3_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
161 s3_config.format = NULL;
162
163 // s4 is not a RTC stream because it is not from the same client with s1.
164 s4_config.stream_id = 0x5004;
165 s4_config.direction = CRAS_STREAM_INPUT;
166 s4_config.cb_threshold = 480;
167 s4_config.client_type = CRAS_CLIENT_TYPE_LACROS;
168 s4_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
169 s4_config.format = NULL;
170
171 reset_test_data();
172 l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
173 destroy_rstream_cb, NULL);
174 stream_list_add(l, &s1_config, &s1);
175 EXPECT_EQ(1, add_called);
176 EXPECT_EQ(1, create_called);
177 EXPECT_EQ(&s1_config, create_config);
178
179 stream_list_add(l, &s2_config, &s2);
180 detect_rtc_stream_pair(l, s2);
181 stream_list_add(l, &s3_config, &s3);
182 detect_rtc_stream_pair(l, s3);
183 stream_list_add(l, &s4_config, &s4);
184 detect_rtc_stream_pair(l, s4);
185
186 EXPECT_EQ(CRAS_STREAM_TYPE_VOICE_COMMUNICATION, s1->stream_type);
187 EXPECT_EQ(CRAS_STREAM_TYPE_VOICE_COMMUNICATION, s2->stream_type);
188 EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, s3->stream_type);
189 EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, s4->stream_type);
190
191 EXPECT_EQ(0, stream_list_rm(l, 0x5001));
192 EXPECT_EQ(0, stream_list_rm(l, 0x5002));
193 EXPECT_EQ(0, stream_list_rm(l, 0x5003));
194 EXPECT_EQ(0, stream_list_rm(l, 0x5004));
195 stream_list_destroy(l);
196 }
197
198 extern "C" {
199
cras_tm_create_timer(struct cras_tm * tm,unsigned int ms,void (* cb)(struct cras_timer * t,void * data),void * cb_data)200 struct cras_timer* cras_tm_create_timer(struct cras_tm* tm,
201 unsigned int ms,
202 void (*cb)(struct cras_timer* t,
203 void* data),
204 void* cb_data) {
205 return reinterpret_cast<struct cras_timer*>(0x404);
206 }
207
cras_tm_cancel_timer(struct cras_tm * tm,struct cras_timer * t)208 void cras_tm_cancel_timer(struct cras_tm* tm, struct cras_timer* t) {}
209 }
210
211 } // namespace
212
main(int argc,char ** argv)213 int main(int argc, char** argv) {
214 ::testing::InitGoogleTest(&argc, argv);
215 return RUN_ALL_TESTS();
216 }
217