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