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