1 // Copyright (c) 2012 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 <algorithm>
6 #include <stdio.h>
7 #include <gtest/gtest.h>
8 #include <map>
9
10 extern "C" {
11 #include "audio_thread.h"
12 #include "cras_iodev.h"
13 #include "cras_iodev_list.h"
14 #include "cras_observer_ops.h"
15 #include "cras_ramp.h"
16 #include "cras_rstream.h"
17 #include "cras_system_state.h"
18 #include "cras_tm.h"
19 #include "stream_list.h"
20 #include "utlist.h"
21 }
22
23 namespace {
24
25 struct cras_server_state server_state_stub;
26 struct cras_server_state *server_state_update_begin_return;
27
28 /* Data for stubs. */
29 static struct cras_observer_ops *observer_ops;
30 static int add_stream_called;
31 static int rm_stream_called;
32 static unsigned int set_node_attr_called;
33 static cras_iodev *audio_thread_remove_streams_active_dev;
34 static cras_iodev *audio_thread_set_active_dev_val;
35 static int audio_thread_set_active_dev_called;
36 static cras_iodev *audio_thread_add_open_dev_dev;
37 static int audio_thread_add_open_dev_called;
38 static int audio_thread_rm_open_dev_called;
39 static int audio_thread_is_dev_open_ret;
40 static struct audio_thread thread;
41 static struct cras_iodev loopback_input;
42 static int cras_iodev_close_called;
43 static struct cras_iodev *cras_iodev_close_dev;
44 static struct cras_iodev dummy_hotword_iodev;
45 static struct cras_iodev dummy_empty_iodev[2];
46 static stream_callback *stream_add_cb;
47 static stream_callback *stream_rm_cb;
48 static struct cras_rstream *stream_list_get_ret;
49 static int server_stream_create_called;
50 static int server_stream_destroy_called;
51 static int audio_thread_drain_stream_return;
52 static int audio_thread_drain_stream_called;
53 static int cras_tm_create_timer_called;
54 static int cras_tm_cancel_timer_called;
55 static void (*cras_tm_timer_cb)(struct cras_timer *t, void *data);
56 static void *cras_tm_timer_cb_data;
57 static struct timespec clock_gettime_retspec;
58 static struct cras_iodev *device_enabled_dev;
59 static int device_enabled_count;
60 static struct cras_iodev *device_disabled_dev;
61 static int device_disabled_count;
62 static void *device_enabled_cb_data;
63 static void *device_disabled_cb_data;
64 static struct cras_rstream *audio_thread_add_stream_stream;
65 static struct cras_iodev *audio_thread_add_stream_dev;
66 static struct cras_iodev *audio_thread_disconnect_stream_dev;
67 static int audio_thread_add_stream_called;
68 static unsigned update_active_node_called;
69 static struct cras_iodev *update_active_node_iodev_val[5];
70 static unsigned update_active_node_node_idx_val[5];
71 static unsigned update_active_node_dev_enabled_val[5];
72 static size_t cras_observer_add_called;
73 static size_t cras_observer_remove_called;
74 static size_t cras_observer_notify_nodes_called;
75 static size_t cras_observer_notify_active_node_called;
76 static size_t cras_observer_notify_output_node_volume_called;
77 static size_t cras_observer_notify_node_left_right_swapped_called;
78 static size_t cras_observer_notify_input_node_gain_called;
79 static int cras_iodev_open_called;
80 static int cras_iodev_open_ret[8];
81 static int set_mute_called;
82 static std::vector<struct cras_iodev*> set_mute_dev_vector;
83 static struct cras_iodev *audio_thread_dev_start_ramp_dev;
84 static int audio_thread_dev_start_ramp_called;
85 static enum CRAS_IODEV_RAMP_REQUEST audio_thread_dev_start_ramp_req ;
86 static std::map<const struct cras_iodev*, enum CRAS_IODEV_STATE> cras_iodev_state_ret;
87 static std::map<const struct cras_iodev*, int> cras_iodev_has_pinned_stream_ret;
88 static struct cras_rstream *audio_thread_disconnect_stream_stream;
89 static int audio_thread_disconnect_stream_called;
90 static int cras_iodev_is_zero_volume_ret;
91
dummy_update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)92 void dummy_update_active_node(struct cras_iodev *iodev,
93 unsigned node_idx,
94 unsigned dev_enabled) {
95 }
96
device_in_vector(std::vector<struct cras_iodev * > v,struct cras_iodev * dev)97 int device_in_vector(std::vector<struct cras_iodev*> v, struct cras_iodev *dev)
98 {
99 return std::find(v.begin(), v.end(), dev) != v.end();
100 }
101
102 class IoDevTestSuite : public testing::Test {
103 protected:
SetUp()104 virtual void SetUp() {
105 cras_iodev_list_reset();
106
107 cras_iodev_close_called = 0;
108 stream_list_get_ret = 0;
109 server_stream_create_called = 0;
110 server_stream_destroy_called = 0;
111 audio_thread_drain_stream_return = 0;
112 audio_thread_drain_stream_called = 0;
113 cras_tm_create_timer_called = 0;
114 cras_tm_cancel_timer_called = 0;
115
116 audio_thread_disconnect_stream_called = 0;
117 audio_thread_disconnect_stream_stream = NULL;
118 audio_thread_is_dev_open_ret = 0;
119 cras_iodev_has_pinned_stream_ret.clear();
120
121 sample_rates_[0] = 44100;
122 sample_rates_[1] = 48000;
123 sample_rates_[2] = 0;
124
125 channel_counts_[0] = 2;
126 channel_counts_[1] = 0;
127
128 memset(&d1_, 0, sizeof(d1_));
129 memset(&d2_, 0, sizeof(d2_));
130 memset(&d3_, 0, sizeof(d3_));
131
132 memset(&node1, 0, sizeof(node1));
133 memset(&node2, 0, sizeof(node2));
134 memset(&node3, 0, sizeof(node3));
135
136 d1_.set_volume = NULL;
137 d1_.set_capture_gain = NULL;
138 d1_.set_capture_mute = NULL;
139 d1_.update_supported_formats = NULL;
140 d1_.update_active_node = update_active_node;
141 d1_.format = NULL;
142 d1_.direction = CRAS_STREAM_OUTPUT;
143 d1_.info.idx = -999;
144 d1_.nodes = &node1;
145 d1_.active_node = &node1;
146 strcpy(d1_.info.name, "d1");
147 d1_.supported_rates = sample_rates_;
148 d1_.supported_channel_counts = channel_counts_;
149 d2_.set_volume = NULL;
150 d2_.set_capture_gain = NULL;
151 d2_.set_capture_mute = NULL;
152 d2_.update_supported_formats = NULL;
153 d2_.update_active_node = update_active_node;
154 d2_.format = NULL;
155 d2_.direction = CRAS_STREAM_OUTPUT;
156 d2_.info.idx = -999;
157 d2_.nodes = &node2;
158 d2_.active_node = &node2;
159 strcpy(d2_.info.name, "d2");
160 d2_.supported_rates = sample_rates_;
161 d2_.supported_channel_counts = channel_counts_;
162 d3_.set_volume = NULL;
163 d3_.set_capture_gain = NULL;
164 d3_.set_capture_mute = NULL;
165 d3_.update_supported_formats = NULL;
166 d3_.update_active_node = update_active_node;
167 d3_.format = NULL;
168 d3_.direction = CRAS_STREAM_OUTPUT;
169 d3_.info.idx = -999;
170 d3_.nodes = &node3;
171 d3_.active_node = &node3;
172 strcpy(d3_.info.name, "d3");
173 d3_.supported_rates = sample_rates_;
174 d3_.supported_channel_counts = channel_counts_;
175
176 loopback_input.set_volume = NULL;
177 loopback_input.set_capture_gain = NULL;
178 loopback_input.set_capture_mute = NULL;
179 loopback_input.update_supported_formats = NULL;
180 loopback_input.update_active_node = update_active_node;
181 loopback_input.format = NULL;
182 loopback_input.direction = CRAS_STREAM_INPUT;
183 loopback_input.info.idx = -999;
184 loopback_input.nodes = &node3;
185 loopback_input.active_node = &node3;
186 strcpy(loopback_input.info.name, "loopback_input");
187 loopback_input.supported_rates = sample_rates_;
188 loopback_input.supported_channel_counts = channel_counts_;
189
190 server_state_update_begin_return = &server_state_stub;
191
192 /* Reset stub data. */
193 add_stream_called = 0;
194 rm_stream_called = 0;
195 set_node_attr_called = 0;
196 audio_thread_rm_open_dev_called = 0;
197 audio_thread_add_open_dev_called = 0;
198 audio_thread_set_active_dev_called = 0;
199 audio_thread_add_stream_called = 0;
200 update_active_node_called = 0;
201 cras_observer_add_called = 0;
202 cras_observer_remove_called = 0;
203 cras_observer_notify_nodes_called = 0;
204 cras_observer_notify_active_node_called = 0;
205 cras_observer_notify_output_node_volume_called = 0;
206 cras_observer_notify_node_left_right_swapped_called = 0;
207 cras_observer_notify_input_node_gain_called = 0;
208 cras_iodev_open_called = 0;
209 memset(cras_iodev_open_ret, 0, sizeof(cras_iodev_open_ret));
210 set_mute_called = 0;
211 set_mute_dev_vector.clear();
212 audio_thread_dev_start_ramp_dev = NULL;
213 audio_thread_dev_start_ramp_called = 0;
214 audio_thread_dev_start_ramp_req =
215 CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
216 cras_iodev_is_zero_volume_ret = 0;
217
218 dummy_empty_iodev[0].state = CRAS_IODEV_STATE_CLOSE;
219 dummy_empty_iodev[1].state = CRAS_IODEV_STATE_CLOSE;
220 }
221
TearDown()222 virtual void TearDown() {
223 cras_iodev_list_reset();
224 }
225
set_volume_1(struct cras_iodev * iodev)226 static void set_volume_1(struct cras_iodev* iodev) {
227 set_volume_1_called_++;
228 }
229
set_capture_gain_1(struct cras_iodev * iodev)230 static void set_capture_gain_1(struct cras_iodev* iodev) {
231 set_capture_gain_1_called_++;
232 }
233
set_capture_mute_1(struct cras_iodev * iodev)234 static void set_capture_mute_1(struct cras_iodev* iodev) {
235 set_capture_mute_1_called_++;
236 }
237
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)238 static void update_active_node(struct cras_iodev *iodev,
239 unsigned node_idx,
240 unsigned dev_enabled) {
241 int i = update_active_node_called++ % 5;
242 update_active_node_iodev_val[i] = iodev;
243 update_active_node_node_idx_val[i] = node_idx;
244 update_active_node_dev_enabled_val[i] = dev_enabled;
245 }
246
247 struct cras_iodev d1_;
248 struct cras_iodev d2_;
249 struct cras_iodev d3_;
250 size_t sample_rates_[3];
251 size_t channel_counts_[2];
252 static int set_volume_1_called_;
253 static int set_capture_gain_1_called_;
254 static int set_capture_mute_1_called_;
255 struct cras_ionode node1, node2, node3;
256 };
257
258 int IoDevTestSuite::set_volume_1_called_;
259 int IoDevTestSuite::set_capture_gain_1_called_;
260 int IoDevTestSuite::set_capture_mute_1_called_;
261
262 // Check that Init registers observer client. */
TEST_F(IoDevTestSuite,InitSetup)263 TEST_F(IoDevTestSuite, InitSetup) {
264 cras_iodev_list_init();
265 EXPECT_EQ(1, cras_observer_add_called);
266 cras_iodev_list_deinit();
267 EXPECT_EQ(1, cras_observer_remove_called);
268 }
269
270 /* Check that the suspend alert from cras_system will trigger suspend
271 * and resume call of all iodevs. */
TEST_F(IoDevTestSuite,SetSuspendResume)272 TEST_F(IoDevTestSuite, SetSuspendResume) {
273 struct cras_rstream rstream, rstream2, rstream3;
274 struct cras_rstream *stream_list = NULL;
275 int rc;
276
277 memset(&rstream, 0, sizeof(rstream));
278 memset(&rstream2, 0, sizeof(rstream2));
279 memset(&rstream3, 0, sizeof(rstream3));
280
281 cras_iodev_list_init();
282
283 d1_.direction = CRAS_STREAM_OUTPUT;
284 rc = cras_iodev_list_add_output(&d1_);
285 ASSERT_EQ(0, rc);
286
287 audio_thread_add_open_dev_called = 0;
288 cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
289 cras_make_node_id(d1_.info.idx, 1));
290 DL_APPEND(stream_list, &rstream);
291 stream_add_cb(&rstream);
292 EXPECT_EQ(1, audio_thread_add_stream_called);
293 EXPECT_EQ(1, audio_thread_add_open_dev_called);
294
295 DL_APPEND(stream_list, &rstream2);
296 stream_add_cb(&rstream2);
297 EXPECT_EQ(2, audio_thread_add_stream_called);
298
299 audio_thread_rm_open_dev_called = 0;
300 observer_ops->suspend_changed(NULL, 1);
301 EXPECT_EQ(1, audio_thread_rm_open_dev_called);
302
303 /* Test disable/enable dev won't cause add_stream to audio_thread. */
304 audio_thread_add_stream_called = 0;
305 cras_iodev_list_disable_dev(&d1_, false);
306 cras_iodev_list_enable_dev(&d1_);
307 EXPECT_EQ(0, audio_thread_add_stream_called);
308
309 audio_thread_drain_stream_return = 0;
310 DL_DELETE(stream_list, &rstream2);
311 stream_rm_cb(&rstream2);
312 EXPECT_EQ(1, audio_thread_drain_stream_called);
313
314 /* Test stream_add_cb won't cause add_stream to audio_thread. */
315 audio_thread_add_stream_called = 0;
316 DL_APPEND(stream_list, &rstream3);
317 stream_add_cb(&rstream3);
318 EXPECT_EQ(0, audio_thread_add_stream_called);
319
320 audio_thread_add_open_dev_called = 0;
321 audio_thread_add_stream_called = 0;
322 stream_list_get_ret = stream_list;
323 observer_ops->suspend_changed(NULL, 0);
324 EXPECT_EQ(1, audio_thread_add_open_dev_called);
325 EXPECT_EQ(2, audio_thread_add_stream_called);
326 EXPECT_EQ(&rstream3, audio_thread_add_stream_stream);
327
328 cras_iodev_list_deinit();
329 EXPECT_EQ(3, cras_observer_notify_active_node_called);
330 }
331
TEST_F(IoDevTestSuite,InitDevFailShouldEnableFallback)332 TEST_F(IoDevTestSuite, InitDevFailShouldEnableFallback) {
333 int rc;
334 struct cras_rstream rstream;
335 struct cras_rstream *stream_list = NULL;
336
337 memset(&rstream, 0, sizeof(rstream));
338 cras_iodev_list_init();
339
340 d1_.direction = CRAS_STREAM_OUTPUT;
341 rc = cras_iodev_list_add_output(&d1_);
342 ASSERT_EQ(0, rc);
343
344 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
345 cras_make_node_id(d1_.info.idx, 0));
346
347 cras_iodev_open_ret[0] = -5;
348 cras_iodev_open_ret[1] = 0;
349
350 DL_APPEND(stream_list, &rstream);
351 stream_list_get_ret = stream_list;
352 stream_add_cb(&rstream);
353 /* open dev called twice, one for fallback device. */
354 EXPECT_EQ(2, cras_iodev_open_called);
355 EXPECT_EQ(1, audio_thread_add_stream_called);
356 cras_iodev_list_deinit();
357 }
358
TEST_F(IoDevTestSuite,InitDevWithEchoRef)359 TEST_F(IoDevTestSuite, InitDevWithEchoRef) {
360 int rc;
361 struct cras_rstream rstream;
362 struct cras_rstream *stream_list = NULL;
363
364 memset(&rstream, 0, sizeof(rstream));
365 cras_iodev_list_init();
366
367 d1_.direction = CRAS_STREAM_OUTPUT;
368 d1_.echo_reference_dev = &d2_;
369 rc = cras_iodev_list_add_output(&d1_);
370 ASSERT_EQ(0, rc);
371
372 d2_.direction = CRAS_STREAM_INPUT;
373 snprintf(d2_.active_node->name, CRAS_NODE_NAME_BUFFER_SIZE, "echo ref");
374 rc = cras_iodev_list_add_input(&d2_);
375 ASSERT_EQ(0, rc);
376
377 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
378 cras_make_node_id(d1_.info.idx, 0));
379 /* No close call happened, because no stream exists. */
380 EXPECT_EQ(0, cras_iodev_close_called);
381
382 cras_iodev_open_ret[1] = 0;
383
384 DL_APPEND(stream_list, &rstream);
385 stream_list_get_ret = stream_list;
386 stream_add_cb(&rstream);
387
388 EXPECT_EQ(1, cras_iodev_open_called);
389 EXPECT_EQ(1, server_stream_create_called);
390 EXPECT_EQ(1, audio_thread_add_stream_called);
391
392 DL_DELETE(stream_list, &rstream);
393 stream_list_get_ret = stream_list;
394 stream_rm_cb(&rstream);
395
396 clock_gettime_retspec.tv_sec = 11;
397 clock_gettime_retspec.tv_nsec = 0;
398 cras_tm_timer_cb(NULL, NULL);
399
400 EXPECT_EQ(1, cras_iodev_close_called);
401 EXPECT_EQ(1, server_stream_destroy_called);
402
403 cras_iodev_list_deinit();
404 }
405
TEST_F(IoDevTestSuite,SelectNodeOpenFailShouldScheduleRetry)406 TEST_F(IoDevTestSuite, SelectNodeOpenFailShouldScheduleRetry) {
407 struct cras_rstream rstream;
408 struct cras_rstream *stream_list = NULL;
409 int rc;
410
411 memset(&rstream, 0, sizeof(rstream));
412 cras_iodev_list_init();
413
414 d1_.direction = CRAS_STREAM_OUTPUT;
415 rc = cras_iodev_list_add_output(&d1_);
416 ASSERT_EQ(0, rc);
417
418 d2_.direction = CRAS_STREAM_OUTPUT;
419 rc = cras_iodev_list_add_output(&d2_);
420 ASSERT_EQ(0, rc);
421
422 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
423 cras_make_node_id(d1_.info.idx, 1));
424 DL_APPEND(stream_list, &rstream);
425 stream_list_get_ret = stream_list;
426 stream_add_cb(&rstream);
427
428 /* Select node triggers: fallback open, d1 close, d2 open, fallback close. */
429 cras_iodev_close_called = 0;
430 cras_iodev_open_called = 0;
431 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
432 cras_make_node_id(d2_.info.idx, 1));
433 EXPECT_EQ(2, cras_iodev_close_called);
434 EXPECT_EQ(2, cras_iodev_open_called);
435 EXPECT_EQ(0, cras_tm_create_timer_called);
436 EXPECT_EQ(0, cras_tm_cancel_timer_called);
437
438 /* Test that if select to d1 and open d1 fail, fallback doesn't close. */
439 cras_iodev_open_called = 0;
440 cras_iodev_open_ret[0] = 0;
441 cras_iodev_open_ret[1] = -5;
442 cras_iodev_open_ret[2] = 0;
443 cras_tm_timer_cb = NULL;
444 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
445 cras_make_node_id(d1_.info.idx, 1));
446 EXPECT_EQ(3, cras_iodev_close_called);
447 EXPECT_EQ(&d2_, cras_iodev_close_dev);
448 EXPECT_EQ(2, cras_iodev_open_called);
449 EXPECT_EQ(0, cras_tm_cancel_timer_called);
450
451 /* Assert a timer is scheduled to retry open. */
452 EXPECT_NE((void *)NULL, cras_tm_timer_cb);
453 EXPECT_EQ(1, cras_tm_create_timer_called);
454
455 audio_thread_add_stream_called = 0;
456 cras_tm_timer_cb(NULL, cras_tm_timer_cb_data);
457 EXPECT_EQ(3, cras_iodev_open_called);
458 EXPECT_EQ(1, audio_thread_add_stream_called);
459
460 /* Retry open success will close fallback dev. */
461 EXPECT_EQ(4, cras_iodev_close_called);
462 EXPECT_EQ(0, cras_tm_cancel_timer_called);
463
464 /* Select to d2 and fake an open failure. */
465 cras_iodev_close_called = 0;
466 cras_iodev_open_called = 0;
467 cras_iodev_open_ret[0] = 0;
468 cras_iodev_open_ret[1] = -5;
469 cras_iodev_open_ret[2] = 0;
470 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
471 cras_make_node_id(d2_.info.idx, 1));
472 EXPECT_EQ(1, cras_iodev_close_called);
473 EXPECT_EQ(&d1_, cras_iodev_close_dev);
474 EXPECT_EQ(2, cras_tm_create_timer_called);
475 EXPECT_NE((void *)NULL, cras_tm_timer_cb);
476
477 /* Select to another iodev should cancel the timer. */
478 memset(cras_iodev_open_ret, 0, sizeof(cras_iodev_open_ret));
479 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
480 cras_make_node_id(d2_.info.idx, 1));
481 EXPECT_EQ(1, cras_tm_cancel_timer_called);
482 cras_iodev_list_deinit();
483 }
484
TEST_F(IoDevTestSuite,InitDevFailShouldScheduleRetry)485 TEST_F(IoDevTestSuite, InitDevFailShouldScheduleRetry) {
486 int rc;
487 struct cras_rstream rstream;
488 struct cras_rstream *stream_list = NULL;
489
490 memset(&rstream, 0, sizeof(rstream));
491 cras_iodev_list_init();
492
493 d1_.direction = CRAS_STREAM_OUTPUT;
494 rc = cras_iodev_list_add_output(&d1_);
495 ASSERT_EQ(0, rc);
496
497 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
498 cras_make_node_id(d1_.info.idx, 0));
499
500 cras_iodev_open_ret[0] = -5;
501 cras_iodev_open_ret[1] = 0;
502 cras_tm_timer_cb = NULL;
503 DL_APPEND(stream_list, &rstream);
504 stream_list_get_ret = stream_list;
505 stream_add_cb(&rstream);
506 /* open dev called twice, one for fallback device. */
507 EXPECT_EQ(2, cras_iodev_open_called);
508 EXPECT_EQ(1, audio_thread_add_stream_called);
509
510 EXPECT_NE((void *)NULL, cras_tm_timer_cb);
511 EXPECT_EQ(1, cras_tm_create_timer_called);
512
513 /* If retry still fail, won't schedule more retry. */
514 cras_iodev_open_ret[2] = -5;
515 cras_tm_timer_cb(NULL, cras_tm_timer_cb_data);
516 EXPECT_EQ(1, cras_tm_create_timer_called);
517 EXPECT_EQ(1, audio_thread_add_stream_called);
518
519 cras_tm_timer_cb = NULL;
520 cras_iodev_open_ret[3] = -5;
521 stream_add_cb(&rstream);
522 EXPECT_NE((void *)NULL, cras_tm_timer_cb);
523 EXPECT_EQ(2, cras_tm_create_timer_called);
524
525 cras_iodev_list_rm_output(&d1_);
526 EXPECT_EQ(1, cras_tm_cancel_timer_called);
527 cras_iodev_list_deinit();
528 }
529
TEST_F(IoDevTestSuite,PinnedStreamInitFailShouldScheduleRetry)530 TEST_F(IoDevTestSuite, PinnedStreamInitFailShouldScheduleRetry) {
531 int rc;
532 struct cras_rstream rstream;
533 struct cras_rstream *stream_list = NULL;
534
535 memset(&rstream, 0, sizeof(rstream));
536 cras_iodev_list_init();
537
538 d1_.direction = CRAS_STREAM_OUTPUT;
539 rc = cras_iodev_list_add_output(&d1_);
540 ASSERT_EQ(0, rc);
541
542 rstream.is_pinned = 1;
543 rstream.pinned_dev_idx = d1_.info.idx;
544
545 cras_iodev_open_ret[0] = -5;
546 cras_iodev_open_ret[1] = 0;
547 cras_tm_timer_cb = NULL;
548 DL_APPEND(stream_list, &rstream);
549 stream_list_get_ret = stream_list;
550 stream_add_cb(&rstream);
551 /* Init pinned dev fail, not proceed to add stream. */
552 EXPECT_EQ(1, cras_iodev_open_called);
553 EXPECT_EQ(0, audio_thread_add_stream_called);
554
555 EXPECT_NE((void *)NULL, cras_tm_timer_cb);
556 EXPECT_EQ(1, cras_tm_create_timer_called);
557
558 cras_tm_timer_cb(NULL, cras_tm_timer_cb_data);
559 EXPECT_EQ(2, cras_iodev_open_called);
560 EXPECT_EQ(1, audio_thread_add_stream_called);
561
562 cras_iodev_list_rm_output(&d1_);
563 cras_iodev_list_deinit();
564 }
565
device_enabled_cb(struct cras_iodev * dev,void * cb_data)566 static void device_enabled_cb(struct cras_iodev *dev, void *cb_data)
567 {
568 device_enabled_dev = dev;
569 device_enabled_count++;
570 device_enabled_cb_data = cb_data;
571 }
572
device_disabled_cb(struct cras_iodev * dev,void * cb_data)573 static void device_disabled_cb(struct cras_iodev *dev, void *cb_data)
574 {
575 device_disabled_dev = dev;
576 device_disabled_count++;
577 device_disabled_cb_data = cb_data;
578 }
579
TEST_F(IoDevTestSuite,SelectNode)580 TEST_F(IoDevTestSuite, SelectNode) {
581 struct cras_rstream rstream, rstream2;
582 int rc;
583
584 memset(&rstream, 0, sizeof(rstream));
585 memset(&rstream2, 0, sizeof(rstream2));
586
587 cras_iodev_list_init();
588
589 d1_.direction = CRAS_STREAM_OUTPUT;
590 node1.idx = 1;
591 rc = cras_iodev_list_add_output(&d1_);
592 ASSERT_EQ(0, rc);
593
594 d2_.direction = CRAS_STREAM_OUTPUT;
595 node2.idx = 2;
596 rc = cras_iodev_list_add_output(&d2_);
597 ASSERT_EQ(0, rc);
598
599 audio_thread_add_open_dev_called = 0;
600 audio_thread_rm_open_dev_called = 0;
601
602 device_enabled_count = 0;
603 device_disabled_count = 0;
604
605 EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(
606 device_enabled_cb, device_disabled_cb, (void *)0xABCD));
607
608 cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
609 cras_make_node_id(d1_.info.idx, 1));
610
611 EXPECT_EQ(1, device_enabled_count);
612 EXPECT_EQ(1, cras_observer_notify_active_node_called);
613 EXPECT_EQ(&d1_, cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT));
614
615 // There should be a disable device call for the fallback device.
616 // But no close call actually happened, because no stream exists.
617 EXPECT_EQ(0, audio_thread_rm_open_dev_called);
618 EXPECT_EQ(1, device_disabled_count);
619 EXPECT_NE(&d1_, device_disabled_dev);
620
621 DL_APPEND(stream_list_get_ret, &rstream);
622 stream_add_cb(&rstream);
623
624 EXPECT_EQ(1, audio_thread_add_stream_called);
625 EXPECT_EQ(1, audio_thread_add_open_dev_called);
626
627 DL_APPEND(stream_list_get_ret, &rstream2);
628 stream_add_cb(&rstream2);
629
630 EXPECT_EQ(2, audio_thread_add_stream_called);
631 EXPECT_EQ(1, audio_thread_add_open_dev_called);
632
633 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
634 cras_make_node_id(d2_.info.idx, 2));
635
636 // Additional enabled devices: fallback device, d2_.
637 EXPECT_EQ(3, device_enabled_count);
638 // Additional disabled devices: d1_, fallback device.
639 EXPECT_EQ(3, device_disabled_count);
640 EXPECT_EQ(2, audio_thread_rm_open_dev_called);
641 EXPECT_EQ(2, cras_observer_notify_active_node_called);
642 EXPECT_EQ(&d2_, cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT));
643
644 // For each stream, the stream is added for fallback device and d2_.
645 EXPECT_EQ(6, audio_thread_add_stream_called);
646
647 EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(NULL, NULL, NULL));
648 cras_iodev_list_deinit();
649 }
650
TEST_F(IoDevTestSuite,SelectPreviouslyEnabledNode)651 TEST_F(IoDevTestSuite, SelectPreviouslyEnabledNode) {
652 struct cras_rstream rstream;
653 int rc;
654
655 memset(&rstream, 0, sizeof(rstream));
656
657 cras_iodev_list_init();
658
659 d1_.direction = CRAS_STREAM_OUTPUT;
660 node1.idx = 1;
661 rc = cras_iodev_list_add_output(&d1_);
662 ASSERT_EQ(0, rc);
663
664 d2_.direction = CRAS_STREAM_OUTPUT;
665 node2.idx = 2;
666 rc = cras_iodev_list_add_output(&d2_);
667 ASSERT_EQ(0, rc);
668
669 audio_thread_add_open_dev_called = 0;
670 audio_thread_rm_open_dev_called = 0;
671 device_enabled_count = 0;
672 device_disabled_count = 0;
673
674 EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(
675 device_enabled_cb, device_disabled_cb, (void *)0xABCD));
676
677 // Add an active node.
678 cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
679 cras_make_node_id(d1_.info.idx, 1));
680
681 EXPECT_EQ(1, device_enabled_count);
682 EXPECT_EQ(1, cras_observer_notify_active_node_called);
683 EXPECT_EQ(&d1_, cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT));
684
685 // There should be a disable device call for the fallback device.
686 EXPECT_EQ(1, device_disabled_count);
687 EXPECT_NE(&d1_, device_disabled_dev);
688 EXPECT_NE(&d2_, device_disabled_dev);
689
690 DL_APPEND(stream_list_get_ret, &rstream);
691 stream_add_cb(&rstream);
692
693 EXPECT_EQ(1, audio_thread_add_open_dev_called);
694 EXPECT_EQ(1, audio_thread_add_stream_called);
695
696 // Add a second active node.
697 cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
698 cras_make_node_id(d2_.info.idx, 2));
699
700 EXPECT_EQ(2, device_enabled_count);
701 EXPECT_EQ(1, device_disabled_count);
702 EXPECT_EQ(2, cras_observer_notify_active_node_called);
703 EXPECT_EQ(&d1_, cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT));
704
705 EXPECT_EQ(2, audio_thread_add_open_dev_called);
706 EXPECT_EQ(2, audio_thread_add_stream_called);
707 EXPECT_EQ(0, audio_thread_rm_open_dev_called);
708
709 // Select the second added active node - the initially added node should get
710 // disabled.
711 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
712 cras_make_node_id(d2_.info.idx, 2));
713
714 EXPECT_EQ(2, device_enabled_count);
715 EXPECT_EQ(2, device_disabled_count);
716 EXPECT_EQ(3, cras_observer_notify_active_node_called);
717
718 EXPECT_EQ(&d2_, cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT));
719 EXPECT_EQ(&d1_, device_disabled_dev);
720
721 EXPECT_EQ(2, audio_thread_add_stream_called);
722 EXPECT_EQ(2, audio_thread_add_open_dev_called);
723 EXPECT_EQ(1, audio_thread_rm_open_dev_called);
724
725 EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(NULL, NULL, NULL));
726 cras_iodev_list_deinit();
727 }
728
TEST_F(IoDevTestSuite,UpdateActiveNode)729 TEST_F(IoDevTestSuite, UpdateActiveNode) {
730 int rc;
731
732 cras_iodev_list_init();
733
734 d1_.direction = CRAS_STREAM_OUTPUT;
735 rc = cras_iodev_list_add_output(&d1_);
736 ASSERT_EQ(0, rc);
737
738 d2_.direction = CRAS_STREAM_OUTPUT;
739 rc = cras_iodev_list_add_output(&d2_);
740 ASSERT_EQ(0, rc);
741
742 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
743 cras_make_node_id(d2_.info.idx, 1));
744
745 EXPECT_EQ(1, update_active_node_called);
746 EXPECT_EQ(&d2_, update_active_node_iodev_val[0]);
747 EXPECT_EQ(1, update_active_node_node_idx_val[0]);
748 EXPECT_EQ(1, update_active_node_dev_enabled_val[0]);
749
750 /* Fake the active node idx on d2_, and later assert this node is
751 * called for update_active_node when d2_ disabled. */
752 d2_.active_node->idx = 2;
753 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
754 cras_make_node_id(d1_.info.idx, 0));
755
756 EXPECT_EQ(3, update_active_node_called);
757 EXPECT_EQ(&d2_, update_active_node_iodev_val[1]);
758 EXPECT_EQ(&d1_, update_active_node_iodev_val[2]);
759 EXPECT_EQ(2, update_active_node_node_idx_val[1]);
760 EXPECT_EQ(0, update_active_node_node_idx_val[2]);
761 EXPECT_EQ(0, update_active_node_dev_enabled_val[1]);
762 EXPECT_EQ(1, update_active_node_dev_enabled_val[2]);
763 EXPECT_EQ(2, cras_observer_notify_active_node_called);
764 cras_iodev_list_deinit();
765 }
766
TEST_F(IoDevTestSuite,SelectNonExistingNode)767 TEST_F(IoDevTestSuite, SelectNonExistingNode) {
768 int rc;
769 cras_iodev_list_init();
770
771 d1_.direction = CRAS_STREAM_OUTPUT;
772 rc = cras_iodev_list_add_output(&d1_);
773 ASSERT_EQ(0, rc);
774
775 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
776 cras_make_node_id(d1_.info.idx, 0));
777 EXPECT_EQ(1, d1_.is_enabled);
778
779 /* Select non-existing node should disable all devices. */
780 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
781 cras_make_node_id(2, 1));
782 EXPECT_EQ(0, d1_.is_enabled);
783 EXPECT_EQ(2, cras_observer_notify_active_node_called);
784 cras_iodev_list_deinit();
785 }
786
787 // Devices with the wrong direction should be rejected.
TEST_F(IoDevTestSuite,AddWrongDirection)788 TEST_F(IoDevTestSuite, AddWrongDirection) {
789 int rc;
790
791 rc = cras_iodev_list_add_input(&d1_);
792 EXPECT_EQ(-EINVAL, rc);
793 d1_.direction = CRAS_STREAM_INPUT;
794 rc = cras_iodev_list_add_output(&d1_);
795 EXPECT_EQ(-EINVAL, rc);
796 }
797
798 // Test adding/removing an iodev to the list.
TEST_F(IoDevTestSuite,AddRemoveOutput)799 TEST_F(IoDevTestSuite, AddRemoveOutput) {
800 struct cras_iodev_info *dev_info;
801 int rc;
802
803 rc = cras_iodev_list_add_output(&d1_);
804 EXPECT_EQ(0, rc);
805 // Test can't insert same iodev twice.
806 rc = cras_iodev_list_add_output(&d1_);
807 EXPECT_NE(0, rc);
808 // Test insert a second output.
809 rc = cras_iodev_list_add_output(&d2_);
810 EXPECT_EQ(0, rc);
811
812 // Test that it is removed.
813 rc = cras_iodev_list_rm_output(&d1_);
814 EXPECT_EQ(0, rc);
815 // Test that we can't remove a dev twice.
816 rc = cras_iodev_list_rm_output(&d1_);
817 EXPECT_NE(0, rc);
818 // Should be 1 dev now.
819 rc = cras_iodev_list_get_outputs(&dev_info);
820 EXPECT_EQ(1, rc);
821 free(dev_info);
822 // Passing null should return the number of outputs.
823 rc = cras_iodev_list_get_outputs(NULL);
824 EXPECT_EQ(1, rc);
825 // Remove other dev.
826 rc = cras_iodev_list_rm_output(&d2_);
827 EXPECT_EQ(0, rc);
828 // Should be 0 devs now.
829 rc = cras_iodev_list_get_outputs(&dev_info);
830 EXPECT_EQ(0, rc);
831 free(dev_info);
832 EXPECT_EQ(0, cras_observer_notify_active_node_called);
833 }
834
835 // Test output_mute_changed callback.
TEST_F(IoDevTestSuite,OutputMuteChangedToMute)836 TEST_F(IoDevTestSuite, OutputMuteChangedToMute) {
837 cras_iodev_list_init();
838
839 // d1_ and d3_ have ramp while d2_ does not have ramp.
840 d1_.ramp = reinterpret_cast<cras_ramp*>(0x123);
841 d2_.ramp = NULL;
842 d3_.ramp = reinterpret_cast<cras_ramp*>(0x124);
843
844 cras_iodev_list_add_output(&d1_);
845 cras_iodev_list_add_output(&d2_);
846 cras_iodev_list_add_output(&d3_);
847
848 // d1_ and d2_ are enabled.
849 cras_iodev_list_enable_dev(&d1_);
850 cras_iodev_list_enable_dev(&d2_);
851
852 // Assume d1 and d2 devices are in normal run.
853 cras_iodev_state_ret[&d1_] = CRAS_IODEV_STATE_NORMAL_RUN;
854 cras_iodev_state_ret[&d2_] = CRAS_IODEV_STATE_NORMAL_RUN;
855 cras_iodev_state_ret[&d3_] = CRAS_IODEV_STATE_CLOSE;
856
857 // Execute the callback.
858 observer_ops->output_mute_changed(NULL, 0, 1, 0);
859
860 // d1_ should set mute state through audio_thread_dev_start_ramp.
861 EXPECT_EQ(&d1_, audio_thread_dev_start_ramp_dev);
862 EXPECT_EQ(1, audio_thread_dev_start_ramp_called);
863 EXPECT_EQ(CRAS_IODEV_RAMP_REQUEST_DOWN_MUTE, audio_thread_dev_start_ramp_req);
864
865 // d2_ should set mute state right away.
866 // d3_ should set mute state right away without calling ramp
867 // because it is not enabled.
868 EXPECT_EQ(2, set_mute_called);
869 EXPECT_EQ(2, set_mute_dev_vector.size());
870 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d2_));
871 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d3_));
872
873 // Assume d1_ should mute for volume.
874 // It should not use ramp.
875 cras_iodev_is_zero_volume_ret = 1;
876
877 // Clear stub data of interest.
878 audio_thread_dev_start_ramp_dev = NULL;
879 audio_thread_dev_start_ramp_called = 0;
880 set_mute_called = 0;
881 set_mute_dev_vector.clear();
882
883 // Execute the callback.
884 observer_ops->output_mute_changed(NULL, 0, 1, 0);
885
886 // Verify three devices all set mute state right away.
887 EXPECT_EQ(NULL, audio_thread_dev_start_ramp_dev);
888 EXPECT_EQ(0, audio_thread_dev_start_ramp_called);
889 EXPECT_EQ(3, set_mute_called);
890 EXPECT_EQ(3, set_mute_dev_vector.size());
891 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d1_));
892 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d2_));
893 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d3_));
894
895 // Assume d1_ is changed to no_stream run state
896 // It should not use ramp.
897 cras_iodev_state_ret[&d1_] = CRAS_IODEV_STATE_NO_STREAM_RUN;
898
899 // Clear stub data of interest.
900 audio_thread_dev_start_ramp_dev = NULL;
901 audio_thread_dev_start_ramp_called = 0;
902 set_mute_called = 0;
903 set_mute_dev_vector.clear();
904
905 // Execute the callback.
906 observer_ops->output_mute_changed(NULL, 0, 1, 0);
907
908 // Verify three devices all set mute state right away.
909 EXPECT_EQ(NULL, audio_thread_dev_start_ramp_dev);
910 EXPECT_EQ(0, audio_thread_dev_start_ramp_called);
911 EXPECT_EQ(3, set_mute_called);
912 EXPECT_EQ(3, set_mute_dev_vector.size());
913 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d1_));
914 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d2_));
915 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d3_));
916 cras_iodev_list_deinit();
917 }
918
919 // Test output_mute_changed callback.
TEST_F(IoDevTestSuite,OutputMuteChangedToUnmute)920 TEST_F(IoDevTestSuite, OutputMuteChangedToUnmute) {
921 cras_iodev_list_init();
922
923 // d1_ and d3_ have ramp while d2_ does not have ramp.
924 d1_.ramp = reinterpret_cast<cras_ramp*>(0x123);
925 d2_.ramp = NULL;
926 d3_.ramp = reinterpret_cast<cras_ramp*>(0x124);
927
928 cras_iodev_list_add_output(&d1_);
929 cras_iodev_list_add_output(&d2_);
930 cras_iodev_list_add_output(&d3_);
931
932 // d1_ and d2_ are enabled.
933 cras_iodev_list_enable_dev(&d1_);
934 cras_iodev_list_enable_dev(&d2_);
935
936 // Assume d1 and d2 devices are in normal run.
937 cras_iodev_state_ret[&d1_] = CRAS_IODEV_STATE_NORMAL_RUN;
938 cras_iodev_state_ret[&d2_] = CRAS_IODEV_STATE_NORMAL_RUN;
939 cras_iodev_state_ret[&d3_] = CRAS_IODEV_STATE_CLOSE;
940
941 // Execute the callback.
942 observer_ops->output_mute_changed(NULL, 0, 0, 0);
943
944 // d1_ should set mute state through audio_thread_dev_start_ramp.
945 EXPECT_EQ(&d1_, audio_thread_dev_start_ramp_dev);
946 EXPECT_EQ(1, audio_thread_dev_start_ramp_called);
947 EXPECT_EQ(CRAS_IODEV_RAMP_REQUEST_UP_UNMUTE,
948 audio_thread_dev_start_ramp_req);
949
950 // d2_ should set mute state right away.
951 // d3_ should set mute state right away without calling ramp
952 // because it is not enabled.
953 EXPECT_EQ(2, set_mute_called);
954 EXPECT_EQ(2, set_mute_dev_vector.size());
955 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d2_));
956 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d3_));
957
958 // Assume d1_ should mute for volume.
959 // It should not use ramp.
960 cras_iodev_is_zero_volume_ret = 1;
961
962 // Clear stub data of interest.
963 audio_thread_dev_start_ramp_dev = NULL;
964 audio_thread_dev_start_ramp_called = 0;
965 set_mute_called = 0;
966 set_mute_dev_vector.clear();
967
968 // Execute the callback.
969 observer_ops->output_mute_changed(NULL, 0, 1, 0);
970
971 // Verify three devices all set mute state right away.
972 EXPECT_EQ(NULL, audio_thread_dev_start_ramp_dev);
973 EXPECT_EQ(0, audio_thread_dev_start_ramp_called);
974 EXPECT_EQ(3, set_mute_called);
975 EXPECT_EQ(3, set_mute_dev_vector.size());
976 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d1_));
977 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d2_));
978 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d3_));
979
980 // Assume d1_ is changed to no_stream run state
981 // It should not use ramp.
982 cras_iodev_state_ret[&d1_] = CRAS_IODEV_STATE_NO_STREAM_RUN;
983
984 // Clear stub data of interest.
985 audio_thread_dev_start_ramp_dev = NULL;
986 audio_thread_dev_start_ramp_called = 0;
987 set_mute_called = 0;
988 set_mute_dev_vector.clear();
989
990 // Execute the callback.
991 observer_ops->output_mute_changed(NULL, 0, 1, 0);
992
993 // Verify three devices all set mute state right away.
994 EXPECT_EQ(NULL, audio_thread_dev_start_ramp_dev);
995 EXPECT_EQ(0, audio_thread_dev_start_ramp_called);
996 EXPECT_EQ(3, set_mute_called);
997 EXPECT_EQ(3, set_mute_dev_vector.size());
998 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d1_));
999 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d2_));
1000 ASSERT_TRUE(device_in_vector(set_mute_dev_vector, &d3_));
1001 cras_iodev_list_deinit();
1002 }
1003
1004 // Test enable/disable an iodev.
TEST_F(IoDevTestSuite,EnableDisableDevice)1005 TEST_F(IoDevTestSuite, EnableDisableDevice) {
1006 device_enabled_count = 0;
1007 device_disabled_count = 0;
1008
1009 EXPECT_EQ(0, cras_iodev_list_add_output(&d1_));
1010
1011 EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(
1012 device_enabled_cb, device_disabled_cb, (void *)0xABCD));
1013
1014 // Enable a device.
1015 cras_iodev_list_enable_dev(&d1_);
1016 EXPECT_EQ(&d1_, device_enabled_dev);
1017 EXPECT_EQ((void *)0xABCD, device_enabled_cb_data);
1018 EXPECT_EQ(1, device_enabled_count);
1019 EXPECT_EQ(&d1_, cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT));
1020
1021 // Disable a device.
1022 cras_iodev_list_disable_dev(&d1_, false);
1023 EXPECT_EQ(&d1_, device_disabled_dev);
1024 EXPECT_EQ(1, device_disabled_count);
1025 EXPECT_EQ((void *)0xABCD, device_disabled_cb_data);
1026
1027 EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(
1028 device_enabled_cb, device_disabled_cb, (void *)0xCDEF));
1029 EXPECT_EQ(2, cras_observer_notify_active_node_called);
1030
1031 EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(NULL, NULL, NULL));
1032 }
1033
1034 // Test adding/removing an input dev to the list.
TEST_F(IoDevTestSuite,AddRemoveInput)1035 TEST_F(IoDevTestSuite, AddRemoveInput) {
1036 struct cras_iodev_info *dev_info;
1037 int rc, i;
1038 uint32_t found_mask;
1039
1040 d1_.direction = CRAS_STREAM_INPUT;
1041 d2_.direction = CRAS_STREAM_INPUT;
1042
1043 cras_iodev_list_init();
1044
1045 // Check no devices exist initially.
1046 rc = cras_iodev_list_get_inputs(NULL);
1047 EXPECT_EQ(0, rc);
1048
1049 rc = cras_iodev_list_add_input(&d1_);
1050 EXPECT_EQ(0, rc);
1051 EXPECT_GE(d1_.info.idx, 0);
1052 // Test can't insert same iodev twice.
1053 rc = cras_iodev_list_add_input(&d1_);
1054 EXPECT_NE(0, rc);
1055 // Test insert a second input.
1056 rc = cras_iodev_list_add_input(&d2_);
1057 EXPECT_EQ(0, rc);
1058 EXPECT_GE(d2_.info.idx, 1);
1059 // make sure shared state was updated.
1060 EXPECT_EQ(2, server_state_stub.num_input_devs);
1061 EXPECT_EQ(d2_.info.idx, server_state_stub.input_devs[0].idx);
1062 EXPECT_EQ(d1_.info.idx, server_state_stub.input_devs[1].idx);
1063
1064 // List the outputs.
1065 rc = cras_iodev_list_get_inputs(&dev_info);
1066 EXPECT_EQ(2, rc);
1067 if (rc == 2) {
1068 found_mask = 0;
1069 for (i = 0; i < rc; i++) {
1070 uint32_t idx = dev_info[i].idx;
1071 EXPECT_EQ(0, (found_mask & (1 << idx)));
1072 found_mask |= (1 << idx);
1073 }
1074 }
1075 if (rc > 0)
1076 free(dev_info);
1077
1078 // Test that it is removed.
1079 rc = cras_iodev_list_rm_input(&d1_);
1080 EXPECT_EQ(0, rc);
1081 // Test that we can't remove a dev twice.
1082 rc = cras_iodev_list_rm_input(&d1_);
1083 EXPECT_NE(0, rc);
1084 // Should be 1 dev now.
1085 rc = cras_iodev_list_get_inputs(&dev_info);
1086 EXPECT_EQ(1, rc);
1087 free(dev_info);
1088 // Remove other dev.
1089 rc = cras_iodev_list_rm_input(&d2_);
1090 EXPECT_EQ(0, rc);
1091 // Shouldn't be any devices left.
1092 rc = cras_iodev_list_get_inputs(&dev_info);
1093 EXPECT_EQ(0, rc);
1094 free(dev_info);
1095
1096 cras_iodev_list_deinit();
1097 }
1098
1099 // Test adding/removing an input dev to the list without updating the server
1100 // state.
TEST_F(IoDevTestSuite,AddRemoveInputNoSem)1101 TEST_F(IoDevTestSuite, AddRemoveInputNoSem) {
1102 int rc;
1103
1104 d1_.direction = CRAS_STREAM_INPUT;
1105 d2_.direction = CRAS_STREAM_INPUT;
1106
1107 server_state_update_begin_return = NULL;
1108
1109 rc = cras_iodev_list_add_input(&d1_);
1110 EXPECT_EQ(0, rc);
1111 EXPECT_GE(d1_.info.idx, 0);
1112 rc = cras_iodev_list_add_input(&d2_);
1113 EXPECT_EQ(0, rc);
1114 EXPECT_GE(d2_.info.idx, 1);
1115
1116 EXPECT_EQ(0, cras_iodev_list_rm_input(&d1_));
1117 EXPECT_EQ(0, cras_iodev_list_rm_input(&d2_));
1118 }
1119
1120 // Test removing the last input.
TEST_F(IoDevTestSuite,RemoveLastInput)1121 TEST_F(IoDevTestSuite, RemoveLastInput) {
1122 struct cras_iodev_info *dev_info;
1123 int rc;
1124
1125 d1_.direction = CRAS_STREAM_INPUT;
1126 d2_.direction = CRAS_STREAM_INPUT;
1127
1128 cras_iodev_list_init();
1129
1130 rc = cras_iodev_list_add_input(&d1_);
1131 EXPECT_EQ(0, rc);
1132 rc = cras_iodev_list_add_input(&d2_);
1133 EXPECT_EQ(0, rc);
1134
1135 // Test that it is removed.
1136 rc = cras_iodev_list_rm_input(&d1_);
1137 EXPECT_EQ(0, rc);
1138 // Add it back.
1139 rc = cras_iodev_list_add_input(&d1_);
1140 EXPECT_EQ(0, rc);
1141 // And again.
1142 rc = cras_iodev_list_rm_input(&d1_);
1143 EXPECT_EQ(0, rc);
1144 // Add it back.
1145 rc = cras_iodev_list_add_input(&d1_);
1146 EXPECT_EQ(0, rc);
1147 // Remove other dev.
1148 rc = cras_iodev_list_rm_input(&d2_);
1149 EXPECT_EQ(0, rc);
1150 // Add it back.
1151 rc = cras_iodev_list_add_input(&d2_);
1152 EXPECT_EQ(0, rc);
1153 // Remove both.
1154 rc = cras_iodev_list_rm_input(&d2_);
1155 EXPECT_EQ(0, rc);
1156 rc = cras_iodev_list_rm_input(&d1_);
1157 EXPECT_EQ(0, rc);
1158 // Shouldn't be any devices left.
1159 rc = cras_iodev_list_get_inputs(&dev_info);
1160 EXPECT_EQ(0, rc);
1161
1162 cras_iodev_list_deinit();
1163 }
1164
1165 // Test nodes changed notification is sent.
TEST_F(IoDevTestSuite,NodesChangedNotification)1166 TEST_F(IoDevTestSuite, NodesChangedNotification) {
1167 cras_iodev_list_init();
1168 EXPECT_EQ(1, cras_observer_add_called);
1169
1170 cras_iodev_list_notify_nodes_changed();
1171 EXPECT_EQ(1, cras_observer_notify_nodes_called);
1172
1173 cras_iodev_list_deinit();
1174 EXPECT_EQ(1, cras_observer_remove_called);
1175 }
1176
1177 // Test callback function for left right swap mode is set and called.
TEST_F(IoDevTestSuite,NodesLeftRightSwappedCallback)1178 TEST_F(IoDevTestSuite, NodesLeftRightSwappedCallback) {
1179
1180 struct cras_iodev iodev;
1181 struct cras_ionode ionode;
1182 memset(&iodev, 0, sizeof(iodev));
1183 memset(&ionode, 0, sizeof(ionode));
1184 ionode.dev = &iodev;
1185 cras_iodev_list_notify_node_left_right_swapped(&ionode);
1186 EXPECT_EQ(1, cras_observer_notify_node_left_right_swapped_called);
1187 }
1188
1189 // Test callback function for volume and gain are set and called.
TEST_F(IoDevTestSuite,VolumeGainCallback)1190 TEST_F(IoDevTestSuite, VolumeGainCallback) {
1191
1192 struct cras_iodev iodev;
1193 struct cras_ionode ionode;
1194 memset(&iodev, 0, sizeof(iodev));
1195 memset(&ionode, 0, sizeof(ionode));
1196 ionode.dev = &iodev;
1197 cras_iodev_list_notify_node_volume(&ionode);
1198 cras_iodev_list_notify_node_capture_gain(&ionode);
1199 EXPECT_EQ(1, cras_observer_notify_output_node_volume_called);
1200 EXPECT_EQ(1, cras_observer_notify_input_node_gain_called);
1201 }
1202
TEST_F(IoDevTestSuite,IodevListSetNodeAttr)1203 TEST_F(IoDevTestSuite, IodevListSetNodeAttr) {
1204 int rc;
1205
1206 cras_iodev_list_init();
1207
1208 // The list is empty now.
1209 rc = cras_iodev_list_set_node_attr(cras_make_node_id(0, 0),
1210 IONODE_ATTR_PLUGGED, 1);
1211 EXPECT_LE(rc, 0);
1212 EXPECT_EQ(0, set_node_attr_called);
1213
1214 // Add two device, each with one node.
1215 d1_.direction = CRAS_STREAM_INPUT;
1216 EXPECT_EQ(0, cras_iodev_list_add_input(&d1_));
1217 node1.idx = 1;
1218 EXPECT_EQ(0, cras_iodev_list_add_output(&d2_));
1219 node2.idx = 2;
1220
1221 // Mismatch id
1222 rc = cras_iodev_list_set_node_attr(cras_make_node_id(d2_.info.idx, 1),
1223 IONODE_ATTR_PLUGGED, 1);
1224 EXPECT_LT(rc, 0);
1225 EXPECT_EQ(0, set_node_attr_called);
1226
1227 // Mismatch id
1228 rc = cras_iodev_list_set_node_attr(cras_make_node_id(d1_.info.idx, 2),
1229 IONODE_ATTR_PLUGGED, 1);
1230 EXPECT_LT(rc, 0);
1231 EXPECT_EQ(0, set_node_attr_called);
1232
1233 // Correct device id and node id
1234 rc = cras_iodev_list_set_node_attr(cras_make_node_id(d1_.info.idx, 1),
1235 IONODE_ATTR_PLUGGED, 1);
1236 EXPECT_EQ(rc, 0);
1237 EXPECT_EQ(1, set_node_attr_called);
1238 cras_iodev_list_deinit();
1239 }
1240
TEST_F(IoDevTestSuite,AddActiveNode)1241 TEST_F(IoDevTestSuite, AddActiveNode) {
1242 int rc;
1243 struct cras_rstream rstream;
1244
1245 memset(&rstream, 0, sizeof(rstream));
1246
1247 cras_iodev_list_init();
1248
1249 d1_.direction = CRAS_STREAM_OUTPUT;
1250 d2_.direction = CRAS_STREAM_OUTPUT;
1251 d3_.direction = CRAS_STREAM_OUTPUT;
1252 rc = cras_iodev_list_add_output(&d1_);
1253 ASSERT_EQ(0, rc);
1254 rc = cras_iodev_list_add_output(&d2_);
1255 ASSERT_EQ(0, rc);
1256 rc = cras_iodev_list_add_output(&d3_);
1257 ASSERT_EQ(0, rc);
1258
1259 audio_thread_add_open_dev_called = 0;
1260 cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
1261 cras_make_node_id(d3_.info.idx, 1));
1262 ASSERT_EQ(audio_thread_add_open_dev_called, 0);
1263 ASSERT_EQ(audio_thread_rm_open_dev_called, 0);
1264
1265 // If a stream is added, the device should be opened.
1266 stream_add_cb(&rstream);
1267 ASSERT_EQ(audio_thread_add_open_dev_called, 1);
1268 audio_thread_rm_open_dev_called = 0;
1269 audio_thread_drain_stream_return = 10;
1270 stream_rm_cb(&rstream);
1271 ASSERT_EQ(audio_thread_drain_stream_called, 1);
1272 ASSERT_EQ(audio_thread_rm_open_dev_called, 0);
1273 audio_thread_drain_stream_return = 0;
1274 clock_gettime_retspec.tv_sec = 15;
1275 clock_gettime_retspec.tv_nsec = 45;
1276 stream_rm_cb(&rstream);
1277 ASSERT_EQ(audio_thread_drain_stream_called, 2);
1278 ASSERT_EQ(0, audio_thread_rm_open_dev_called);
1279 // Stream should remain open for a while before being closed.
1280 // Test it is closed after 30 seconds.
1281 clock_gettime_retspec.tv_sec += 30;
1282 cras_tm_timer_cb(NULL, NULL);
1283 ASSERT_EQ(1, audio_thread_rm_open_dev_called);
1284
1285 audio_thread_rm_open_dev_called = 0;
1286 cras_iodev_list_rm_output(&d3_);
1287 ASSERT_EQ(audio_thread_rm_open_dev_called, 0);
1288
1289 /* Assert active devices was set to default one, when selected device
1290 * removed. */
1291 cras_iodev_list_rm_output(&d1_);
1292 cras_iodev_list_deinit();
1293 }
1294
TEST_F(IoDevTestSuite,DrainTimerCancel)1295 TEST_F(IoDevTestSuite, DrainTimerCancel) {
1296 int rc;
1297 struct cras_rstream rstream;
1298
1299 memset(&rstream, 0, sizeof(rstream));
1300
1301 cras_iodev_list_init();
1302
1303 d1_.direction = CRAS_STREAM_OUTPUT;
1304 rc = cras_iodev_list_add_output(&d1_);
1305 EXPECT_EQ(0, rc);
1306
1307 audio_thread_add_open_dev_called = 0;
1308 cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
1309 cras_make_node_id(d1_.info.idx, 1));
1310 EXPECT_EQ(0, audio_thread_add_open_dev_called);
1311 EXPECT_EQ(0, audio_thread_rm_open_dev_called);
1312
1313 // If a stream is added, the device should be opened.
1314 stream_add_cb(&rstream);
1315 EXPECT_EQ(1, audio_thread_add_open_dev_called);
1316
1317 audio_thread_rm_open_dev_called = 0;
1318 audio_thread_drain_stream_return = 0;
1319 clock_gettime_retspec.tv_sec = 15;
1320 clock_gettime_retspec.tv_nsec = 45;
1321 stream_rm_cb(&rstream);
1322 EXPECT_EQ(1, audio_thread_drain_stream_called);
1323 EXPECT_EQ(0, audio_thread_rm_open_dev_called);
1324
1325 // Add stream again, make sure device isn't closed after timeout.
1326 audio_thread_add_open_dev_called = 0;
1327 stream_add_cb(&rstream);
1328 EXPECT_EQ(0, audio_thread_add_open_dev_called);
1329
1330 clock_gettime_retspec.tv_sec += 30;
1331 cras_tm_timer_cb(NULL, NULL);
1332 EXPECT_EQ(0, audio_thread_rm_open_dev_called);
1333
1334 // Remove stream, and check the device is eventually closed.
1335 audio_thread_rm_open_dev_called = 0;
1336 audio_thread_drain_stream_called = 0;
1337 stream_rm_cb(&rstream);
1338 EXPECT_EQ(1, audio_thread_drain_stream_called);
1339 EXPECT_EQ(0, audio_thread_rm_open_dev_called);
1340
1341 clock_gettime_retspec.tv_sec += 30;
1342 cras_tm_timer_cb(NULL, NULL);
1343 EXPECT_EQ(1, audio_thread_rm_open_dev_called);
1344 cras_iodev_list_deinit();
1345 }
1346
TEST_F(IoDevTestSuite,RemoveThenSelectActiveNode)1347 TEST_F(IoDevTestSuite, RemoveThenSelectActiveNode) {
1348 int rc;
1349 cras_node_id_t id;
1350 cras_iodev_list_init();
1351
1352 d1_.direction = CRAS_STREAM_OUTPUT;
1353 d2_.direction = CRAS_STREAM_OUTPUT;
1354
1355 /* d1_ will be the default_output */
1356 rc = cras_iodev_list_add_output(&d1_);
1357 ASSERT_EQ(0, rc);
1358 rc = cras_iodev_list_add_output(&d2_);
1359 ASSERT_EQ(0, rc);
1360
1361 /* Test the scenario that the selected active output removed
1362 * from active dev list, should be able to select back again. */
1363 id = cras_make_node_id(d2_.info.idx, 1);
1364
1365 cras_iodev_list_rm_active_node(CRAS_STREAM_OUTPUT, id);
1366 ASSERT_EQ(audio_thread_rm_open_dev_called, 0);
1367
1368 cras_iodev_list_deinit();
1369 }
1370
TEST_F(IoDevTestSuite,AddRemovePinnedStream)1371 TEST_F(IoDevTestSuite, AddRemovePinnedStream) {
1372 struct cras_rstream rstream;
1373
1374 cras_iodev_list_init();
1375
1376 // Add 2 output devices.
1377 d1_.direction = CRAS_STREAM_OUTPUT;
1378 d1_.info.idx = 1;
1379 EXPECT_EQ(0, cras_iodev_list_add_output(&d1_));
1380 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
1381 cras_make_node_id(d1_.info.idx, 0));
1382 EXPECT_EQ(1, update_active_node_called);
1383 EXPECT_EQ(&d1_, update_active_node_iodev_val[0]);
1384
1385 d2_.direction = CRAS_STREAM_OUTPUT;
1386 d2_.info.idx = 2;
1387 EXPECT_EQ(0, cras_iodev_list_add_output(&d2_));
1388
1389 // Setup pinned stream.
1390 memset(&rstream, 0, sizeof(rstream));
1391 rstream.is_pinned = 1;
1392 rstream.pinned_dev_idx = d1_.info.idx;
1393
1394 // Add pinned stream to d1.
1395 EXPECT_EQ(0, stream_add_cb(&rstream));
1396 EXPECT_EQ(1, audio_thread_add_stream_called);
1397 EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
1398 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1399 EXPECT_EQ(2, update_active_node_called);
1400 // Init d1_ because of pinned stream
1401 EXPECT_EQ(&d1_, update_active_node_iodev_val[1]);
1402
1403 // Select d2, check pinned stream is not added to d2.
1404 cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
1405 cras_make_node_id(d2_.info.idx, 0));
1406 EXPECT_EQ(1, audio_thread_add_stream_called);
1407 EXPECT_EQ(4, update_active_node_called);
1408 // Unselect d1_ and select to d2_
1409 EXPECT_EQ(&d1_, update_active_node_iodev_val[2]);
1410 EXPECT_EQ(&d2_, update_active_node_iodev_val[3]);
1411
1412 // Remove pinned stream from d1, check d1 is closed after stream removed.
1413 EXPECT_EQ(0, stream_rm_cb(&rstream));
1414 EXPECT_EQ(1, cras_iodev_close_called);
1415 EXPECT_EQ(&d1_, cras_iodev_close_dev);
1416 EXPECT_EQ(5, update_active_node_called);
1417 // close pinned device
1418 EXPECT_EQ(&d1_, update_active_node_iodev_val[4]);
1419
1420 // Assume dev is already opened, add pin stream should not trigger another
1421 // update_active_node call, but will trigger audio_thread_add_stream.
1422 audio_thread_is_dev_open_ret = 1;
1423 EXPECT_EQ(0, stream_add_cb(&rstream));
1424 EXPECT_EQ(5, update_active_node_called);
1425 EXPECT_EQ(2, audio_thread_add_stream_called);
1426
1427 cras_iodev_list_deinit();
1428 }
1429
TEST_F(IoDevTestSuite,SuspendResumePinnedStream)1430 TEST_F(IoDevTestSuite, SuspendResumePinnedStream) {
1431 struct cras_rstream rstream;
1432
1433 cras_iodev_list_init();
1434
1435 // Add 2 output devices.
1436 d1_.direction = CRAS_STREAM_OUTPUT;
1437 EXPECT_EQ(0, cras_iodev_list_add_output(&d1_));
1438 d2_.direction = CRAS_STREAM_OUTPUT;
1439 EXPECT_EQ(0, cras_iodev_list_add_output(&d2_));
1440
1441 // Setup pinned stream.
1442 memset(&rstream, 0, sizeof(rstream));
1443 rstream.is_pinned = 1;
1444 rstream.pinned_dev_idx = d1_.info.idx;
1445
1446 // Add pinned stream to d1.
1447 EXPECT_EQ(0, stream_add_cb(&rstream));
1448 EXPECT_EQ(1, audio_thread_add_stream_called);
1449 EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
1450 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1451
1452 DL_APPEND(stream_list_get_ret, &rstream);
1453
1454 // Test for suspend
1455
1456 // Device state enters no_stream after stream is disconnected.
1457 d1_.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
1458 // Device has no pinned stream now. But this pinned stream remains in stream_list.
1459 cras_iodev_has_pinned_stream_ret[&d1_] = 0;
1460
1461 // Suspend
1462 observer_ops->suspend_changed(NULL, 1);
1463
1464 // Verify that stream is disconnected and d1 is closed.
1465 EXPECT_EQ(1, audio_thread_disconnect_stream_called);
1466 EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
1467 EXPECT_EQ(1, cras_iodev_close_called);
1468 EXPECT_EQ(&d1_, cras_iodev_close_dev);
1469
1470 // Test for resume
1471 cras_iodev_open_called = 0;
1472 audio_thread_add_stream_called = 0;
1473 audio_thread_add_stream_stream = NULL;
1474 d1_.state = CRAS_IODEV_STATE_CLOSE;
1475
1476 // Resume
1477 observer_ops->suspend_changed(NULL, 0);
1478
1479 // Verify that device is opened and stream is attached to the device.
1480 EXPECT_EQ(1, cras_iodev_open_called);
1481 EXPECT_EQ(1, audio_thread_add_stream_called);
1482 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1483 cras_iodev_list_deinit();
1484 }
1485
TEST_F(IoDevTestSuite,HotwordStreamsAddedThenSuspendResume)1486 TEST_F(IoDevTestSuite, HotwordStreamsAddedThenSuspendResume) {
1487 struct cras_rstream rstream;
1488 struct cras_rstream *stream_list = NULL;
1489 cras_iodev_list_init();
1490
1491 node1.type = CRAS_NODE_TYPE_HOTWORD;
1492 d1_.direction = CRAS_STREAM_INPUT;
1493 EXPECT_EQ(0, cras_iodev_list_add_input(&d1_));
1494
1495 memset(&rstream, 0, sizeof(rstream));
1496 rstream.is_pinned = 1;
1497 rstream.pinned_dev_idx = d1_.info.idx;
1498 rstream.flags = HOTWORD_STREAM;
1499
1500 /* Add a hotword stream. */
1501 EXPECT_EQ(0, stream_add_cb(&rstream));
1502 EXPECT_EQ(1, audio_thread_add_stream_called);
1503 EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
1504 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1505
1506 DL_APPEND(stream_list, &rstream);
1507 stream_list_get_ret = stream_list;
1508
1509 /* Suspend hotword streams, verify the existing stream disconnects
1510 * from the hotword device and connects to the empty iodev. */
1511 EXPECT_EQ(0, cras_iodev_list_suspend_hotword_streams());
1512 EXPECT_EQ(1, audio_thread_disconnect_stream_called);
1513 EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
1514 EXPECT_EQ(&d1_, audio_thread_disconnect_stream_dev);
1515 EXPECT_EQ(2, audio_thread_add_stream_called);
1516 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1517 EXPECT_EQ(&dummy_hotword_iodev, audio_thread_add_stream_dev);
1518
1519 /* Resume hotword streams, verify the stream disconnects from
1520 * the empty iodev and connects back to the real hotword iodev. */
1521 EXPECT_EQ(0, cras_iodev_list_resume_hotword_stream());
1522 EXPECT_EQ(2, audio_thread_disconnect_stream_called);
1523 EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
1524 EXPECT_EQ(&dummy_hotword_iodev, audio_thread_disconnect_stream_dev);
1525 EXPECT_EQ(3, audio_thread_add_stream_called);
1526 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1527 EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
1528 cras_iodev_list_deinit();
1529 }
1530
TEST_F(IoDevTestSuite,HotwordStreamsAddedAfterSuspend)1531 TEST_F(IoDevTestSuite, HotwordStreamsAddedAfterSuspend) {
1532 struct cras_rstream rstream;
1533 struct cras_rstream *stream_list = NULL;
1534 cras_iodev_list_init();
1535
1536 node1.type = CRAS_NODE_TYPE_HOTWORD;
1537 d1_.direction = CRAS_STREAM_INPUT;
1538 EXPECT_EQ(0, cras_iodev_list_add_input(&d1_));
1539
1540 memset(&rstream, 0, sizeof(rstream));
1541 rstream.is_pinned = 1;
1542 rstream.pinned_dev_idx = d1_.info.idx;
1543 rstream.flags = HOTWORD_STREAM;
1544
1545 /* Suspends hotword streams before a stream connected. */
1546 EXPECT_EQ(0, cras_iodev_list_suspend_hotword_streams());
1547 EXPECT_EQ(0, audio_thread_disconnect_stream_called);
1548 EXPECT_EQ(0, audio_thread_add_stream_called);
1549
1550 DL_APPEND(stream_list, &rstream);
1551 stream_list_get_ret = stream_list;
1552
1553 /* Hotword stream connected, verify it is added to the empty iodev. */
1554 EXPECT_EQ(0, stream_add_cb(&rstream));
1555 EXPECT_EQ(1, audio_thread_add_stream_called);
1556 EXPECT_EQ(&dummy_hotword_iodev, audio_thread_add_stream_dev);
1557 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1558
1559 /* Resume hotword streams, now the existing hotword stream should disconnect
1560 * from the empty iodev and connect to the real hotword iodev. */
1561 EXPECT_EQ(0, cras_iodev_list_resume_hotword_stream());
1562 EXPECT_EQ(1, audio_thread_disconnect_stream_called);
1563 EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
1564 EXPECT_EQ(&dummy_hotword_iodev, audio_thread_disconnect_stream_dev);
1565 EXPECT_EQ(2, audio_thread_add_stream_called);
1566 EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
1567 EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
1568 cras_iodev_list_deinit();
1569 }
1570
1571 } // namespace
1572
main(int argc,char ** argv)1573 int main(int argc, char **argv) {
1574 ::testing::InitGoogleTest(&argc, argv);
1575 return RUN_ALL_TESTS();
1576 }
1577
1578 extern "C" {
1579
1580 // Stubs
1581
cras_system_state_update_begin()1582 struct cras_server_state *cras_system_state_update_begin() {
1583 return server_state_update_begin_return;
1584 }
1585
cras_system_state_update_complete()1586 void cras_system_state_update_complete() {
1587 }
1588
audio_thread_create()1589 struct audio_thread *audio_thread_create() {
1590 return &thread;
1591 }
1592
audio_thread_start(struct audio_thread * thread)1593 int audio_thread_start(struct audio_thread *thread) {
1594 return 0;
1595 }
1596
audio_thread_destroy(struct audio_thread * thread)1597 void audio_thread_destroy(struct audio_thread *thread) {
1598 }
1599
audio_thread_set_active_dev(struct audio_thread * thread,struct cras_iodev * dev)1600 int audio_thread_set_active_dev(struct audio_thread *thread,
1601 struct cras_iodev *dev) {
1602 audio_thread_set_active_dev_called++;
1603 audio_thread_set_active_dev_val = dev;
1604 return 0;
1605 }
1606
audio_thread_remove_streams(struct audio_thread * thread,enum CRAS_STREAM_DIRECTION dir)1607 void audio_thread_remove_streams(struct audio_thread *thread,
1608 enum CRAS_STREAM_DIRECTION dir) {
1609 audio_thread_remove_streams_active_dev = audio_thread_set_active_dev_val;
1610 }
1611
audio_thread_add_open_dev(struct audio_thread * thread,struct cras_iodev * dev)1612 int audio_thread_add_open_dev(struct audio_thread *thread,
1613 struct cras_iodev *dev)
1614 {
1615 audio_thread_add_open_dev_dev = dev;
1616 audio_thread_add_open_dev_called++;
1617 return 0;
1618 }
1619
audio_thread_rm_open_dev(struct audio_thread * thread,struct cras_iodev * dev)1620 int audio_thread_rm_open_dev(struct audio_thread *thread,
1621 struct cras_iodev *dev)
1622 {
1623 audio_thread_rm_open_dev_called++;
1624 return 0;
1625 }
1626
audio_thread_is_dev_open(struct audio_thread * thread,struct cras_iodev * dev)1627 int audio_thread_is_dev_open(struct audio_thread *thread,
1628 struct cras_iodev *dev)
1629 {
1630 return audio_thread_is_dev_open_ret;
1631 }
1632
audio_thread_add_stream(struct audio_thread * thread,struct cras_rstream * stream,struct cras_iodev ** devs,unsigned int num_devs)1633 int audio_thread_add_stream(struct audio_thread *thread,
1634 struct cras_rstream *stream,
1635 struct cras_iodev **devs,
1636 unsigned int num_devs)
1637 {
1638 audio_thread_add_stream_called++;
1639 audio_thread_add_stream_stream = stream;
1640 audio_thread_add_stream_dev = (num_devs ? devs[0] : NULL);
1641 return 0;
1642 }
1643
audio_thread_disconnect_stream(struct audio_thread * thread,struct cras_rstream * stream,struct cras_iodev * iodev)1644 int audio_thread_disconnect_stream(struct audio_thread *thread,
1645 struct cras_rstream *stream,
1646 struct cras_iodev *iodev)
1647 {
1648 audio_thread_disconnect_stream_called++;
1649 audio_thread_disconnect_stream_stream = stream;
1650 audio_thread_disconnect_stream_dev = iodev;
1651 return 0;
1652 }
1653
audio_thread_drain_stream(struct audio_thread * thread,struct cras_rstream * stream)1654 int audio_thread_drain_stream(struct audio_thread *thread,
1655 struct cras_rstream *stream)
1656 {
1657 audio_thread_drain_stream_called++;
1658 return audio_thread_drain_stream_return;
1659 }
1660
set_node_volume(struct cras_ionode * node,int value)1661 void set_node_volume(struct cras_ionode *node, int value)
1662 {
1663 struct cras_iodev *dev = node->dev;
1664 unsigned int volume;
1665
1666 if (dev->direction != CRAS_STREAM_OUTPUT)
1667 return;
1668
1669 volume = (unsigned int)std::min(value, 100);
1670 node->volume = volume;
1671 if (dev->set_volume)
1672 dev->set_volume(dev);
1673
1674 cras_iodev_list_notify_node_volume(node);
1675 }
1676
cras_iodev_set_node_attr(struct cras_ionode * ionode,enum ionode_attr attr,int value)1677 int cras_iodev_set_node_attr(struct cras_ionode *ionode,
1678 enum ionode_attr attr, int value)
1679 {
1680 set_node_attr_called++;
1681
1682 switch (attr) {
1683 case IONODE_ATTR_PLUGGED:
1684 // plug_node(ionode, value);
1685 break;
1686 case IONODE_ATTR_VOLUME:
1687 set_node_volume(ionode, value);
1688 break;
1689 case IONODE_ATTR_CAPTURE_GAIN:
1690 // set_node_capture_gain(ionode, value);
1691 break;
1692 default:
1693 return -EINVAL;
1694 }
1695
1696 return 0;
1697 }
1698
empty_iodev_create(enum CRAS_STREAM_DIRECTION direction,enum CRAS_NODE_TYPE node_type)1699 struct cras_iodev *empty_iodev_create(enum CRAS_STREAM_DIRECTION direction,
1700 enum CRAS_NODE_TYPE node_type) {
1701 struct cras_iodev *dev;
1702 if (node_type == CRAS_NODE_TYPE_HOTWORD) {
1703 dev = &dummy_hotword_iodev;
1704 } else {
1705 dev = &dummy_empty_iodev[direction];
1706 }
1707 dev->direction = direction;
1708 dev->update_active_node = dummy_update_active_node;
1709 if (dev->active_node == NULL) {
1710 struct cras_ionode *node = (struct cras_ionode *)calloc(1, sizeof(*node));
1711 node->type = node_type;
1712 dev->active_node = node;
1713 }
1714 return dev;
1715 }
1716
empty_iodev_destroy(struct cras_iodev * iodev)1717 void empty_iodev_destroy(struct cras_iodev *iodev) {
1718 if (iodev->active_node) {
1719 free(iodev->active_node);
1720 iodev->active_node = NULL;
1721 }
1722 }
1723
test_iodev_create(enum CRAS_STREAM_DIRECTION direction,enum TEST_IODEV_TYPE type)1724 struct cras_iodev *test_iodev_create(enum CRAS_STREAM_DIRECTION direction,
1725 enum TEST_IODEV_TYPE type) {
1726 return NULL;
1727 }
1728
test_iodev_command(struct cras_iodev * iodev,enum CRAS_TEST_IODEV_CMD command,unsigned int data_len,const uint8_t * data)1729 void test_iodev_command(struct cras_iodev *iodev,
1730 enum CRAS_TEST_IODEV_CMD command,
1731 unsigned int data_len,
1732 const uint8_t *data) {
1733 }
1734
loopback_iodev_create(enum CRAS_LOOPBACK_TYPE type)1735 struct cras_iodev *loopback_iodev_create(enum CRAS_LOOPBACK_TYPE type) {
1736 return &loopback_input;
1737 }
1738
loopback_iodev_destroy(struct cras_iodev * iodev)1739 void loopback_iodev_destroy(struct cras_iodev *iodev) {
1740 }
1741
cras_iodev_open(struct cras_iodev * iodev,unsigned int cb_level,const struct cras_audio_format * fmt)1742 int cras_iodev_open(struct cras_iodev *iodev, unsigned int cb_level,
1743 const struct cras_audio_format *fmt)
1744 {
1745 if (cras_iodev_open_ret[cras_iodev_open_called] == 0)
1746 iodev->state = CRAS_IODEV_STATE_OPEN;
1747 return cras_iodev_open_ret[cras_iodev_open_called++];
1748 }
1749
cras_iodev_close(struct cras_iodev * iodev)1750 int cras_iodev_close(struct cras_iodev *iodev) {
1751 iodev->state = CRAS_IODEV_STATE_CLOSE;
1752 cras_iodev_close_called++;
1753 cras_iodev_close_dev = iodev;
1754 return 0;
1755 }
1756
cras_iodev_set_format(struct cras_iodev * iodev,const struct cras_audio_format * fmt)1757 int cras_iodev_set_format(struct cras_iodev *iodev,
1758 const struct cras_audio_format *fmt) {
1759 return 0;
1760 }
1761
cras_iodev_set_mute(struct cras_iodev * iodev)1762 int cras_iodev_set_mute(struct cras_iodev* iodev) {
1763 set_mute_called++;
1764 set_mute_dev_vector.push_back(iodev);
1765 return 0;
1766 }
1767
cras_iodev_is_zero_volume(const struct cras_iodev * iodev)1768 int cras_iodev_is_zero_volume(const struct cras_iodev *iodev)
1769 {
1770 return cras_iodev_is_zero_volume_ret;
1771 }
1772
cras_iodev_state(const struct cras_iodev * iodev)1773 enum CRAS_IODEV_STATE cras_iodev_state(const struct cras_iodev *iodev)
1774 {
1775 return cras_iodev_state_ret[iodev];
1776 }
1777
cras_iodev_has_pinned_stream(const struct cras_iodev * dev)1778 int cras_iodev_has_pinned_stream(const struct cras_iodev *dev)
1779 {
1780 return cras_iodev_has_pinned_stream_ret[dev];
1781 }
1782
stream_list_create(stream_callback * add_cb,stream_callback * rm_cb,stream_create_func * create_cb,stream_destroy_func * destroy_cb,struct cras_tm * timer_manager)1783 struct stream_list *stream_list_create(stream_callback *add_cb,
1784 stream_callback *rm_cb,
1785 stream_create_func *create_cb,
1786 stream_destroy_func *destroy_cb,
1787 struct cras_tm *timer_manager) {
1788 stream_add_cb = add_cb;
1789 stream_rm_cb = rm_cb;
1790 return reinterpret_cast<stream_list *>(0xf00);
1791 }
1792
stream_list_destroy(struct stream_list * list)1793 void stream_list_destroy(struct stream_list *list) {
1794 }
1795
stream_list_get(struct stream_list * list)1796 struct cras_rstream *stream_list_get(struct stream_list *list) {
1797 return stream_list_get_ret;
1798 }
server_stream_create(struct stream_list * stream_list,unsigned int dev_idx)1799 void server_stream_create(struct stream_list *stream_list,
1800 unsigned int dev_idx)
1801 {
1802 server_stream_create_called++;
1803 }
server_stream_destroy(struct stream_list * stream_list,unsigned int dev_idx)1804 void server_stream_destroy(struct stream_list *stream_list,
1805 unsigned int dev_idx)
1806 {
1807 server_stream_destroy_called++;
1808 }
1809
cras_rstream_create(struct cras_rstream_config * config,struct cras_rstream ** stream_out)1810 int cras_rstream_create(struct cras_rstream_config *config,
1811 struct cras_rstream **stream_out) {
1812 return 0;
1813 }
1814
cras_rstream_destroy(struct cras_rstream * rstream)1815 void cras_rstream_destroy(struct cras_rstream *rstream) {
1816 }
1817
cras_system_state_get_tm()1818 struct cras_tm *cras_system_state_get_tm() {
1819 return NULL;
1820 }
1821
cras_tm_create_timer(struct cras_tm * tm,unsigned int ms,void (* cb)(struct cras_timer * t,void * data),void * cb_data)1822 struct cras_timer *cras_tm_create_timer(
1823 struct cras_tm *tm,
1824 unsigned int ms,
1825 void (*cb)(struct cras_timer *t, void *data),
1826 void *cb_data) {
1827 cras_tm_timer_cb = cb;
1828 cras_tm_timer_cb_data = cb_data;
1829 cras_tm_create_timer_called++;
1830 return reinterpret_cast<struct cras_timer *>(0x404);
1831 }
1832
cras_tm_cancel_timer(struct cras_tm * tm,struct cras_timer * t)1833 void cras_tm_cancel_timer(struct cras_tm *tm, struct cras_timer *t) {
1834 cras_tm_cancel_timer_called++;
1835 }
1836
cras_fmt_conv_destroy(struct cras_fmt_conv * conv)1837 void cras_fmt_conv_destroy(struct cras_fmt_conv *conv)
1838 {
1839 }
1840
cras_channel_remix_conv_create(unsigned int num_channels,const float * coefficient)1841 struct cras_fmt_conv *cras_channel_remix_conv_create(
1842 unsigned int num_channels, const float *coefficient)
1843 {
1844 return NULL;
1845 }
1846
cras_channel_remix_convert(struct cras_fmt_conv * conv,uint8_t * in_buf,size_t frames)1847 void cras_channel_remix_convert(struct cras_fmt_conv *conv,
1848 uint8_t *in_buf, size_t frames)
1849 {
1850 }
1851
cras_observer_add(const struct cras_observer_ops * ops,void * context)1852 struct cras_observer_client *cras_observer_add(
1853 const struct cras_observer_ops *ops,
1854 void *context)
1855 {
1856 observer_ops = (struct cras_observer_ops *)calloc(1, sizeof(*ops));
1857 memcpy(observer_ops, ops, sizeof(*ops));
1858 cras_observer_add_called++;
1859 return reinterpret_cast<struct cras_observer_client *>(0x55);
1860 }
1861
cras_observer_remove(struct cras_observer_client * client)1862 void cras_observer_remove(struct cras_observer_client *client)
1863 {
1864 if (observer_ops)
1865 free(observer_ops);
1866 cras_observer_remove_called++;
1867 }
1868
cras_observer_notify_nodes(void)1869 void cras_observer_notify_nodes(void) {
1870 cras_observer_notify_nodes_called++;
1871 }
1872
cras_observer_notify_active_node(enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)1873 void cras_observer_notify_active_node(enum CRAS_STREAM_DIRECTION direction,
1874 cras_node_id_t node_id)
1875 {
1876 cras_observer_notify_active_node_called++;
1877 }
1878
cras_observer_notify_output_node_volume(cras_node_id_t node_id,int32_t volume)1879 void cras_observer_notify_output_node_volume(cras_node_id_t node_id,
1880 int32_t volume)
1881 {
1882 cras_observer_notify_output_node_volume_called++;
1883 }
1884
cras_observer_notify_node_left_right_swapped(cras_node_id_t node_id,int swapped)1885 void cras_observer_notify_node_left_right_swapped(cras_node_id_t node_id,
1886 int swapped)
1887 {
1888 cras_observer_notify_node_left_right_swapped_called++;
1889 }
1890
cras_observer_notify_input_node_gain(cras_node_id_t node_id,int32_t gain)1891 void cras_observer_notify_input_node_gain(cras_node_id_t node_id,
1892 int32_t gain)
1893 {
1894 cras_observer_notify_input_node_gain_called++;
1895 }
1896
audio_thread_dev_start_ramp(struct audio_thread * thread,struct cras_iodev * dev,enum CRAS_IODEV_RAMP_REQUEST request)1897 int audio_thread_dev_start_ramp(struct audio_thread *thread,
1898 struct cras_iodev *dev,
1899 enum CRAS_IODEV_RAMP_REQUEST request)
1900 {
1901 audio_thread_dev_start_ramp_called++;
1902 audio_thread_dev_start_ramp_dev = dev;
1903 audio_thread_dev_start_ramp_req = request;
1904 return 0;
1905 }
1906
1907 #ifdef HAVE_WEBRTC_APM
cras_apm_list_add(struct cras_apm_list * list,void * dev_ptr,const struct cras_audio_format * fmt)1908 struct cras_apm *cras_apm_list_add(struct cras_apm_list *list,
1909 void *dev_ptr,
1910 const struct cras_audio_format *fmt)
1911 {
1912 return NULL;
1913 }
cras_apm_list_remove(struct cras_apm_list * list,void * dev_ptr)1914 void cras_apm_list_remove(struct cras_apm_list *list, void *dev_ptr)
1915 {
1916 }
cras_apm_list_init(const char * device_config_dir)1917 int cras_apm_list_init(const char *device_config_dir)
1918 {
1919 return 0;
1920 }
1921 #endif
1922
1923 // From librt.
clock_gettime(clockid_t clk_id,struct timespec * tp)1924 int clock_gettime(clockid_t clk_id, struct timespec *tp) {
1925 tp->tv_sec = clock_gettime_retspec.tv_sec;
1926 tp->tv_nsec = clock_gettime_retspec.tv_nsec;
1927 return 0;
1928 }
1929
1930 } // extern "C"
1931