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