• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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