Home | History | Annotate | Download | only in tests
      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 <stdio.h>
      6 #include <gtest/gtest.h>
      7 #include <map>
      8 #include <string>
      9 #include <syslog.h>
     10 #include <vector>
     11 
     12 extern "C" {
     13 #include "cras_alsa_mixer.h"
     14 #include "cras_alsa_mixer_name.h"
     15 #include "cras_types.h"
     16 #include "cras_util.h"
     17 #include "cras_volume_curve.h"
     18 #include "utlist.h"
     19 
     20 //  Include C file to test static functions and use the definition of some
     21 //  structure.
     22 #include "cras_alsa_mixer.c"
     23 }
     24 
     25 namespace {
     26 
     27 static size_t snd_mixer_open_called;
     28 static int snd_mixer_open_return_value;
     29 static size_t snd_mixer_close_called;
     30 static size_t snd_mixer_attach_called;
     31 static int snd_mixer_attach_return_value;
     32 const char *snd_mixer_attach_mixdev;
     33 static size_t snd_mixer_selem_register_called;
     34 static int snd_mixer_selem_register_return_value;
     35 static size_t snd_mixer_load_called;
     36 static int snd_mixer_load_return_value;
     37 static size_t snd_mixer_first_elem_called;
     38 static snd_mixer_elem_t *snd_mixer_first_elem_return_value;
     39 static int snd_mixer_elem_next_called;
     40 static snd_mixer_elem_t **snd_mixer_elem_next_return_values;
     41 static int snd_mixer_elem_next_return_values_index;
     42 static int snd_mixer_elem_next_return_values_length;
     43 static int snd_mixer_selem_set_playback_dB_all_called;
     44 static long *snd_mixer_selem_set_playback_dB_all_values;
     45 static int snd_mixer_selem_set_playback_dB_all_values_length;
     46 static int snd_mixer_selem_set_playback_switch_all_called;
     47 static int snd_mixer_selem_set_playback_switch_all_value;
     48 static int snd_mixer_selem_has_playback_volume_called;
     49 static int *snd_mixer_selem_has_playback_volume_return_values;
     50 static int snd_mixer_selem_has_playback_volume_return_values_length;
     51 static int snd_mixer_selem_has_playback_switch_called;
     52 static int *snd_mixer_selem_has_playback_switch_return_values;
     53 static int snd_mixer_selem_has_playback_switch_return_values_length;
     54 static int snd_mixer_selem_set_capture_dB_all_called;
     55 static long *snd_mixer_selem_set_capture_dB_all_values;
     56 static int snd_mixer_selem_set_capture_dB_all_values_length;
     57 static int snd_mixer_selem_set_capture_switch_all_called;
     58 static int snd_mixer_selem_set_capture_switch_all_value;
     59 static int snd_mixer_selem_has_capture_volume_called;
     60 static int *snd_mixer_selem_has_capture_volume_return_values;
     61 static int snd_mixer_selem_has_capture_volume_return_values_length;
     62 static int snd_mixer_selem_has_capture_switch_called;
     63 static int *snd_mixer_selem_has_capture_switch_return_values;
     64 static int snd_mixer_selem_has_capture_switch_return_values_length;
     65 static int snd_mixer_selem_get_name_called;
     66 static const char **snd_mixer_selem_get_name_return_values;
     67 static int snd_mixer_selem_get_name_return_values_length;
     68 static int snd_mixer_selem_get_playback_dB_called;
     69 static long *snd_mixer_selem_get_playback_dB_return_values;
     70 static int snd_mixer_selem_get_playback_dB_return_values_length;
     71 static int snd_mixer_selem_get_capture_dB_called;
     72 static long *snd_mixer_selem_get_capture_dB_return_values;
     73 static int snd_mixer_selem_get_capture_dB_return_values_length;
     74 static size_t cras_volume_curve_destroy_called;
     75 static size_t snd_mixer_selem_get_playback_dB_range_called;
     76 static size_t snd_mixer_selem_get_playback_dB_range_values_length;
     77 static const long *snd_mixer_selem_get_playback_dB_range_min_values;
     78 static const long *snd_mixer_selem_get_playback_dB_range_max_values;
     79 static size_t snd_mixer_selem_get_capture_dB_range_called;
     80 static size_t snd_mixer_selem_get_capture_dB_range_values_length;
     81 static const long *snd_mixer_selem_get_capture_dB_range_min_values;
     82 static const long *snd_mixer_selem_get_capture_dB_range_max_values;
     83 static size_t iniparser_getstring_return_index;
     84 static size_t iniparser_getstring_return_length;
     85 static char **iniparser_getstring_returns;
     86 static size_t snd_mixer_find_selem_called;
     87 static std::map<std::string, snd_mixer_elem_t*> snd_mixer_find_elem_map;
     88 static std::string snd_mixer_find_elem_id_name;
     89 
     90 static void ResetStubData() {
     91   iniparser_getstring_return_index = 0;
     92   iniparser_getstring_return_length = 0;
     93   snd_mixer_open_called = 0;
     94   snd_mixer_open_return_value = 0;
     95   snd_mixer_close_called = 0;
     96   snd_mixer_attach_called = 0;
     97   snd_mixer_attach_return_value = 0;
     98   snd_mixer_attach_mixdev = static_cast<const char *>(NULL);
     99   snd_mixer_selem_register_called = 0;
    100   snd_mixer_selem_register_return_value = 0;
    101   snd_mixer_load_called = 0;
    102   snd_mixer_load_return_value = 0;
    103   snd_mixer_first_elem_called = 0;
    104   snd_mixer_first_elem_return_value = static_cast<snd_mixer_elem_t *>(NULL);
    105   snd_mixer_elem_next_called = 0;
    106   snd_mixer_elem_next_return_values = static_cast<snd_mixer_elem_t **>(NULL);
    107   snd_mixer_elem_next_return_values_index = 0;
    108   snd_mixer_elem_next_return_values_length = 0;
    109   snd_mixer_selem_set_playback_dB_all_called = 0;
    110   snd_mixer_selem_set_playback_dB_all_values = static_cast<long *>(NULL);
    111   snd_mixer_selem_set_playback_dB_all_values_length = 0;
    112   snd_mixer_selem_set_playback_switch_all_called = 0;
    113   snd_mixer_selem_has_playback_volume_called = 0;
    114   snd_mixer_selem_has_playback_volume_return_values = static_cast<int *>(NULL);
    115   snd_mixer_selem_has_playback_volume_return_values_length = 0;
    116   snd_mixer_selem_has_playback_switch_called = 0;
    117   snd_mixer_selem_has_playback_switch_return_values = static_cast<int *>(NULL);
    118   snd_mixer_selem_has_playback_switch_return_values_length = 0;
    119   snd_mixer_selem_set_capture_dB_all_called = 0;
    120   snd_mixer_selem_set_capture_dB_all_values = static_cast<long *>(NULL);
    121   snd_mixer_selem_set_capture_dB_all_values_length = 0;
    122   snd_mixer_selem_set_capture_switch_all_called = 0;
    123   snd_mixer_selem_has_capture_volume_called = 0;
    124   snd_mixer_selem_has_capture_volume_return_values = static_cast<int *>(NULL);
    125   snd_mixer_selem_has_capture_volume_return_values_length = 0;
    126   snd_mixer_selem_has_capture_switch_called = 0;
    127   snd_mixer_selem_has_capture_switch_return_values = static_cast<int *>(NULL);
    128   snd_mixer_selem_has_capture_switch_return_values_length = 0;
    129   snd_mixer_selem_get_name_called = 0;
    130   snd_mixer_selem_get_name_return_values = static_cast<const char **>(NULL);
    131   snd_mixer_selem_get_name_return_values_length = 0;
    132   snd_mixer_selem_get_playback_dB_called = 0;
    133   snd_mixer_selem_get_playback_dB_return_values = static_cast<long *>(NULL);
    134   snd_mixer_selem_get_playback_dB_return_values_length = 0;
    135   snd_mixer_selem_get_capture_dB_called = 0;
    136   snd_mixer_selem_get_capture_dB_return_values = static_cast<long *>(NULL);
    137   snd_mixer_selem_get_capture_dB_return_values_length = 0;
    138   cras_volume_curve_destroy_called = 0;
    139   snd_mixer_selem_get_playback_dB_range_called = 0;
    140   snd_mixer_selem_get_playback_dB_range_values_length = 0;
    141   snd_mixer_selem_get_playback_dB_range_min_values = static_cast<long *>(NULL);
    142   snd_mixer_selem_get_playback_dB_range_max_values = static_cast<long *>(NULL);
    143   snd_mixer_selem_get_capture_dB_range_called = 0;
    144   snd_mixer_selem_get_capture_dB_range_values_length = 0;
    145   snd_mixer_selem_get_capture_dB_range_min_values = static_cast<long *>(NULL);
    146   snd_mixer_selem_get_capture_dB_range_max_values = static_cast<long *>(NULL);
    147   snd_mixer_find_selem_called = 0;
    148   snd_mixer_find_elem_map.clear();
    149   snd_mixer_find_elem_id_name.clear();
    150 }
    151 
    152 struct cras_alsa_mixer *create_mixer_and_add_controls_by_name_matching(
    153     const char *card_name,
    154     struct mixer_name *extra_controls,
    155     struct mixer_name *coupled_controls) {
    156   struct cras_alsa_mixer *cmix = cras_alsa_mixer_create(card_name);
    157   cras_alsa_mixer_add_controls_by_name_matching(
    158       cmix, extra_controls, coupled_controls);
    159   return cmix;
    160 }
    161 
    162 TEST(AlsaMixer, CreateFailOpen) {
    163   struct cras_alsa_mixer *c;
    164 
    165   ResetStubData();
    166   snd_mixer_open_return_value = -1;
    167   c = cras_alsa_mixer_create("hw:0");
    168   EXPECT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    169   EXPECT_EQ(1, snd_mixer_open_called);
    170 }
    171 
    172 TEST(AlsaMixer, CreateFailAttach) {
    173   struct cras_alsa_mixer *c;
    174 
    175   ResetStubData();
    176   snd_mixer_attach_return_value = -1;
    177   c = cras_alsa_mixer_create("hw:0");
    178   EXPECT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    179   EXPECT_EQ(1, snd_mixer_open_called);
    180   EXPECT_EQ(1, snd_mixer_attach_called);
    181   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    182   EXPECT_EQ(1, snd_mixer_close_called);
    183 }
    184 
    185 TEST(AlsaMixer, CreateFailSelemRegister) {
    186   struct cras_alsa_mixer *c;
    187 
    188   ResetStubData();
    189   snd_mixer_selem_register_return_value = -1;
    190   c = cras_alsa_mixer_create("hw:0");
    191   EXPECT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    192   EXPECT_EQ(1, snd_mixer_open_called);
    193   EXPECT_EQ(1, snd_mixer_attach_called);
    194   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    195   EXPECT_EQ(1, snd_mixer_selem_register_called);
    196   EXPECT_EQ(1, snd_mixer_close_called);
    197 }
    198 
    199 TEST(AlsaMixer, CreateFailLoad) {
    200   struct cras_alsa_mixer *c;
    201 
    202   ResetStubData();
    203   snd_mixer_load_return_value = -1;
    204   c = cras_alsa_mixer_create("hw:0");
    205   EXPECT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    206   EXPECT_EQ(1, snd_mixer_open_called);
    207   EXPECT_EQ(1, snd_mixer_attach_called);
    208   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    209   EXPECT_EQ(1, snd_mixer_selem_register_called);
    210   EXPECT_EQ(1, snd_mixer_load_called);
    211   EXPECT_EQ(1, snd_mixer_close_called);
    212 }
    213 
    214 TEST(AlsaMixer, CreateNoElements) {
    215   struct cras_alsa_mixer *c;
    216 
    217   ResetStubData();
    218   c = create_mixer_and_add_controls_by_name_matching(
    219       "hw:0", NULL, NULL);
    220   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    221   EXPECT_EQ(1, snd_mixer_open_called);
    222   EXPECT_EQ(1, snd_mixer_attach_called);
    223   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    224   EXPECT_EQ(1, snd_mixer_selem_register_called);
    225   EXPECT_EQ(1, snd_mixer_load_called);
    226   EXPECT_EQ(0, snd_mixer_close_called);
    227 
    228   /* set mute shouldn't call anything. */
    229   cras_alsa_mixer_set_mute(c, 0, NULL);
    230   EXPECT_EQ(0, snd_mixer_selem_set_playback_switch_all_called);
    231   /* set volume shouldn't call anything. */
    232   cras_alsa_mixer_set_dBFS(c, 0, NULL);
    233   EXPECT_EQ(0, snd_mixer_selem_set_playback_dB_all_called);
    234 
    235   cras_alsa_mixer_destroy(c);
    236   EXPECT_EQ(1, snd_mixer_close_called);
    237 }
    238 
    239 TEST(AlsaMixer, CreateOneUnknownElementWithoutVolume) {
    240   struct cras_alsa_mixer *c;
    241   int element_playback_volume[] = {
    242     0,
    243   };
    244   int element_playback_switches[] = {
    245     1,
    246   };
    247   const char *element_names[] = {
    248     "Unknown",
    249   };
    250   struct mixer_control *mixer_output;
    251   int rc;
    252 
    253   ResetStubData();
    254   snd_mixer_first_elem_return_value = reinterpret_cast<snd_mixer_elem_t *>(1);
    255   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
    256   snd_mixer_selem_has_playback_volume_return_values_length =
    257       ARRAY_SIZE(element_playback_volume);
    258   snd_mixer_selem_get_name_return_values = element_names;
    259   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    260   c = create_mixer_and_add_controls_by_name_matching(
    261       "hw:0", NULL, NULL);
    262   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    263   EXPECT_EQ(1, snd_mixer_open_called);
    264   EXPECT_EQ(1, snd_mixer_attach_called);
    265   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    266   EXPECT_EQ(1, snd_mixer_selem_register_called);
    267   EXPECT_EQ(1, snd_mixer_load_called);
    268   EXPECT_EQ(0, snd_mixer_close_called);
    269   EXPECT_EQ(1, snd_mixer_selem_has_playback_volume_called);
    270   EXPECT_EQ(1, snd_mixer_selem_get_name_called);
    271   EXPECT_EQ(0, snd_mixer_selem_get_playback_dB_range_called);
    272 
    273   /* set mute shouldn't call anything. */
    274   cras_alsa_mixer_set_mute(c, 0, NULL);
    275   EXPECT_EQ(0, snd_mixer_selem_set_playback_switch_all_called);
    276 
    277   ResetStubData();
    278   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
    279   snd_mixer_selem_has_playback_switch_return_values_length =
    280       ARRAY_SIZE(element_playback_switches);
    281   snd_mixer_selem_get_name_return_values = element_names;
    282   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    283   rc = mixer_control_create(&mixer_output, NULL,
    284                             reinterpret_cast<snd_mixer_elem_t *>(1),
    285                             CRAS_STREAM_OUTPUT);
    286   EXPECT_EQ(0, rc);
    287   EXPECT_EQ(1, snd_mixer_selem_get_name_called);
    288   EXPECT_EQ(1, snd_mixer_selem_has_playback_volume_called);
    289   EXPECT_EQ(1, snd_mixer_selem_has_playback_switch_called);
    290   EXPECT_EQ(1, snd_mixer_selem_get_playback_dB_range_called);
    291 
    292   /* if passed a mixer output then it should mute that. */
    293   cras_alsa_mixer_set_mute(c, 0, mixer_output);
    294   EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_called);
    295   /* set volume shouldn't call anything. */
    296   cras_alsa_mixer_set_dBFS(c, 0, NULL);
    297   EXPECT_EQ(0, snd_mixer_selem_set_playback_dB_all_called);
    298 
    299   cras_alsa_mixer_destroy(c);
    300   EXPECT_EQ(1, snd_mixer_close_called);
    301   mixer_control_destroy(mixer_output);
    302 }
    303 
    304 TEST(AlsaMixer, CreateOneUnknownElementWithVolume) {
    305   struct cras_alsa_mixer *c;
    306   static const long min_volumes[] = {-500};
    307   static const long max_volumes[] = {40};
    308   int element_playback_volume[] = {
    309     1,
    310     0,
    311   };
    312   int element_playback_switches[] = {
    313     0,
    314     1,
    315   };
    316   const char *element_names[] = {
    317     "Unknown",
    318     "Playback",
    319   };
    320   struct mixer_control *mixer_output;
    321   int rc;
    322 
    323   ResetStubData();
    324   snd_mixer_first_elem_return_value = reinterpret_cast<snd_mixer_elem_t *>(1);
    325   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
    326   snd_mixer_selem_has_playback_volume_return_values_length =
    327       ARRAY_SIZE(element_playback_volume);
    328   snd_mixer_selem_get_name_return_values = element_names;
    329   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    330   snd_mixer_selem_get_playback_dB_range_min_values = min_volumes;
    331   snd_mixer_selem_get_playback_dB_range_max_values = max_volumes;
    332   snd_mixer_selem_get_playback_dB_range_values_length = ARRAY_SIZE(min_volumes);
    333   c = create_mixer_and_add_controls_by_name_matching(
    334       "hw:0", NULL, NULL);
    335   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    336   EXPECT_EQ(1, snd_mixer_open_called);
    337   EXPECT_EQ(1, snd_mixer_attach_called);
    338   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    339   EXPECT_EQ(1, snd_mixer_selem_register_called);
    340   EXPECT_EQ(1, snd_mixer_load_called);
    341   EXPECT_EQ(0, snd_mixer_close_called);
    342   EXPECT_EQ(3, snd_mixer_selem_has_playback_volume_called);
    343   EXPECT_EQ(2, snd_mixer_selem_get_playback_dB_range_called);
    344   EXPECT_EQ(3, snd_mixer_selem_get_name_called);
    345 
    346   /* Should use "Playback" since it has playback switch. */
    347   cras_alsa_mixer_set_mute(c, 0, NULL);
    348   EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_called);
    349 
    350   ResetStubData();
    351   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
    352   snd_mixer_selem_has_playback_volume_return_values_length =
    353       ARRAY_SIZE(element_playback_volume);
    354   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
    355   snd_mixer_selem_has_playback_switch_return_values_length =
    356       ARRAY_SIZE(element_playback_switches);
    357   snd_mixer_selem_get_name_return_values = element_names;
    358   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    359   rc = mixer_control_create(&mixer_output, NULL,
    360                             reinterpret_cast<snd_mixer_elem_t *>(2),
    361                             CRAS_STREAM_OUTPUT);
    362   EXPECT_EQ(0, rc);
    363   EXPECT_EQ(1, snd_mixer_selem_get_name_called);
    364   EXPECT_EQ(1, snd_mixer_selem_has_playback_volume_called);
    365   EXPECT_EQ(1, snd_mixer_selem_has_playback_switch_called);
    366   EXPECT_EQ(0, snd_mixer_selem_get_playback_dB_range_called);
    367 
    368   /*
    369    * If passed a mixer output then it should mute both "Playback" and that
    370    * mixer_output.
    371    */
    372   cras_alsa_mixer_set_mute(c, 0, mixer_output);
    373   EXPECT_EQ(2, snd_mixer_selem_set_playback_switch_all_called);
    374   cras_alsa_mixer_set_dBFS(c, 0, NULL);
    375   EXPECT_EQ(1, snd_mixer_selem_set_playback_dB_all_called);
    376 
    377   cras_alsa_mixer_destroy(c);
    378   EXPECT_EQ(1, snd_mixer_close_called);
    379   mixer_control_destroy(mixer_output);
    380 }
    381 
    382 TEST(AlsaMixer, CreateOneMasterElement) {
    383   struct cras_alsa_mixer *c;
    384   int element_playback_volume[] = {
    385     1,
    386     1,
    387   };
    388   int element_playback_switches[] = {
    389     1,
    390     1,
    391   };
    392   const char *element_names[] = {
    393     "Master",
    394     "Playback"
    395   };
    396   struct mixer_control *mixer_output;
    397   int rc;
    398   long set_dB_values[3];
    399   static const long min_volumes[] = {0, 0};
    400   static const long max_volumes[] = {950, 950};
    401 
    402   ResetStubData();
    403   snd_mixer_first_elem_return_value = reinterpret_cast<snd_mixer_elem_t *>(1);
    404   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
    405   snd_mixer_selem_has_playback_volume_return_values_length =
    406       ARRAY_SIZE(element_playback_volume);
    407   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
    408   snd_mixer_selem_has_playback_switch_return_values_length =
    409       ARRAY_SIZE(element_playback_switches);
    410   snd_mixer_selem_get_name_return_values = element_names;
    411   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    412   c = create_mixer_and_add_controls_by_name_matching(
    413       "hw:0", NULL, NULL);
    414   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    415   EXPECT_EQ(1, snd_mixer_open_called);
    416   EXPECT_EQ(1, snd_mixer_attach_called);
    417   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    418   EXPECT_EQ(1, snd_mixer_selem_register_called);
    419   EXPECT_EQ(1, snd_mixer_load_called);
    420   EXPECT_EQ(0, snd_mixer_close_called);
    421   EXPECT_EQ(3, snd_mixer_selem_get_name_called);
    422   EXPECT_EQ(1, snd_mixer_elem_next_called);
    423 
    424   /* set mute should be called for Master. */
    425   cras_alsa_mixer_set_mute(c, 0, NULL);
    426   EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_called);
    427   /* set volume should be called for Master. */
    428   cras_alsa_mixer_set_dBFS(c, 0, NULL);
    429   EXPECT_EQ(1, snd_mixer_selem_set_playback_dB_all_called);
    430 
    431   ResetStubData();
    432   snd_mixer_selem_set_playback_dB_all_values = set_dB_values;
    433   snd_mixer_selem_set_playback_dB_all_values_length =
    434       ARRAY_SIZE(set_dB_values);
    435   snd_mixer_selem_get_playback_dB_range_min_values = min_volumes;
    436   snd_mixer_selem_get_playback_dB_range_max_values = max_volumes;
    437   snd_mixer_selem_get_playback_dB_range_values_length = ARRAY_SIZE(min_volumes);
    438   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
    439   snd_mixer_selem_has_playback_volume_return_values_length =
    440       ARRAY_SIZE(element_playback_volume);
    441   snd_mixer_selem_get_name_return_values = element_names;
    442   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    443   rc = mixer_control_create(&mixer_output, NULL,
    444                             reinterpret_cast<snd_mixer_elem_t *>(2),
    445                             CRAS_STREAM_OUTPUT);
    446   EXPECT_EQ(0, rc);
    447   EXPECT_EQ(1, snd_mixer_selem_get_name_called);
    448   EXPECT_EQ(1, snd_mixer_selem_has_playback_volume_called);
    449   EXPECT_EQ(1, snd_mixer_selem_has_playback_switch_called);
    450   EXPECT_EQ(1, snd_mixer_selem_get_playback_dB_range_called);
    451 
    452   /* if passed a mixer output then it should set the volume for that too. */
    453   cras_alsa_mixer_set_dBFS(c, 0, mixer_output);
    454   EXPECT_EQ(2, snd_mixer_selem_set_playback_dB_all_called);
    455   EXPECT_EQ(950, set_dB_values[0]);
    456   EXPECT_EQ(950, set_dB_values[1]);
    457 
    458   cras_alsa_mixer_destroy(c);
    459   EXPECT_EQ(1, snd_mixer_close_called);
    460   mixer_control_destroy(mixer_output);
    461 }
    462 
    463 TEST(AlsaMixer, CreateTwoMainVolumeElements) {
    464   struct cras_alsa_mixer *c;
    465   snd_mixer_elem_t *elements[] = {
    466     reinterpret_cast<snd_mixer_elem_t *>(2),
    467   };
    468   int element_playback_volume[] = {
    469     1,
    470     1,
    471     1,
    472   };
    473   int element_playback_switches[] = {
    474     1,
    475     1,
    476     1,
    477   };
    478   const char *element_names[] = {
    479     "Master",
    480     "PCM",
    481     "Other",
    482   };
    483   struct mixer_control *mixer_output;
    484   int rc;
    485   static const long min_volumes[] = {-500, -1250, -500};
    486   static const long max_volumes[] = {40, 40, 0};
    487   long get_dB_returns[] = {0, 0, 0};
    488   long set_dB_values[3];
    489 
    490   ResetStubData();
    491   snd_mixer_first_elem_return_value = reinterpret_cast<snd_mixer_elem_t *>(1);
    492   snd_mixer_elem_next_return_values = elements;
    493   snd_mixer_elem_next_return_values_length = ARRAY_SIZE(elements);
    494   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
    495   snd_mixer_selem_has_playback_volume_return_values_length =
    496       ARRAY_SIZE(element_playback_volume);
    497   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
    498   snd_mixer_selem_has_playback_switch_return_values_length =
    499       ARRAY_SIZE(element_playback_switches);
    500   snd_mixer_selem_get_name_return_values = element_names;
    501   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    502   snd_mixer_selem_get_playback_dB_range_called = 0;
    503   snd_mixer_selem_get_playback_dB_range_min_values = min_volumes;
    504   snd_mixer_selem_get_playback_dB_range_max_values = max_volumes;
    505   snd_mixer_selem_get_playback_dB_range_values_length = ARRAY_SIZE(min_volumes);
    506   snd_mixer_selem_set_playback_dB_all_values = set_dB_values;
    507   snd_mixer_selem_set_playback_dB_all_values_length =
    508       ARRAY_SIZE(set_dB_values);
    509   c = create_mixer_and_add_controls_by_name_matching(
    510       "hw:0", NULL, NULL);
    511   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    512   EXPECT_EQ(2, snd_mixer_selem_get_playback_dB_range_called);
    513   EXPECT_EQ(1, snd_mixer_open_called);
    514   EXPECT_EQ(1, snd_mixer_attach_called);
    515   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    516   EXPECT_EQ(1, snd_mixer_selem_register_called);
    517   EXPECT_EQ(1, snd_mixer_load_called);
    518   EXPECT_EQ(0, snd_mixer_close_called);
    519   EXPECT_EQ(2, snd_mixer_elem_next_called);
    520   EXPECT_EQ(5, snd_mixer_selem_get_name_called);
    521   EXPECT_EQ(3, snd_mixer_selem_has_playback_switch_called);
    522 
    523   /* Set mute should be called for Master only. */
    524   cras_alsa_mixer_set_mute(c, 0, NULL);
    525   EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_called);
    526 
    527   /* Set volume should be called for Master and PCM. If Master doesn't set to
    528    * anything but zero then the entire volume should be passed to the PCM
    529    * control.*/
    530 
    531   /* Set volume should be called for Master and PCM. (without mixer_output) */
    532   snd_mixer_selem_get_playback_dB_return_values = get_dB_returns;
    533   snd_mixer_selem_get_playback_dB_return_values_length =
    534       ARRAY_SIZE(get_dB_returns);
    535   cras_alsa_mixer_set_dBFS(c, -50, NULL);
    536   EXPECT_EQ(2, snd_mixer_selem_set_playback_dB_all_called);
    537   EXPECT_EQ(2, snd_mixer_selem_get_playback_dB_called);
    538   /* volume should be set relative to max volume (40 + 40). */
    539   EXPECT_EQ(30, set_dB_values[0]);
    540   EXPECT_EQ(30, set_dB_values[1]);
    541 
    542   ResetStubData();
    543   snd_mixer_selem_set_playback_dB_all_values = set_dB_values;
    544   snd_mixer_selem_set_playback_dB_all_values_length = ARRAY_SIZE(set_dB_values);
    545   snd_mixer_selem_get_playback_dB_range_min_values = min_volumes;
    546   snd_mixer_selem_get_playback_dB_range_max_values = max_volumes;
    547   snd_mixer_selem_get_playback_dB_range_values_length = ARRAY_SIZE(min_volumes);
    548   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
    549   snd_mixer_selem_has_playback_volume_return_values_length =
    550       ARRAY_SIZE(element_playback_volume);
    551   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
    552   snd_mixer_selem_has_playback_switch_return_values_length =
    553       ARRAY_SIZE(element_playback_switches);
    554   snd_mixer_selem_get_name_return_values = element_names;
    555   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    556   rc = mixer_control_create(&mixer_output, NULL,
    557                             reinterpret_cast<snd_mixer_elem_t *>(3),
    558                             CRAS_STREAM_OUTPUT);
    559   EXPECT_EQ(0, rc);
    560   EXPECT_EQ(1, snd_mixer_selem_get_name_called);
    561   EXPECT_EQ(1, snd_mixer_selem_has_playback_volume_called);
    562   EXPECT_EQ(1, snd_mixer_selem_has_playback_switch_called);
    563   EXPECT_EQ(1, snd_mixer_selem_get_playback_dB_range_called);
    564 
    565   /* Set volume should be called for Master, PCM, and the mixer_output passed
    566    * in. If Master doesn't set to anything but zero then the entire volume
    567    * should be passed to the PCM control.*/
    568   cras_alsa_mixer_set_dBFS(c, -50, mixer_output);
    569   EXPECT_EQ(3, snd_mixer_selem_set_playback_dB_all_called);
    570   EXPECT_EQ(2, snd_mixer_selem_get_playback_dB_called);
    571   EXPECT_EQ(30, set_dB_values[0]);
    572   EXPECT_EQ(30, set_dB_values[1]);
    573   EXPECT_EQ(30, set_dB_values[2]);
    574   /* Set volume should be called for Master and PCM. Since the controls were
    575    * sorted, Master should get the volume remaining after PCM is set, in this
    576    * case -50 - -24 = -26. */
    577   long get_dB_returns2[] = {
    578     -25,
    579     -24,
    580   };
    581   snd_mixer_selem_get_playback_dB_return_values = get_dB_returns2;
    582   snd_mixer_selem_get_playback_dB_return_values_length =
    583       ARRAY_SIZE(get_dB_returns2);
    584   snd_mixer_selem_set_playback_dB_all_called = 0;
    585   snd_mixer_selem_get_playback_dB_called = 0;
    586   mixer_output->has_volume = 0;
    587   mixer_output->min_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
    588   mixer_output->max_volume_dB = MIXER_CONTROL_VOLUME_DB_INVALID;
    589   cras_alsa_mixer_set_dBFS(c, -50, mixer_output);
    590   EXPECT_EQ(2, snd_mixer_selem_set_playback_dB_all_called);
    591   EXPECT_EQ(2, snd_mixer_selem_get_playback_dB_called);
    592   EXPECT_EQ(54, set_dB_values[0]); // Master
    593   EXPECT_EQ(30, set_dB_values[1]); // PCM
    594 
    595   cras_alsa_mixer_destroy(c);
    596   EXPECT_EQ(1, snd_mixer_close_called);
    597   mixer_control_destroy(mixer_output);
    598 }
    599 
    600 TEST(AlsaMixer, CreateTwoMainCaptureElements) {
    601   struct cras_alsa_mixer *c;
    602   snd_mixer_elem_t *elements[] = {
    603     reinterpret_cast<snd_mixer_elem_t *>(2),
    604   };
    605   int element_capture_volume[] = {
    606     1,
    607     1,
    608     1,
    609   };
    610   int element_capture_switches[] = {
    611     1,
    612     1,
    613     1,
    614   };
    615   const char *element_names[] = {
    616     "Capture",
    617     "Digital Capture",
    618     "Mic",
    619   };
    620   struct mixer_control *mixer_input;
    621   int rc;
    622 
    623   ResetStubData();
    624   snd_mixer_first_elem_return_value = reinterpret_cast<snd_mixer_elem_t *>(1);
    625   snd_mixer_elem_next_return_values = elements;
    626   snd_mixer_elem_next_return_values_length = ARRAY_SIZE(elements);
    627   snd_mixer_selem_has_capture_volume_return_values = element_capture_volume;
    628   snd_mixer_selem_has_capture_volume_return_values_length =
    629       ARRAY_SIZE(element_capture_volume);
    630   snd_mixer_selem_has_capture_switch_return_values = element_capture_switches;
    631   snd_mixer_selem_has_capture_switch_return_values_length =
    632       ARRAY_SIZE(element_capture_switches);
    633   snd_mixer_selem_get_name_return_values = element_names;
    634   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    635   c = create_mixer_and_add_controls_by_name_matching(
    636       "hw:0", NULL, NULL);
    637   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
    638   EXPECT_EQ(1, snd_mixer_open_called);
    639   EXPECT_EQ(1, snd_mixer_attach_called);
    640   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    641   EXPECT_EQ(1, snd_mixer_selem_register_called);
    642   EXPECT_EQ(1, snd_mixer_load_called);
    643   EXPECT_EQ(0, snd_mixer_close_called);
    644   EXPECT_EQ(2, snd_mixer_elem_next_called);
    645   EXPECT_EQ(5, snd_mixer_selem_get_name_called);
    646   EXPECT_EQ(3, snd_mixer_selem_has_capture_switch_called);
    647 
    648   /* Set mute should be called for Master only. */
    649   cras_alsa_mixer_set_capture_mute(c, 0, NULL);
    650   EXPECT_EQ(1, snd_mixer_selem_set_capture_switch_all_called);
    651   /* Set volume should be called for Capture and Digital Capture. If Capture
    652    * doesn't set to anything but zero then the entire volume should be passed to
    653    * the Digital Capture control. */
    654   long get_dB_returns[] = {
    655     0,
    656     0,
    657   };
    658   long set_dB_values[2];
    659   snd_mixer_selem_get_capture_dB_return_values = get_dB_returns;
    660   snd_mixer_selem_get_capture_dB_return_values_length =
    661       ARRAY_SIZE(get_dB_returns);
    662   snd_mixer_selem_set_capture_dB_all_values = set_dB_values;
    663   snd_mixer_selem_set_capture_dB_all_values_length =
    664       ARRAY_SIZE(set_dB_values);
    665   cras_alsa_mixer_set_capture_dBFS(c, -10, NULL);
    666   EXPECT_EQ(2, snd_mixer_selem_set_capture_dB_all_called);
    667   EXPECT_EQ(2, snd_mixer_selem_get_capture_dB_called);
    668   EXPECT_EQ(-10, set_dB_values[0]);
    669   EXPECT_EQ(-10, set_dB_values[1]);
    670   /* Set volume should be called for Capture and Digital Capture. Capture should
    671    * get the gain remaining after Mic Boos is set, in this case 20 - 25 = -5. */
    672   long get_dB_returns2[] = {
    673     25,
    674     -5,
    675   };
    676   snd_mixer_selem_get_capture_dB_return_values = get_dB_returns2;
    677   snd_mixer_selem_get_capture_dB_return_values_length =
    678       ARRAY_SIZE(get_dB_returns2);
    679   snd_mixer_selem_set_capture_dB_all_values = set_dB_values;
    680   snd_mixer_selem_set_capture_dB_all_values_length =
    681       ARRAY_SIZE(set_dB_values);
    682   snd_mixer_selem_set_capture_dB_all_called = 0;
    683   snd_mixer_selem_get_capture_dB_called = 0;
    684   cras_alsa_mixer_set_capture_dBFS(c, 20, NULL);
    685   EXPECT_EQ(2, snd_mixer_selem_set_capture_dB_all_called);
    686   EXPECT_EQ(2, snd_mixer_selem_get_capture_dB_called);
    687   EXPECT_EQ(20, set_dB_values[0]);
    688   EXPECT_EQ(-5, set_dB_values[1]);
    689 
    690   /* Set volume to the two main controls plus additional specific input
    691    * volume control */
    692 
    693   long get_dB_returns3[] = {
    694     0,
    695     0,
    696     0,
    697   };
    698   long set_dB_values3[3];
    699 
    700   snd_mixer_selem_get_capture_dB_return_values = get_dB_returns3;
    701   snd_mixer_selem_get_capture_dB_return_values_length =
    702       ARRAY_SIZE(get_dB_returns3);
    703   snd_mixer_selem_get_capture_dB_called = 0;
    704   snd_mixer_selem_set_capture_dB_all_values = set_dB_values3;
    705   snd_mixer_selem_set_capture_dB_all_values_length =
    706       ARRAY_SIZE(set_dB_values3);
    707   snd_mixer_selem_set_capture_dB_all_called = 0;
    708   snd_mixer_selem_has_capture_volume_return_values = element_capture_volume;
    709   snd_mixer_selem_has_capture_volume_return_values_length =
    710       ARRAY_SIZE(element_capture_volume);
    711   snd_mixer_selem_has_capture_switch_return_values = element_capture_switches;
    712   snd_mixer_selem_has_capture_switch_return_values_length =
    713       ARRAY_SIZE(element_capture_switches);
    714   snd_mixer_selem_get_name_return_values = element_names;
    715   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    716   snd_mixer_selem_get_name_called = 0;
    717   snd_mixer_selem_has_capture_volume_called = 0;
    718   snd_mixer_selem_has_capture_switch_called = 0;
    719   snd_mixer_selem_get_capture_dB_range_called = 0;
    720   rc = mixer_control_create(&mixer_input, NULL,
    721                             reinterpret_cast<snd_mixer_elem_t *>(3),
    722                             CRAS_STREAM_INPUT);
    723   EXPECT_EQ(0, rc);
    724   EXPECT_EQ(1, snd_mixer_selem_get_name_called);
    725   EXPECT_EQ(1, snd_mixer_selem_has_capture_volume_called);
    726   EXPECT_EQ(1, snd_mixer_selem_has_capture_switch_called);
    727   EXPECT_EQ(1, snd_mixer_selem_get_capture_dB_range_called);
    728   EXPECT_EQ(1, mixer_input->has_volume);
    729 
    730   cras_alsa_mixer_set_capture_dBFS(c, 20, mixer_input);
    731 
    732   EXPECT_EQ(3, snd_mixer_selem_set_capture_dB_all_called);
    733   EXPECT_EQ(2, snd_mixer_selem_get_capture_dB_called);
    734   EXPECT_EQ(20, set_dB_values3[0]);
    735   EXPECT_EQ(20, set_dB_values3[1]);
    736   EXPECT_EQ(20, set_dB_values3[2]);
    737 
    738   cras_alsa_mixer_destroy(c);
    739   EXPECT_EQ(1, snd_mixer_close_called);
    740   mixer_control_destroy(mixer_input);
    741 }
    742 
    743 class AlsaMixerOutputs : public testing::Test {
    744  protected:
    745   virtual void SetUp() {
    746     output_called_values_.clear();
    747     output_callback_called_ = 0;
    748     static snd_mixer_elem_t *elements[] = {
    749       reinterpret_cast<snd_mixer_elem_t *>(2),  // PCM
    750       reinterpret_cast<snd_mixer_elem_t *>(3),  // Headphone
    751       reinterpret_cast<snd_mixer_elem_t *>(4),  // Speaker
    752       reinterpret_cast<snd_mixer_elem_t *>(5),  // HDMI
    753       reinterpret_cast<snd_mixer_elem_t *>(6),  // IEC958
    754       reinterpret_cast<snd_mixer_elem_t *>(7),  // Mic Boost
    755       reinterpret_cast<snd_mixer_elem_t *>(8),  // Capture
    756     };
    757     static int element_playback_volume[] = {
    758       1,
    759       1,
    760       1,
    761       0,
    762       0,
    763       1,
    764       1,
    765     };
    766     static int element_playback_switches[] = {
    767       1,
    768       1,
    769       1,
    770       0,
    771       1,
    772       1,
    773       1,
    774     };
    775     static int element_capture_volume[] = {0, 0, 0, 0, 0, 0,
    776       1,
    777       1,
    778     };
    779     static int element_capture_switches[] = {0, 0, 0, 0, 0, 0,
    780       1,
    781       1,
    782     };
    783     static const long min_volumes[] = {0, 0, 0, 0, 0, 0, 500, -1250};
    784     static const long max_volumes[] = {0, 0, 0, 0, 0, 0, 3000, 400};
    785     static const char *element_names[] = {
    786       "Master",
    787       "PCM",
    788       "Headphone",
    789       "Speaker",
    790       "HDMI",
    791       "IEC958",
    792       "Capture",
    793       "Digital Capture",
    794     };
    795     static const char *output_names_extra[] = {
    796       "IEC958"
    797     };
    798     static char *iniparser_returns[] = {
    799       NULL,
    800     };
    801     struct mixer_name *extra_controls =
    802         mixer_name_add_array(NULL, output_names_extra,
    803                              ARRAY_SIZE(output_names_extra),
    804                              CRAS_STREAM_OUTPUT,
    805                              MIXER_NAME_VOLUME);
    806 
    807     ResetStubData();
    808     snd_mixer_first_elem_return_value =
    809         reinterpret_cast<snd_mixer_elem_t *>(1);  // Master
    810     snd_mixer_elem_next_return_values = elements;
    811     snd_mixer_elem_next_return_values_length = ARRAY_SIZE(elements);
    812     snd_mixer_selem_has_playback_volume_return_values =
    813         element_playback_volume;
    814     snd_mixer_selem_has_playback_volume_return_values_length =
    815       ARRAY_SIZE(element_playback_volume);
    816     snd_mixer_selem_has_playback_switch_return_values =
    817         element_playback_switches;
    818     snd_mixer_selem_has_playback_switch_return_values_length =
    819       ARRAY_SIZE(element_playback_switches);
    820     snd_mixer_selem_has_capture_volume_return_values =
    821         element_capture_volume;
    822     snd_mixer_selem_has_capture_volume_return_values_length =
    823       ARRAY_SIZE(element_capture_volume);
    824     snd_mixer_selem_has_capture_switch_return_values =
    825         element_capture_switches;
    826     snd_mixer_selem_has_capture_switch_return_values_length =
    827       ARRAY_SIZE(element_capture_switches);
    828     snd_mixer_selem_get_name_return_values = element_names;
    829     snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    830     snd_mixer_selem_get_capture_dB_range_called = 0;
    831     snd_mixer_selem_get_capture_dB_range_min_values = min_volumes;
    832     snd_mixer_selem_get_capture_dB_range_max_values = max_volumes;
    833     snd_mixer_selem_get_capture_dB_range_values_length =
    834         ARRAY_SIZE(min_volumes);
    835     iniparser_getstring_returns = iniparser_returns;
    836     iniparser_getstring_return_length = ARRAY_SIZE(iniparser_returns);
    837     cras_mixer_ = create_mixer_and_add_controls_by_name_matching(
    838         "hw:0", extra_controls, NULL);
    839     ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), cras_mixer_);
    840     EXPECT_EQ(1, snd_mixer_open_called);
    841     EXPECT_EQ(1, snd_mixer_attach_called);
    842     EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
    843     EXPECT_EQ(1, snd_mixer_selem_register_called);
    844     EXPECT_EQ(1, snd_mixer_load_called);
    845     EXPECT_EQ(0, snd_mixer_close_called);
    846     EXPECT_EQ(ARRAY_SIZE(elements) + 1, snd_mixer_elem_next_called);
    847     EXPECT_EQ(8, snd_mixer_selem_has_playback_volume_called);
    848     EXPECT_EQ(7, snd_mixer_selem_has_playback_switch_called);
    849     EXPECT_EQ(4, snd_mixer_selem_has_capture_volume_called);
    850     EXPECT_EQ(3, snd_mixer_selem_has_capture_switch_called);
    851     mixer_name_free(extra_controls);
    852   }
    853 
    854   virtual void TearDown() {
    855     cras_alsa_mixer_destroy(cras_mixer_);
    856     EXPECT_EQ(1, snd_mixer_close_called);
    857   }
    858 
    859   static void OutputCallback(struct mixer_control *out, void *arg) {
    860     output_callback_called_++;
    861     output_called_values_.push_back(out);
    862   }
    863 
    864   struct cras_alsa_mixer *cras_mixer_;
    865   static size_t output_callback_called_;
    866   static std::vector<struct mixer_control *> output_called_values_;
    867 };
    868 
    869 size_t AlsaMixerOutputs::output_callback_called_;
    870 std::vector<struct mixer_control *>
    871     AlsaMixerOutputs::output_called_values_;
    872 
    873 TEST_F(AlsaMixerOutputs, CheckFourOutputs) {
    874   cras_alsa_mixer_list_outputs(cras_mixer_,
    875                                AlsaMixerOutputs::OutputCallback,
    876                                reinterpret_cast<void*>(555));
    877   EXPECT_EQ(4, output_callback_called_);
    878 }
    879 
    880 TEST_F(AlsaMixerOutputs, CheckFindOutputByNameNoMatch) {
    881   struct mixer_control *out;
    882 
    883   out = cras_alsa_mixer_get_output_matching_name(cras_mixer_,
    884                                                  "AAAAA Jack");
    885   EXPECT_EQ(static_cast<struct mixer_control *>(NULL), out);
    886 }
    887 
    888 TEST_F(AlsaMixerOutputs, CheckFindOutputByName) {
    889   struct mixer_control *out;
    890 
    891   out = cras_alsa_mixer_get_output_matching_name(cras_mixer_,
    892                                                  "Headphone Jack");
    893   EXPECT_NE(static_cast<struct mixer_control *>(NULL), out);
    894 }
    895 
    896 TEST_F(AlsaMixerOutputs, CheckFindOutputHDMIByName) {
    897   struct mixer_control *out;
    898 
    899   out = cras_alsa_mixer_get_output_matching_name(cras_mixer_,
    900                                                  "HDMI Jack");
    901   EXPECT_NE(static_cast<struct mixer_control *>(NULL), out);
    902 }
    903 
    904 TEST_F(AlsaMixerOutputs, CheckFindInputNameWorkaround) {
    905   struct mixer_control *control;
    906   snd_mixer_elem_t *elements[] = {
    907     reinterpret_cast<snd_mixer_elem_t *>(1),  // Speaker
    908     reinterpret_cast<snd_mixer_elem_t *>(2),  // Headphone
    909     reinterpret_cast<snd_mixer_elem_t *>(3),  // MIC
    910   };
    911   const char *element_names[] = {
    912     "Speaker",
    913     "Headphone",
    914     "MIC",
    915   };
    916   size_t i;
    917 
    918   ResetStubData();
    919   for (i = 0; i < ARRAY_SIZE(elements); i++)
    920     snd_mixer_find_elem_map[element_names[i]] = elements[i];
    921 
    922   snd_mixer_selem_get_name_called = 0;
    923   snd_mixer_selem_get_name_return_values = element_names;
    924   snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
    925   control = cras_alsa_mixer_get_input_matching_name(cras_mixer_,
    926                                                     "MIC");
    927   EXPECT_NE(static_cast<struct mixer_control *>(NULL), control);
    928   /* This exercises the 'workaround' where the control is added if it was
    929    * previouly missing in cras_alsa_mixer_get_input_matching_name().
    930    * snd_mixer_find_selem is called once for the missing control. */
    931   EXPECT_EQ(1, snd_mixer_find_selem_called);
    932   EXPECT_EQ(1, snd_mixer_selem_has_capture_volume_called);
    933   EXPECT_EQ(1, snd_mixer_selem_has_capture_switch_called);
    934 }
    935 
    936 TEST_F(AlsaMixerOutputs, ActivateDeactivate) {
    937   int rc;
    938 
    939   cras_alsa_mixer_list_outputs(cras_mixer_,
    940                                AlsaMixerOutputs::OutputCallback,
    941                                reinterpret_cast<void*>(555));
    942   EXPECT_EQ(4, output_callback_called_);
    943   EXPECT_EQ(4, output_called_values_.size());
    944 
    945   rc = cras_alsa_mixer_set_output_active_state(output_called_values_[0], 0);
    946   ASSERT_EQ(0, rc);
    947   EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_called);
    948   cras_alsa_mixer_set_output_active_state(output_called_values_[0], 1);
    949   EXPECT_EQ(2, snd_mixer_selem_set_playback_switch_all_called);
    950 }
    951 
    952 TEST_F(AlsaMixerOutputs, MinMaxCaptureGain) {
    953   long min, max;
    954   min = cras_alsa_mixer_get_minimum_capture_gain(cras_mixer_,
    955 		  NULL);
    956   EXPECT_EQ(-750, min);
    957   max = cras_alsa_mixer_get_maximum_capture_gain(cras_mixer_,
    958 		  NULL);
    959   EXPECT_EQ(3400, max);
    960 }
    961 
    962 TEST_F(AlsaMixerOutputs, MinMaxCaptureGainWithActiveInput) {
    963   struct mixer_control *mixer_input;
    964   long min, max;
    965 
    966   mixer_input = (struct mixer_control *)calloc(1, sizeof(*mixer_input));
    967   mixer_input->min_volume_dB = 50;
    968   mixer_input->max_volume_dB = 60;
    969   mixer_input->has_volume = 1;
    970   min = cras_alsa_mixer_get_minimum_capture_gain(cras_mixer_, mixer_input);
    971   max = cras_alsa_mixer_get_maximum_capture_gain(cras_mixer_, mixer_input);
    972   EXPECT_EQ(-700, min);
    973   EXPECT_EQ(3460, max);
    974 
    975   free((void *)mixer_input);
    976 }
    977 
    978 TEST(AlsaMixer, CreateWithCoupledOutputControls) {
    979   struct cras_alsa_mixer *c;
    980   struct mixer_control *output_control;
    981   struct mixer_control_element *c1, *c2, *c3, *c4;
    982 
    983   static const long min_volumes[] = {-70, -70};
    984   static const long max_volumes[] = {30, 30};
    985 
    986   long set_dB_values[2];
    987 
    988   const char *coupled_output_names[] = {"Left Master",
    989                                         "Right Master",
    990                                         "Left Speaker",
    991                                         "Right Speaker"};
    992   struct mixer_name *coupled_controls =
    993       mixer_name_add_array(NULL, coupled_output_names,
    994                            ARRAY_SIZE(coupled_output_names),
    995                            CRAS_STREAM_OUTPUT,
    996                            MIXER_NAME_VOLUME);
    997   int element_playback_volume[] = {1, 1, 0, 0};
    998   int element_playback_switches[] = {0, 0, 1, 1};
    999 
   1000   long target_dBFS = -30;
   1001   long expected_dB_value = target_dBFS + max_volumes[0];
   1002 
   1003   ResetStubData();
   1004 
   1005   snd_mixer_find_elem_map[std::string("Left Master")] =
   1006       reinterpret_cast<snd_mixer_elem_t *>(1);
   1007   snd_mixer_find_elem_map[std::string("Right Master")] =
   1008       reinterpret_cast<snd_mixer_elem_t *>(2);
   1009   snd_mixer_find_elem_map[std::string("Left Speaker")] =
   1010       reinterpret_cast<snd_mixer_elem_t *>(3);
   1011   snd_mixer_find_elem_map[std::string("Right Speaker")] =
   1012       reinterpret_cast<snd_mixer_elem_t *>(4);
   1013 
   1014   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
   1015   snd_mixer_selem_has_playback_volume_return_values_length =
   1016       ARRAY_SIZE(element_playback_volume);
   1017   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
   1018   snd_mixer_selem_has_playback_switch_return_values_length =
   1019       ARRAY_SIZE(element_playback_switches);
   1020 
   1021   snd_mixer_selem_get_playback_dB_range_min_values = min_volumes;
   1022   snd_mixer_selem_get_playback_dB_range_max_values = max_volumes;
   1023   snd_mixer_selem_get_playback_dB_range_values_length = ARRAY_SIZE(min_volumes);
   1024 
   1025   c = create_mixer_and_add_controls_by_name_matching(
   1026       "hw:0", NULL, coupled_controls);
   1027 
   1028   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
   1029   EXPECT_EQ(1, snd_mixer_open_called);
   1030   EXPECT_EQ(1, snd_mixer_attach_called);
   1031   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
   1032   EXPECT_EQ(1, snd_mixer_selem_register_called);
   1033   EXPECT_EQ(1, snd_mixer_load_called);
   1034   EXPECT_EQ(0, snd_mixer_close_called);
   1035 
   1036   output_control = c->output_controls;
   1037   EXPECT_EQ(NULL, output_control->next);
   1038   c1 = output_control->elements;
   1039   c2 = c1->next;
   1040   c3 = c2->next;
   1041   c4 = c3->next;
   1042   EXPECT_EQ(c1->elem, reinterpret_cast<snd_mixer_elem_t *>(1));
   1043   EXPECT_EQ(c2->elem, reinterpret_cast<snd_mixer_elem_t *>(2));
   1044   EXPECT_EQ(c3->elem, reinterpret_cast<snd_mixer_elem_t *>(3));
   1045   EXPECT_EQ(c4->elem, reinterpret_cast<snd_mixer_elem_t *>(4));
   1046   EXPECT_EQ(c4->next, reinterpret_cast<mixer_control_element *>(NULL));
   1047   EXPECT_EQ(c1->has_volume, 1);
   1048   EXPECT_EQ(c1->has_mute, 0);
   1049   EXPECT_EQ(c2->has_volume, 1);
   1050   EXPECT_EQ(c2->has_mute, 0);
   1051   EXPECT_EQ(c3->has_volume, 0);
   1052   EXPECT_EQ(c3->has_mute, 1);
   1053   EXPECT_EQ(c4->has_volume, 0);
   1054   EXPECT_EQ(c4->has_mute, 1);
   1055   EXPECT_EQ(output_control->max_volume_dB, max_volumes[0]);
   1056   EXPECT_EQ(output_control->min_volume_dB, min_volumes[0]);
   1057 
   1058   snd_mixer_selem_set_playback_dB_all_values = set_dB_values;
   1059   snd_mixer_selem_set_playback_dB_all_values_length =
   1060       ARRAY_SIZE(set_dB_values);
   1061 
   1062   cras_alsa_mixer_set_dBFS(c, target_dBFS, output_control);
   1063 
   1064   /* Set volume should set playback dB on two of the coupled controls. */
   1065   EXPECT_EQ(2, snd_mixer_selem_set_playback_dB_all_called);
   1066   EXPECT_EQ(set_dB_values[0], expected_dB_value);
   1067   EXPECT_EQ(set_dB_values[1], expected_dB_value);
   1068 
   1069   /* Mute should set playback switch on two of the coupled controls. */
   1070   cras_alsa_mixer_set_mute(c, 1, output_control);
   1071   EXPECT_EQ(2, snd_mixer_selem_set_playback_switch_all_called);
   1072   EXPECT_EQ(0, snd_mixer_selem_set_playback_switch_all_value);
   1073 
   1074   /* Unmute should set playback switch on two of the coupled controls. */
   1075   cras_alsa_mixer_set_mute(c, 0, output_control);
   1076   EXPECT_EQ(4, snd_mixer_selem_set_playback_switch_all_called);
   1077   EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_value);
   1078 
   1079   EXPECT_EQ(max_volumes[0] - min_volumes[0],
   1080             cras_alsa_mixer_get_output_dB_range(output_control));
   1081 
   1082   cras_alsa_mixer_destroy(c);
   1083   EXPECT_EQ(1, snd_mixer_close_called);
   1084   mixer_name_free(coupled_controls);
   1085 }
   1086 
   1087 TEST(AlsaMixer, CoupledOutputHasMuteNoVolume) {
   1088   struct cras_alsa_mixer *c;
   1089   struct mixer_control *output_control;
   1090   struct mixer_control_element *c1, *c2, *c3, *c4;
   1091 
   1092   static const long min_volumes[] = {-70};
   1093   static const long max_volumes[] = {30};
   1094 
   1095   const char *coupled_output_names[] = {"Left Master",
   1096                                         "Right Master",
   1097                                         "Left Speaker",
   1098                                         "Right Speaker"};
   1099   struct mixer_name *coupled_controls =
   1100       mixer_name_add_array(NULL, coupled_output_names,
   1101                            ARRAY_SIZE(coupled_output_names),
   1102                            CRAS_STREAM_OUTPUT,
   1103                            MIXER_NAME_VOLUME);
   1104   int element_playback_volume[] = {0, 0, 0, 0};
   1105   int element_playback_switches[] = {0, 0, 1, 1};
   1106 
   1107   ResetStubData();
   1108 
   1109   snd_mixer_find_elem_map[std::string("Left Master")] =
   1110       reinterpret_cast<snd_mixer_elem_t *>(1);
   1111   snd_mixer_find_elem_map[std::string("Right Master")] =
   1112       reinterpret_cast<snd_mixer_elem_t *>(2);
   1113   snd_mixer_find_elem_map[std::string("Left Speaker")] =
   1114       reinterpret_cast<snd_mixer_elem_t *>(3);
   1115   snd_mixer_find_elem_map[std::string("Right Speaker")] =
   1116       reinterpret_cast<snd_mixer_elem_t *>(4);
   1117 
   1118   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
   1119   snd_mixer_selem_has_playback_volume_return_values_length =
   1120       ARRAY_SIZE(element_playback_volume);
   1121   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
   1122   snd_mixer_selem_has_playback_switch_return_values_length =
   1123       ARRAY_SIZE(element_playback_switches);
   1124 
   1125   snd_mixer_selem_get_playback_dB_range_min_values = min_volumes;
   1126   snd_mixer_selem_get_playback_dB_range_max_values = max_volumes;
   1127   snd_mixer_selem_get_playback_dB_range_values_length = ARRAY_SIZE(min_volumes);
   1128 
   1129   c = create_mixer_and_add_controls_by_name_matching(
   1130       "hw:0", NULL, coupled_controls);
   1131 
   1132   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
   1133   EXPECT_EQ(1, snd_mixer_open_called);
   1134   EXPECT_EQ(1, snd_mixer_attach_called);
   1135   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
   1136   EXPECT_EQ(1, snd_mixer_selem_register_called);
   1137   EXPECT_EQ(1, snd_mixer_load_called);
   1138   EXPECT_EQ(0, snd_mixer_close_called);
   1139 
   1140   output_control = c->output_controls;
   1141   EXPECT_EQ(NULL, output_control->next);
   1142   c1 = output_control->elements;
   1143   c2 = c1->next;
   1144   c3 = c2->next;
   1145   c4 = c3->next;
   1146   EXPECT_EQ(c1->elem, reinterpret_cast<snd_mixer_elem_t *>(1));
   1147   EXPECT_EQ(c2->elem, reinterpret_cast<snd_mixer_elem_t *>(2));
   1148   EXPECT_EQ(c3->elem, reinterpret_cast<snd_mixer_elem_t *>(3));
   1149   EXPECT_EQ(c4->elem, reinterpret_cast<snd_mixer_elem_t *>(4));
   1150   EXPECT_EQ(c4->next, reinterpret_cast<mixer_control_element *>(NULL));
   1151   EXPECT_EQ(c1->has_volume, 0);
   1152   EXPECT_EQ(c1->has_mute, 0);
   1153   EXPECT_EQ(c2->has_volume, 0);
   1154   EXPECT_EQ(c2->has_mute, 0);
   1155   EXPECT_EQ(c3->has_volume, 0);
   1156   EXPECT_EQ(c3->has_mute, 1);
   1157   EXPECT_EQ(c4->has_volume, 0);
   1158   EXPECT_EQ(c4->has_mute, 1);
   1159 
   1160   EXPECT_EQ(0, cras_alsa_mixer_has_volume(output_control));
   1161   EXPECT_EQ(1, output_control->has_mute);
   1162 
   1163   cras_alsa_mixer_destroy(c);
   1164   EXPECT_EQ(1, snd_mixer_close_called);
   1165   mixer_name_free(coupled_controls);
   1166 }
   1167 
   1168 TEST(AlsaMixer, CoupledOutputHasVolumeNoMute) {
   1169   struct cras_alsa_mixer *c;
   1170   struct mixer_control *output_control;
   1171   struct mixer_control_element *c1, *c2, *c3, *c4;
   1172 
   1173   static const long min_volumes[] = {-70, -70};
   1174   static const long max_volumes[] = {30, 30};
   1175 
   1176   const char *coupled_output_names[] = {"Left Master",
   1177                                         "Right Master",
   1178                                         "Left Speaker",
   1179                                         "Right Speaker"};
   1180   struct mixer_name *coupled_controls =
   1181       mixer_name_add_array(NULL, coupled_output_names,
   1182                            ARRAY_SIZE(coupled_output_names),
   1183                            CRAS_STREAM_OUTPUT,
   1184                            MIXER_NAME_VOLUME);
   1185   int element_playback_volume[] = {1, 1, 0, 0};
   1186   int element_playback_switches[] = {0, 0, 0, 0};
   1187 
   1188   ResetStubData();
   1189 
   1190   snd_mixer_find_elem_map[std::string("Left Master")] =
   1191       reinterpret_cast<snd_mixer_elem_t *>(1);
   1192   snd_mixer_find_elem_map[std::string("Right Master")] =
   1193       reinterpret_cast<snd_mixer_elem_t *>(2);
   1194   snd_mixer_find_elem_map[std::string("Left Speaker")] =
   1195       reinterpret_cast<snd_mixer_elem_t *>(3);
   1196   snd_mixer_find_elem_map[std::string("Right Speaker")] =
   1197       reinterpret_cast<snd_mixer_elem_t *>(4);
   1198 
   1199   snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
   1200   snd_mixer_selem_has_playback_volume_return_values_length =
   1201       ARRAY_SIZE(element_playback_volume);
   1202   snd_mixer_selem_has_playback_switch_return_values = element_playback_switches;
   1203   snd_mixer_selem_has_playback_switch_return_values_length =
   1204       ARRAY_SIZE(element_playback_switches);
   1205 
   1206   snd_mixer_selem_get_playback_dB_range_min_values = min_volumes;
   1207   snd_mixer_selem_get_playback_dB_range_max_values = max_volumes;
   1208   snd_mixer_selem_get_playback_dB_range_values_length = ARRAY_SIZE(min_volumes);
   1209 
   1210   c = create_mixer_and_add_controls_by_name_matching(
   1211       "hw:0", NULL, coupled_controls);
   1212 
   1213   ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), c);
   1214   EXPECT_EQ(1, snd_mixer_open_called);
   1215   EXPECT_EQ(1, snd_mixer_attach_called);
   1216   EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
   1217   EXPECT_EQ(1, snd_mixer_selem_register_called);
   1218   EXPECT_EQ(1, snd_mixer_load_called);
   1219   EXPECT_EQ(0, snd_mixer_close_called);
   1220 
   1221   output_control = c->output_controls;
   1222   EXPECT_EQ(NULL, output_control->next);
   1223   c1 = output_control->elements;
   1224   c2 = c1->next;
   1225   c3 = c2->next;
   1226   c4 = c3->next;
   1227   EXPECT_EQ(c1->elem, reinterpret_cast<snd_mixer_elem_t *>(1));
   1228   EXPECT_EQ(c2->elem, reinterpret_cast<snd_mixer_elem_t *>(2));
   1229   EXPECT_EQ(c3->elem, reinterpret_cast<snd_mixer_elem_t *>(3));
   1230   EXPECT_EQ(c4->elem, reinterpret_cast<snd_mixer_elem_t *>(4));
   1231   EXPECT_EQ(c4->next, reinterpret_cast<mixer_control_element *>(NULL));
   1232   EXPECT_EQ(c1->has_volume, 1);
   1233   EXPECT_EQ(c1->has_mute, 0);
   1234   EXPECT_EQ(c2->has_volume, 1);
   1235   EXPECT_EQ(c2->has_mute, 0);
   1236   EXPECT_EQ(c3->has_volume, 0);
   1237   EXPECT_EQ(c3->has_mute, 0);
   1238   EXPECT_EQ(c4->has_volume, 0);
   1239   EXPECT_EQ(c4->has_mute, 0);
   1240 
   1241   EXPECT_EQ(1, cras_alsa_mixer_has_volume(output_control));
   1242   EXPECT_EQ(0, output_control->has_mute);
   1243 
   1244   cras_alsa_mixer_destroy(c);
   1245   EXPECT_EQ(1, snd_mixer_close_called);
   1246   mixer_name_free(coupled_controls);
   1247 }
   1248 
   1249 TEST(AlsaMixer, MixerName) {
   1250   struct mixer_name *names;
   1251   struct mixer_name *control;
   1252   size_t mixer_name_count;
   1253   static const char *element_names[] = {
   1254     "Master",
   1255     "PCM",
   1256     "Headphone",
   1257     "Speaker",
   1258     "HDMI",
   1259     "IEC958",
   1260   };
   1261 
   1262   names = mixer_name_add_array(NULL, element_names,
   1263                                ARRAY_SIZE(element_names),
   1264                                CRAS_STREAM_OUTPUT, MIXER_NAME_VOLUME);
   1265   names = mixer_name_add(names, "Playback",
   1266                          CRAS_STREAM_OUTPUT, MIXER_NAME_VOLUME);
   1267   names = mixer_name_add(names, "Main",
   1268                          CRAS_STREAM_OUTPUT, MIXER_NAME_MAIN_VOLUME);
   1269   names = mixer_name_add(names, "Mic",
   1270                          CRAS_STREAM_INPUT, MIXER_NAME_VOLUME);
   1271   names = mixer_name_add(names, "Capture",
   1272                          CRAS_STREAM_INPUT, MIXER_NAME_MAIN_VOLUME);
   1273 
   1274   /* Number of items (test mixer_name_add(_array)). */
   1275   mixer_name_count = 0;
   1276   DL_FOREACH(names, control) {
   1277     mixer_name_count++;
   1278   }
   1279   EXPECT_EQ(10, mixer_name_count);
   1280 
   1281   /* Item not in the list: mismatch direction. */
   1282   control = mixer_name_find(names, "Main",
   1283                             CRAS_STREAM_INPUT, MIXER_NAME_UNDEFINED);
   1284   EXPECT_EQ(1, control == NULL);
   1285 
   1286   /* Item not in the list: mismatch type. */
   1287   control = mixer_name_find(names, "Main",
   1288                             CRAS_STREAM_OUTPUT, MIXER_NAME_VOLUME);
   1289   EXPECT_EQ(1, control == NULL);
   1290 
   1291   /* Find by name and direction. */
   1292   control = mixer_name_find(names, "Main",
   1293                             CRAS_STREAM_OUTPUT, MIXER_NAME_UNDEFINED);
   1294   EXPECT_EQ(0, strcmp("Main", control->name));
   1295 
   1296   /* Find by type and direction. */
   1297   control = mixer_name_find(names, NULL,
   1298                             CRAS_STREAM_INPUT, MIXER_NAME_VOLUME);
   1299   EXPECT_EQ(0, strcmp("Mic", control->name));
   1300 
   1301   mixer_name_free(names);
   1302 }
   1303 
   1304 class AlsaMixerFullySpeced : public testing::Test {
   1305  protected:
   1306   virtual void SetUp() {
   1307     callback_values_.clear();
   1308     callback_called_ = 0;
   1309     static snd_mixer_elem_t *elements[] = {
   1310       reinterpret_cast<snd_mixer_elem_t *>(1),  // HP-L
   1311       reinterpret_cast<snd_mixer_elem_t *>(2),  // HP-R
   1312       reinterpret_cast<snd_mixer_elem_t *>(3),  // SPK-L
   1313       reinterpret_cast<snd_mixer_elem_t *>(4),  // SPK-R
   1314       reinterpret_cast<snd_mixer_elem_t *>(5),  // HDMI
   1315       reinterpret_cast<snd_mixer_elem_t *>(6),  // CAPTURE
   1316       reinterpret_cast<snd_mixer_elem_t *>(7),  // MIC-L
   1317       reinterpret_cast<snd_mixer_elem_t *>(8),  // MIC-R
   1318       reinterpret_cast<snd_mixer_elem_t *>(0),  // Unknown
   1319     };
   1320     static int element_playback_volume[] = {
   1321       1,
   1322       1,
   1323       1,
   1324       1,
   1325       1,
   1326       0, 0, 0,
   1327     };
   1328     static int element_playback_switches[] = {
   1329       0,
   1330       0,
   1331       0,
   1332       0,
   1333       1,
   1334       0, 0, 0,
   1335     };
   1336     static int element_capture_volume[] = {0, 0, 0, 0, 0,
   1337       0,
   1338       1,
   1339       1,
   1340     };
   1341     static int element_capture_switches[] = {0, 0, 0, 0, 0,
   1342       1,
   1343       0,
   1344       0,
   1345     };
   1346     static const long min_volumes[] = {-84, -84, -84, -84, -84, 0, 0, 0};
   1347     static const long max_volumes[] = {0, 0, 0, 0, 0, 0, 84, 84};
   1348     static const char *element_names[] = {
   1349       "HP-L",
   1350       "HP-R",
   1351       "SPK-L",
   1352       "SPK-R",
   1353       "HDMI",
   1354       "CAPTURE",
   1355       "MIC-L",
   1356       "MIC-R",
   1357       "Unknown"
   1358     };
   1359     struct ucm_section *sections = NULL;
   1360     struct ucm_section *section;
   1361     size_t i;
   1362 
   1363     ResetStubData();
   1364 
   1365     for (i = 0; i < ARRAY_SIZE(elements); i++)
   1366        snd_mixer_find_elem_map[element_names[i]] = elements[i];
   1367 
   1368     section = ucm_section_create("NullElement", 0, CRAS_STREAM_OUTPUT,
   1369                                  NULL, NULL);
   1370     ucm_section_set_mixer_name(section, "Unknown");
   1371     DL_APPEND(sections, section);
   1372     section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
   1373                                  "my-sound-card Headset Jack", "gpio");
   1374     ucm_section_add_coupled(section, "HP-L", MIXER_NAME_VOLUME);
   1375     ucm_section_add_coupled(section, "HP-R", MIXER_NAME_VOLUME);
   1376     DL_APPEND(sections, section);
   1377     section = ucm_section_create("Speaker", 0, CRAS_STREAM_OUTPUT,
   1378                                  NULL, NULL);
   1379     ucm_section_add_coupled(section, "SPK-L", MIXER_NAME_VOLUME);
   1380     ucm_section_add_coupled(section, "SPK-R", MIXER_NAME_VOLUME);
   1381     DL_APPEND(sections, section);
   1382     section = ucm_section_create("Mic", 0, CRAS_STREAM_INPUT,
   1383                                  "my-sound-card Headset Jack", "gpio");
   1384     ucm_section_set_mixer_name(section, "CAPTURE");
   1385     DL_APPEND(sections, section);
   1386     section = ucm_section_create("Internal Mic", 0, CRAS_STREAM_INPUT,
   1387                                  NULL, NULL);
   1388     ucm_section_add_coupled(section, "MIC-L", MIXER_NAME_VOLUME);
   1389     ucm_section_add_coupled(section, "MIC-R", MIXER_NAME_VOLUME);
   1390     DL_APPEND(sections, section);
   1391     section = ucm_section_create("HDMI", 0, CRAS_STREAM_OUTPUT,
   1392                                  NULL, NULL);
   1393     ucm_section_set_mixer_name(section, "HDMI");
   1394     DL_APPEND(sections, section);
   1395     ASSERT_NE(sections, (struct ucm_section *)NULL);
   1396 
   1397     snd_mixer_selem_has_playback_volume_return_values =
   1398         element_playback_volume;
   1399     snd_mixer_selem_has_playback_volume_return_values_length =
   1400       ARRAY_SIZE(element_playback_volume);
   1401     snd_mixer_selem_has_playback_switch_return_values =
   1402         element_playback_switches;
   1403     snd_mixer_selem_has_playback_switch_return_values_length =
   1404       ARRAY_SIZE(element_playback_switches);
   1405     snd_mixer_selem_has_capture_volume_return_values =
   1406         element_capture_volume;
   1407     snd_mixer_selem_has_capture_volume_return_values_length =
   1408       ARRAY_SIZE(element_capture_volume);
   1409     snd_mixer_selem_has_capture_switch_return_values =
   1410         element_capture_switches;
   1411     snd_mixer_selem_has_capture_switch_return_values_length =
   1412       ARRAY_SIZE(element_capture_switches);
   1413     snd_mixer_selem_get_name_return_values = element_names;
   1414     snd_mixer_selem_get_name_return_values_length = ARRAY_SIZE(element_names);
   1415     snd_mixer_selem_get_capture_dB_range_min_values = min_volumes;
   1416     snd_mixer_selem_get_capture_dB_range_max_values = max_volumes;
   1417     snd_mixer_selem_get_capture_dB_range_values_length =
   1418         ARRAY_SIZE(min_volumes);
   1419 
   1420     cras_mixer_ = cras_alsa_mixer_create("hw:0");
   1421     ASSERT_NE(static_cast<struct cras_alsa_mixer *>(NULL), cras_mixer_);
   1422     EXPECT_EQ(1, snd_mixer_open_called);
   1423     EXPECT_EQ(1, snd_mixer_attach_called);
   1424     EXPECT_EQ(0, strcmp(snd_mixer_attach_mixdev, "hw:0"));
   1425     EXPECT_EQ(1, snd_mixer_selem_register_called);
   1426     EXPECT_EQ(1, snd_mixer_load_called);
   1427     EXPECT_EQ(0, snd_mixer_close_called);
   1428 
   1429     section = sections;
   1430     EXPECT_EQ(-ENOENT,\
   1431               cras_alsa_mixer_add_controls_in_section(cras_mixer_, section));
   1432     ASSERT_NE((struct ucm_section *)NULL, section->next);
   1433     section = section->next;
   1434     EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section(cras_mixer_, section));
   1435     ASSERT_NE((struct ucm_section *)NULL, section->next);
   1436     section = section->next;
   1437     EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section(cras_mixer_, section));
   1438     ASSERT_NE((struct ucm_section *)NULL, section->next);
   1439     section = section->next;
   1440     EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section(cras_mixer_, section));
   1441     ASSERT_NE((struct ucm_section *)NULL, section->next);
   1442     section = section->next;
   1443     EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section(cras_mixer_, section));
   1444     ASSERT_NE((struct ucm_section *)NULL, section->next);
   1445     section = section->next;
   1446     EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section(cras_mixer_, section));
   1447     EXPECT_EQ(section->next, (struct ucm_section*)NULL);
   1448 
   1449     EXPECT_EQ(9, snd_mixer_find_selem_called);
   1450     EXPECT_EQ(5, snd_mixer_selem_has_playback_volume_called);
   1451     EXPECT_EQ(5, snd_mixer_selem_has_playback_switch_called);
   1452     EXPECT_EQ(3, snd_mixer_selem_has_capture_volume_called);
   1453     EXPECT_EQ(3, snd_mixer_selem_has_capture_switch_called);
   1454     EXPECT_EQ(5, snd_mixer_selem_get_playback_dB_range_called);
   1455     EXPECT_EQ(2, snd_mixer_selem_get_capture_dB_range_called);
   1456 
   1457     sections_ = sections;
   1458   }
   1459 
   1460   virtual void TearDown() {
   1461     ucm_section_free_list(sections_);
   1462     cras_alsa_mixer_destroy(cras_mixer_);
   1463     EXPECT_EQ(1, snd_mixer_close_called);
   1464   }
   1465 
   1466   static void Callback(struct mixer_control *control, void *arg) {
   1467     callback_called_++;
   1468     callback_values_.push_back(control);
   1469   }
   1470 
   1471   struct cras_alsa_mixer *cras_mixer_;
   1472   static size_t callback_called_;
   1473   static std::vector<struct mixer_control *> callback_values_;
   1474   struct ucm_section *sections_;
   1475 };
   1476 
   1477 size_t AlsaMixerFullySpeced::callback_called_;
   1478 std::vector<struct mixer_control *> AlsaMixerFullySpeced::callback_values_;
   1479 
   1480 TEST_F(AlsaMixerFullySpeced, CheckControlCounts) {
   1481   cras_alsa_mixer_list_outputs(cras_mixer_,
   1482                                AlsaMixerFullySpeced::Callback,
   1483                                reinterpret_cast<void*>(555));
   1484   EXPECT_EQ(3, callback_called_);
   1485   callback_called_ = 0;
   1486   cras_alsa_mixer_list_inputs(cras_mixer_,
   1487                                AlsaMixerFullySpeced::Callback,
   1488                                reinterpret_cast<void*>(555));
   1489   EXPECT_EQ(2, callback_called_);
   1490 }
   1491 
   1492 TEST_F(AlsaMixerFullySpeced, CheckFindOutputByNameNoMatch) {
   1493   struct mixer_control *out;
   1494 
   1495   out = cras_alsa_mixer_get_output_matching_name(cras_mixer_,
   1496                                                  "AAAAA Jack");
   1497   EXPECT_EQ(static_cast<struct mixer_control *>(NULL), out);
   1498 }
   1499 
   1500 TEST_F(AlsaMixerFullySpeced, CheckFindOutputByName) {
   1501   struct mixer_control *out;
   1502 
   1503   out = cras_alsa_mixer_get_output_matching_name(cras_mixer_,
   1504                                                  "Headphone Jack");
   1505   EXPECT_NE(static_cast<struct mixer_control *>(NULL), out);
   1506 }
   1507 
   1508 TEST_F(AlsaMixerFullySpeced, CheckFindControlForSection) {
   1509   struct mixer_control *control;
   1510   struct ucm_section *section = sections_;
   1511 
   1512   // Look for the control for the Headphone section.
   1513   // We've already asserted that section != NULL above.
   1514   // Matching the control created by CoupledMixers.
   1515   section = section->next;
   1516   control = cras_alsa_mixer_get_control_for_section(cras_mixer_, section);
   1517   ASSERT_NE(static_cast<struct mixer_control *>(NULL), control);
   1518   EXPECT_EQ(0, strcmp(control->name, "Headphone"));
   1519 
   1520   // Look for the control for the Mic section.
   1521   // Matching the control created by MixerName.
   1522   section = section->next->next;
   1523   control = cras_alsa_mixer_get_control_for_section(cras_mixer_, section);
   1524   ASSERT_NE(static_cast<struct mixer_control *>(NULL), control);
   1525   EXPECT_EQ(0, strcmp(control->name, "CAPTURE"));
   1526 }
   1527 
   1528 /* Stubs */
   1529 
   1530 extern "C" {
   1531 int snd_mixer_open(snd_mixer_t **mixer, int mode) {
   1532   snd_mixer_open_called++;
   1533   *mixer = reinterpret_cast<snd_mixer_t *>(2);
   1534   return snd_mixer_open_return_value;
   1535 }
   1536 int snd_mixer_attach(snd_mixer_t *mixer, const char *name) {
   1537   snd_mixer_attach_called++;
   1538   snd_mixer_attach_mixdev = name;
   1539   return snd_mixer_attach_return_value;
   1540 }
   1541 int snd_mixer_selem_register(snd_mixer_t *mixer,
   1542                              struct snd_mixer_selem_regopt *options,
   1543                              snd_mixer_class_t **classp) {
   1544   snd_mixer_selem_register_called++;
   1545   return snd_mixer_selem_register_return_value;
   1546 }
   1547 int snd_mixer_load(snd_mixer_t *mixer) {
   1548   snd_mixer_load_called++;
   1549   return snd_mixer_load_return_value;
   1550 }
   1551 const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem) {
   1552   int index = reinterpret_cast<size_t>(elem) - 1;
   1553   snd_mixer_selem_get_name_called++;
   1554   if (index >= snd_mixer_selem_get_name_return_values_length)
   1555     return static_cast<char *>(NULL);
   1556 
   1557   return snd_mixer_selem_get_name_return_values[index];
   1558 }
   1559 unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem) {
   1560   return 0;
   1561 }
   1562 int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem) {
   1563   int index = reinterpret_cast<size_t>(elem) - 1;
   1564   snd_mixer_selem_has_playback_volume_called++;
   1565   if (index >= snd_mixer_selem_has_playback_volume_return_values_length)
   1566     return -1;
   1567 
   1568   return snd_mixer_selem_has_playback_volume_return_values[index];
   1569 }
   1570 int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem) {
   1571   int index = reinterpret_cast<size_t>(elem) - 1;
   1572   snd_mixer_selem_has_playback_switch_called++;
   1573   if (index >= snd_mixer_selem_has_playback_switch_return_values_length)
   1574     return -1;
   1575 
   1576   return snd_mixer_selem_has_playback_switch_return_values[index];
   1577 }
   1578 int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem) {
   1579   int index = reinterpret_cast<size_t>(elem) - 1;
   1580   snd_mixer_selem_has_capture_volume_called++;
   1581   if (index >= snd_mixer_selem_has_capture_volume_return_values_length)
   1582     return -1;
   1583 
   1584   return snd_mixer_selem_has_capture_volume_return_values[index];
   1585 }
   1586 int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem) {
   1587   int index = reinterpret_cast<size_t>(elem) - 1;
   1588   snd_mixer_selem_has_capture_switch_called++;
   1589   if (index >= snd_mixer_selem_has_capture_switch_return_values_length)
   1590     return -1;
   1591 
   1592   return snd_mixer_selem_has_capture_switch_return_values[index];
   1593 }
   1594 snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer) {
   1595   snd_mixer_first_elem_called++;
   1596   return snd_mixer_first_elem_return_value;
   1597 }
   1598 snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem) {
   1599   snd_mixer_elem_next_called++;
   1600   if (snd_mixer_elem_next_return_values_index >=
   1601       snd_mixer_elem_next_return_values_length)
   1602     return static_cast<snd_mixer_elem_t *>(NULL);
   1603 
   1604   return snd_mixer_elem_next_return_values[
   1605       snd_mixer_elem_next_return_values_index++];
   1606 }
   1607 int snd_mixer_close(snd_mixer_t *mixer) {
   1608   snd_mixer_close_called++;
   1609   return 0;
   1610 }
   1611 int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem,
   1612                                         long value,
   1613                                         int dir) {
   1614   int index = reinterpret_cast<size_t>(elem) - 1;
   1615   snd_mixer_selem_set_playback_dB_all_called++;
   1616   if (index < snd_mixer_selem_set_playback_dB_all_values_length)
   1617     snd_mixer_selem_set_playback_dB_all_values[index] = value;
   1618   return 0;
   1619 }
   1620 int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem,
   1621                                     snd_mixer_selem_channel_id_t channel,
   1622                                     long *value) {
   1623   int index = reinterpret_cast<size_t>(elem) - 1;
   1624   snd_mixer_selem_get_playback_dB_called++;
   1625   if (index >= snd_mixer_selem_get_playback_dB_return_values_length)
   1626     *value = 0;
   1627   else
   1628     *value = snd_mixer_selem_get_playback_dB_return_values[index];
   1629   return 0;
   1630 }
   1631 int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value) {
   1632   snd_mixer_selem_set_playback_switch_all_called++;
   1633   snd_mixer_selem_set_playback_switch_all_value = value;
   1634   return 0;
   1635 }
   1636 int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem,
   1637                                        long value,
   1638                                        int dir) {
   1639   int index = reinterpret_cast<size_t>(elem) - 1;
   1640   snd_mixer_selem_set_capture_dB_all_called++;
   1641   if (index < snd_mixer_selem_set_capture_dB_all_values_length)
   1642     snd_mixer_selem_set_capture_dB_all_values[index] = value;
   1643   return 0;
   1644 }
   1645 int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem,
   1646                                    snd_mixer_selem_channel_id_t channel,
   1647                                    long *value) {
   1648   int index = reinterpret_cast<size_t>(elem) - 1;
   1649   snd_mixer_selem_get_capture_dB_called++;
   1650   if (index >= snd_mixer_selem_get_capture_dB_return_values_length)
   1651     *value = 0;
   1652   else
   1653     *value = snd_mixer_selem_get_capture_dB_return_values[index];
   1654   return 0;
   1655 }
   1656 int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value) {
   1657   snd_mixer_selem_set_capture_switch_all_called++;
   1658   snd_mixer_selem_set_capture_switch_all_value = value;
   1659   return 0;
   1660 }
   1661 int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem, long *min,
   1662                                          long *max) {
   1663   size_t index = reinterpret_cast<size_t>(elem) - 1;
   1664   snd_mixer_selem_get_capture_dB_range_called++;
   1665   if (index >= snd_mixer_selem_get_capture_dB_range_values_length) {
   1666     *min = 0;
   1667     *max = 0;
   1668   } else {
   1669     *min = snd_mixer_selem_get_capture_dB_range_min_values[index];
   1670     *max = snd_mixer_selem_get_capture_dB_range_max_values[index];
   1671   }
   1672   return 0;
   1673 }
   1674 int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem,
   1675                                           long *min,
   1676                                           long *max) {
   1677   size_t index = reinterpret_cast<size_t>(elem) - 1;
   1678   snd_mixer_selem_get_playback_dB_range_called++;
   1679   if (index >= snd_mixer_selem_get_playback_dB_range_values_length) {
   1680     *min = 0;
   1681     *max = 0;
   1682   } else {
   1683     *min = snd_mixer_selem_get_playback_dB_range_min_values[index];
   1684     *max = snd_mixer_selem_get_playback_dB_range_max_values[index];
   1685   }
   1686   return 0;
   1687 }
   1688 
   1689 snd_mixer_elem_t *snd_mixer_find_selem(
   1690     snd_mixer_t *mixer, const snd_mixer_selem_id_t *id) {
   1691   std::string name(snd_mixer_selem_id_get_name(id));
   1692   unsigned int index = snd_mixer_selem_id_get_index(id);
   1693   snd_mixer_find_selem_called++;
   1694   if (index != 0)
   1695     return NULL;
   1696   if (snd_mixer_find_elem_map.find(name) == snd_mixer_find_elem_map.end()) {
   1697     return NULL;
   1698   }
   1699   return snd_mixer_find_elem_map[name];
   1700 }
   1701 
   1702 //  From cras_volume_curve.
   1703 static long get_dBFS_default(const struct cras_volume_curve *curve,
   1704 			     size_t volume)
   1705 {
   1706   return 100 * (volume - 100);
   1707 }
   1708 
   1709 struct cras_volume_curve *cras_volume_curve_create_default()
   1710 {
   1711   struct cras_volume_curve *curve;
   1712   curve = (struct cras_volume_curve *)calloc(1, sizeof(*curve));
   1713   if (curve)
   1714     curve->get_dBFS = get_dBFS_default;
   1715   return curve;
   1716 }
   1717 
   1718 void cras_volume_curve_destroy(struct cras_volume_curve *curve)
   1719 {
   1720   cras_volume_curve_destroy_called++;
   1721   free(curve);
   1722 }
   1723 
   1724 // From libiniparser.
   1725 struct cras_volume_curve *cras_card_config_get_volume_curve_for_control(
   1726 		const struct cras_card_config *card_config,
   1727 		const char *control_name)
   1728 {
   1729   struct cras_volume_curve *curve;
   1730   curve = (struct cras_volume_curve *)calloc(1, sizeof(*curve));
   1731   if (curve != NULL)
   1732     curve->get_dBFS = get_dBFS_default;
   1733   return curve;
   1734 }
   1735 
   1736 } /* extern "C" */
   1737 
   1738 }  //  namespace
   1739 
   1740 int main(int argc, char **argv) {
   1741   ::testing::InitGoogleTest(&argc, argv);
   1742   openlog(NULL, LOG_PERROR, LOG_USER);
   1743   return RUN_ALL_TESTS();
   1744 }
   1745