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 <deque>
      6 #include <linux/input.h>
      7 #include <map>
      8 #include <poll.h>
      9 #include <stdio.h>
     10 #include <sys/param.h>
     11 #include <gtest/gtest.h>
     12 #include <string>
     13 #include <syslog.h>
     14 #include <vector>
     15 
     16 extern "C" {
     17 #include "cras_alsa_jack.h"
     18 #include "cras_alsa_ucm_section.h"
     19 #include "cras_gpio_jack.h"
     20 #include "cras_tm.h"
     21 #include "cras_types.h"
     22 #include "cras_util.h"
     23 }
     24 
     25 namespace {
     26 
     27 #define BITS_PER_BYTE		(8)
     28 #define BITS_PER_LONG		(sizeof(long) * BITS_PER_BYTE)
     29 #define NBITS(x)		((((x) - 1) / BITS_PER_LONG) + 1)
     30 #define OFF(x)			((x) % BITS_PER_LONG)
     31 #define BIT(x)			(1UL << OFF(x))
     32 #define LONG(x)			((x) / BITS_PER_LONG)
     33 #define IS_BIT_SET(bit, array)	!!((array[LONG(bit)]) & (1UL << OFF(bit)))
     34 
     35 static int fake_jack_cb_plugged;
     36 static void *fake_jack_cb_data;
     37 static size_t fake_jack_cb_called;
     38 unsigned int snd_hctl_elem_get_device_return_val;
     39 unsigned int snd_hctl_elem_get_device_called;
     40 static size_t snd_hctl_first_elem_called;
     41 static snd_hctl_elem_t *snd_hctl_first_elem_return_val;
     42 static size_t snd_hctl_elem_next_called;
     43 std::deque<snd_hctl_elem_t *> snd_hctl_elem_next_ret_vals;
     44 std::deque<snd_hctl_elem_t *> snd_hctl_elem_next_ret_vals_poped;
     45 static size_t snd_hctl_elem_get_name_called;
     46 static size_t snd_hctl_elem_set_callback_called;
     47 static snd_hctl_elem_t *snd_hctl_elem_set_callback_obj;
     48 static snd_hctl_elem_callback_t snd_hctl_elem_set_callback_value;
     49 static size_t snd_hctl_find_elem_called;
     50 static std::vector<snd_hctl_elem_t *> snd_hctl_find_elem_return_vals;
     51 static std::map<std::string, size_t> snd_ctl_elem_id_set_name_map;
     52 static size_t cras_system_add_select_fd_called;
     53 static std::vector<int> cras_system_add_select_fd_values;
     54 static size_t cras_system_rm_select_fd_called;
     55 static std::vector<int> cras_system_rm_select_fd_values;
     56 static size_t snd_hctl_elem_set_callback_private_called;
     57 static void *snd_hctl_elem_set_callback_private_value;
     58 static size_t snd_hctl_elem_get_hctl_called;
     59 static snd_hctl_t *snd_hctl_elem_get_hctl_return_value;
     60 static size_t snd_ctl_elem_value_get_boolean_called;
     61 static int snd_ctl_elem_value_get_boolean_return_value;
     62 static void *fake_jack_cb_arg;
     63 static struct cras_alsa_mixer *fake_mixer;
     64 static size_t cras_alsa_mixer_get_output_matching_name_called;
     65 static size_t cras_alsa_mixer_get_input_matching_name_called;
     66 static size_t cras_alsa_mixer_get_control_for_section_called;
     67 static struct mixer_control *
     68     cras_alsa_mixer_get_output_matching_name_return_value;
     69 static struct mixer_control *
     70     cras_alsa_mixer_get_input_matching_name_return_value;
     71 static struct mixer_control *
     72     cras_alsa_mixer_get_control_for_section_return_value;
     73 static size_t gpio_switch_list_for_each_called;
     74 static std::vector<std::string> gpio_switch_list_for_each_dev_paths;
     75 static std::vector<std::string> gpio_switch_list_for_each_dev_names;
     76 static size_t gpio_switch_open_called;
     77 static size_t gpio_switch_eviocgsw_called;
     78 static size_t gpio_switch_eviocgbit_called;
     79 static unsigned ucm_get_dev_for_jack_called;
     80 static unsigned ucm_get_cap_control_called;
     81 static char *ucm_get_cap_control_value;
     82 static bool ucm_get_dev_for_jack_return;
     83 static int ucm_set_enabled_value;
     84 static unsigned long eviocbit_ret[NBITS(SW_CNT)];
     85 static int gpio_switch_eviocgbit_fd;
     86 static const char *edid_file_ret;
     87 static size_t ucm_get_dsp_name_called;
     88 static unsigned ucm_get_override_type_name_called;
     89 static char *ucm_get_device_name_for_dev_value;
     90 static snd_hctl_t *fake_hctl = (snd_hctl_t *)2;
     91 
     92 static void ResetStubData() {
     93   gpio_switch_list_for_each_called = 0;
     94   gpio_switch_list_for_each_dev_paths.clear();
     95   gpio_switch_list_for_each_dev_paths.push_back("/dev/input/event3");
     96   gpio_switch_list_for_each_dev_paths.push_back("/dev/input/event2");
     97   gpio_switch_list_for_each_dev_names.clear();
     98   gpio_switch_open_called = 0;
     99   gpio_switch_eviocgsw_called = 0;
    100   gpio_switch_eviocgbit_called = 0;
    101   snd_hctl_elem_get_device_return_val = 0;
    102   snd_hctl_elem_get_device_called = 0;
    103   snd_hctl_first_elem_called = 0;
    104   snd_hctl_first_elem_return_val = reinterpret_cast<snd_hctl_elem_t *>(0x87);
    105   snd_hctl_elem_next_called = 0;
    106   snd_hctl_elem_next_ret_vals.clear();
    107   snd_hctl_elem_next_ret_vals_poped.clear();
    108   snd_hctl_elem_get_name_called = 0;
    109   snd_hctl_elem_set_callback_called = 0;
    110   snd_hctl_elem_set_callback_obj = NULL;
    111   snd_hctl_elem_set_callback_value = NULL;
    112   snd_hctl_find_elem_called = 0;
    113   snd_hctl_find_elem_return_vals.clear();
    114   snd_ctl_elem_id_set_name_map.clear();
    115   cras_system_add_select_fd_called = 0;
    116   cras_system_add_select_fd_values.clear();
    117   cras_system_rm_select_fd_called = 0;
    118   cras_system_rm_select_fd_values.clear();
    119   snd_hctl_elem_set_callback_private_called = 0;
    120   snd_hctl_elem_get_hctl_called = 0;
    121   snd_ctl_elem_value_get_boolean_called = 0;
    122   fake_jack_cb_called = 0;
    123   fake_jack_cb_plugged = 0;
    124   fake_jack_cb_arg = reinterpret_cast<void *>(0x987);
    125   fake_mixer = reinterpret_cast<struct cras_alsa_mixer *>(0x789);
    126   cras_alsa_mixer_get_output_matching_name_called = 0;
    127   cras_alsa_mixer_get_input_matching_name_called = 0;
    128   cras_alsa_mixer_get_control_for_section_called = 0;
    129   cras_alsa_mixer_get_output_matching_name_return_value =
    130       reinterpret_cast<struct mixer_control *>(0x456);
    131   cras_alsa_mixer_get_input_matching_name_return_value = NULL;
    132   cras_alsa_mixer_get_control_for_section_return_value =
    133       reinterpret_cast<struct mixer_control *>(0x456);
    134   ucm_get_dev_for_jack_called = 0;
    135   ucm_get_cap_control_called = 0;
    136   ucm_get_cap_control_value = NULL;
    137   ucm_get_dev_for_jack_return = false;
    138   edid_file_ret = NULL;
    139   ucm_get_dsp_name_called = 0;
    140   ucm_get_override_type_name_called = 0;
    141   ucm_get_device_name_for_dev_value = NULL;
    142 
    143   memset(eviocbit_ret, 0, sizeof(eviocbit_ret));
    144 }
    145 
    146 static void fake_jack_cb(const struct cras_alsa_jack *jack,
    147                          int plugged,
    148                          void *data)
    149 {
    150   fake_jack_cb_called++;
    151   fake_jack_cb_plugged = plugged;
    152   fake_jack_cb_data = data;
    153 
    154   // Check that jack enable callback is called if there is a ucm device.
    155   ucm_set_enabled_value = !plugged;
    156   cras_alsa_jack_enable_ucm(jack, plugged);
    157   EXPECT_EQ(ucm_get_dev_for_jack_return ? plugged : !plugged,
    158             ucm_set_enabled_value);
    159 }
    160 
    161 TEST(AlsaJacks, CreateNullHctl) {
    162   struct cras_alsa_jack_list *jack_list;
    163   ResetStubData();
    164   jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1,
    165                                          fake_mixer,
    166                                          NULL, NULL,
    167                                          CRAS_STREAM_OUTPUT,
    168                                          fake_jack_cb,
    169                                          fake_jack_cb_arg);
    170   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    171   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    172   EXPECT_EQ(1, gpio_switch_list_for_each_called);
    173   EXPECT_EQ(0, gpio_switch_open_called);
    174   EXPECT_EQ(0, gpio_switch_eviocgsw_called);
    175   EXPECT_EQ(0, gpio_switch_eviocgbit_called);
    176 
    177   cras_alsa_jack_list_destroy(jack_list);
    178 }
    179 
    180 TEST(AlsaJacks, CreateNoElements) {
    181   struct cras_alsa_jack_list *jack_list;
    182 
    183   ResetStubData();
    184   snd_hctl_first_elem_return_val = NULL;
    185   jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1,
    186                                          fake_mixer,
    187                                          NULL, fake_hctl,
    188                                          CRAS_STREAM_OUTPUT,
    189                                          fake_jack_cb,
    190                                          fake_jack_cb_arg);
    191   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    192   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    193   EXPECT_EQ(1, gpio_switch_list_for_each_called);
    194   EXPECT_EQ(0, gpio_switch_open_called);
    195   EXPECT_EQ(0, gpio_switch_eviocgsw_called);
    196   EXPECT_EQ(0, gpio_switch_eviocgbit_called);
    197   EXPECT_EQ(1, snd_hctl_first_elem_called);
    198   EXPECT_EQ(0, snd_hctl_elem_next_called);
    199 
    200   cras_alsa_jack_list_destroy(jack_list);
    201 }
    202 
    203 static struct cras_alsa_jack_list *run_test_with_elem_list(
    204     CRAS_STREAM_DIRECTION direction,
    205     std::string *elems,
    206     unsigned int device_index,
    207     struct cras_use_case_mgr *ucm,
    208     size_t nelems,
    209     size_t nhdmi_jacks,
    210     size_t njacks) {
    211   struct cras_alsa_jack_list *jack_list;
    212 
    213   snd_hctl_first_elem_return_val =
    214       reinterpret_cast<snd_hctl_elem_t *>(&elems[0]);
    215   for (unsigned int i = 1; i < nelems; i++)
    216     snd_hctl_elem_next_ret_vals.push_front(
    217         reinterpret_cast<snd_hctl_elem_t *>(&elems[i]));
    218 
    219   jack_list = cras_alsa_jack_list_create(0,
    220                                          "card_name",
    221                                          device_index,
    222                                          1,
    223                                          fake_mixer,
    224                                          ucm, fake_hctl,
    225                                          direction,
    226                                          fake_jack_cb,
    227                                          fake_jack_cb_arg);
    228   if (jack_list == NULL)
    229     return jack_list;
    230   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    231   EXPECT_EQ(ucm ? njacks : 0, ucm_get_dev_for_jack_called);
    232   EXPECT_EQ(ucm ? njacks : 0, ucm_get_override_type_name_called);
    233   EXPECT_EQ(1 + nhdmi_jacks, snd_hctl_first_elem_called);
    234   EXPECT_EQ(njacks, snd_hctl_elem_set_callback_called);
    235 
    236   /* For some functions, the number of calls to them could
    237    * be larger then expected count if there is ELD control
    238    * in given elements. */
    239   EXPECT_GE(snd_hctl_elem_next_called, nelems + nhdmi_jacks);
    240   EXPECT_GE(snd_hctl_elem_get_name_called, nelems + njacks);
    241 
    242   if (direction == CRAS_STREAM_OUTPUT)
    243     EXPECT_EQ(njacks, cras_alsa_mixer_get_output_matching_name_called);
    244   if (direction == CRAS_STREAM_INPUT && ucm_get_dev_for_jack_return)
    245     EXPECT_EQ(njacks, ucm_get_cap_control_called);
    246 
    247   return jack_list;
    248 }
    249 
    250 static struct cras_alsa_jack_list *run_test_with_section(
    251     CRAS_STREAM_DIRECTION direction,
    252     std::string *elems,
    253     size_t nelems,
    254     unsigned int device_index,
    255     struct cras_use_case_mgr *ucm,
    256     struct ucm_section *ucm_section,
    257     int add_jack_rc,
    258     size_t njacks) {
    259   struct cras_alsa_jack_list *jack_list;
    260   struct cras_alsa_jack *jack;
    261 
    262   for (size_t i = 0; i < nelems; i++) {
    263     snd_ctl_elem_id_set_name_map[elems[i]] = i;
    264     snd_hctl_find_elem_return_vals.push_back(
    265         reinterpret_cast<snd_hctl_elem_t*>(&elems[i]));
    266   }
    267 
    268   jack_list = cras_alsa_jack_list_create(0,
    269                                          "card_name",
    270                                          device_index,
    271                                          1,
    272                                          fake_mixer,
    273                                          ucm, fake_hctl,
    274                                          direction,
    275                                          fake_jack_cb,
    276                                          fake_jack_cb_arg);
    277   if (jack_list == NULL)
    278     return jack_list;
    279   EXPECT_EQ(add_jack_rc,
    280       cras_alsa_jack_list_add_jack_for_section(jack_list, ucm_section, &jack));
    281   if (add_jack_rc == 0) {
    282     EXPECT_EQ(njacks, ucm_get_dsp_name_called);
    283     EXPECT_NE(jack, reinterpret_cast<struct cras_alsa_jack *>(NULL));
    284   } else {
    285     EXPECT_EQ(jack, reinterpret_cast<struct cras_alsa_jack *>(NULL));
    286   }
    287   if (add_jack_rc != 0 || njacks != ucm_get_dsp_name_called) {
    288       cras_alsa_jack_list_destroy(jack_list);
    289       return NULL;
    290   }
    291   EXPECT_EQ(njacks, snd_hctl_elem_set_callback_called);
    292   EXPECT_EQ(njacks, cras_alsa_mixer_get_control_for_section_called);
    293 
    294   return jack_list;
    295 }
    296 
    297 TEST(AlsaJacks, ReportNull) {
    298   cras_alsa_jack_list_report(NULL);
    299 }
    300 
    301 TEST(AlsaJacks, CreateNoJacks) {
    302   static std::string elem_names[] = {
    303     "Mic Jack",
    304     "foo",
    305     "bar",
    306   };
    307   struct cras_alsa_jack_list *jack_list;
    308 
    309   ResetStubData();
    310   jack_list = run_test_with_elem_list(CRAS_STREAM_OUTPUT,
    311                                       elem_names,
    312                                       0,
    313                                       NULL,
    314                                       ARRAY_SIZE(elem_names),
    315                                       0,
    316                                       0);
    317   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    318 
    319   cras_alsa_jack_list_destroy(jack_list);
    320   EXPECT_EQ(0, cras_system_rm_select_fd_called);
    321 }
    322 
    323 TEST(AlsaJacks, CreateGPIOHp) {
    324   struct cras_alsa_jack_list *jack_list;
    325 
    326   ResetStubData();
    327   gpio_switch_list_for_each_dev_names.push_back("some-other-device");
    328   gpio_switch_list_for_each_dev_names.push_back("c1 Headphone Jack");
    329   eviocbit_ret[LONG(SW_HEADPHONE_INSERT)] |= 1 << OFF(SW_HEADPHONE_INSERT);
    330   gpio_switch_eviocgbit_fd = 2;
    331   snd_hctl_first_elem_return_val = NULL;
    332   jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1,
    333                                          fake_mixer,
    334                                          NULL, fake_hctl,
    335                                          CRAS_STREAM_OUTPUT,
    336                                          fake_jack_cb,
    337                                          fake_jack_cb_arg);
    338   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    339   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    340   cras_alsa_jack_list_destroy(jack_list);
    341   EXPECT_EQ(1, gpio_switch_list_for_each_called);
    342   EXPECT_GT(gpio_switch_open_called, 1);
    343   EXPECT_EQ(1, gpio_switch_eviocgsw_called);
    344   EXPECT_GT(gpio_switch_eviocgbit_called, 1);
    345   EXPECT_EQ(1, cras_system_add_select_fd_called);
    346   EXPECT_EQ(1, cras_system_rm_select_fd_called);
    347 }
    348 
    349 TEST(AlsaJacks, CreateGPIOMic) {
    350   struct cras_alsa_jack_list *jack_list;
    351   ResetStubData();
    352   ucm_get_dev_for_jack_return = true;
    353   gpio_switch_list_for_each_dev_names.push_back("c1 Mic Jack");
    354   gpio_switch_list_for_each_dev_names.push_back("c1 Headphone Jack");
    355   eviocbit_ret[LONG(SW_MICROPHONE_INSERT)] |= 1 << OFF(SW_MICROPHONE_INSERT);
    356   gpio_switch_eviocgbit_fd = 3;
    357   snd_hctl_first_elem_return_val = NULL;
    358   ucm_get_cap_control_value = reinterpret_cast<char *>(0x1);
    359 
    360   // Freed in destroy.
    361   cras_alsa_mixer_get_input_matching_name_return_value =
    362       reinterpret_cast<struct mixer_control *>(malloc(1));
    363 
    364   jack_list = cras_alsa_jack_list_create(
    365       0,
    366       "c1",
    367       0,
    368       1,
    369       fake_mixer,
    370       reinterpret_cast<struct cras_use_case_mgr *>(0x55),
    371       fake_hctl,
    372       CRAS_STREAM_INPUT,
    373       fake_jack_cb,
    374       fake_jack_cb_arg);
    375   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    376   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    377   EXPECT_EQ(ucm_get_cap_control_called, 1);
    378   EXPECT_EQ(cras_alsa_mixer_get_input_matching_name_called, 1);
    379   cras_alsa_jack_list_destroy(jack_list);
    380 }
    381 
    382 TEST(AlsaJacks, CreateGPIOHdmi) {
    383   struct cras_alsa_jack_list *jack_list;
    384 
    385   ResetStubData();
    386   gpio_switch_list_for_each_dev_names.push_back("c1 HDMI Jack");
    387   gpio_switch_list_for_each_dev_names.push_back("c1 Mic Jack");
    388   eviocbit_ret[LONG(SW_LINEOUT_INSERT)] |= 1 << OFF(SW_LINEOUT_INSERT);
    389   gpio_switch_eviocgbit_fd = 3;
    390   snd_hctl_first_elem_return_val = NULL;
    391   jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1,
    392                                          fake_mixer,
    393                                          NULL, fake_hctl,
    394                                          CRAS_STREAM_OUTPUT,
    395                                          fake_jack_cb,
    396                                          fake_jack_cb_arg);
    397   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    398   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    399   EXPECT_EQ(1, gpio_switch_eviocgsw_called);
    400 
    401   fake_jack_cb_called = 0;
    402   cras_alsa_jack_list_report(jack_list);
    403   EXPECT_EQ(1, fake_jack_cb_plugged);
    404   EXPECT_EQ(1, fake_jack_cb_called);
    405 
    406   cras_alsa_jack_list_destroy(jack_list);
    407   EXPECT_EQ(1, gpio_switch_list_for_each_called);
    408   EXPECT_GT(gpio_switch_open_called, 1);
    409   EXPECT_GT(gpio_switch_eviocgbit_called, 1);
    410   EXPECT_EQ(1, cras_system_add_select_fd_called);
    411   EXPECT_EQ(1, cras_system_rm_select_fd_called);
    412 }
    413 
    414 void run_gpio_jack_test(
    415     int device_index,
    416     int is_first_device,
    417     enum CRAS_STREAM_DIRECTION direction,
    418     int should_create_jack,
    419     const char* jack_name)
    420 {
    421   struct cras_alsa_jack_list *jack_list;
    422   struct cras_use_case_mgr *ucm =
    423       reinterpret_cast<struct cras_use_case_mgr *>(0x55);
    424 
    425   gpio_switch_list_for_each_dev_names.push_back("some-other-device one");
    426   gpio_switch_eviocgbit_fd = 2;
    427   if (direction == CRAS_STREAM_OUTPUT) {
    428     eviocbit_ret[LONG(SW_HEADPHONE_INSERT)] |= 1 << OFF(SW_HEADPHONE_INSERT);
    429   } else {
    430     eviocbit_ret[LONG(SW_MICROPHONE_INSERT)] |= 1 << OFF(SW_MICROPHONE_INSERT);
    431   }
    432   gpio_switch_list_for_each_dev_names.push_back(jack_name);
    433   snd_hctl_first_elem_return_val = NULL;
    434 
    435   jack_list = cras_alsa_jack_list_create(0, "c1", device_index,
    436                                          is_first_device,
    437                                          fake_mixer,
    438                                          ucm, fake_hctl,
    439                                          direction,
    440                                          fake_jack_cb,
    441                                          fake_jack_cb_arg);
    442   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    443   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    444 
    445   cras_alsa_jack_list_report(jack_list);
    446   EXPECT_EQ(should_create_jack, fake_jack_cb_plugged);
    447   EXPECT_EQ(should_create_jack, fake_jack_cb_called);
    448 
    449   cras_alsa_jack_list_destroy(jack_list);
    450 }
    451 
    452 TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMMatched) {
    453   int device_index = 1;
    454   int is_first_device = 0;
    455   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT;
    456   int should_create_jack = 1;
    457 
    458   ResetStubData();
    459 
    460   /* PlaybackPCM matched, so create jack even if this is not the first device.*/
    461   ucm_get_dev_for_jack_return = true;
    462   ucm_get_device_name_for_dev_value = strdup("hw:c1,1");
    463 
    464   run_gpio_jack_test(
    465       device_index, is_first_device, direction, should_create_jack,
    466       "c1 Headset Jack");
    467 }
    468 
    469 TEST(AlsaJacks, CreateGPIOHpUCMCapturePCMMatched) {
    470   int device_index = 1;
    471   int is_first_device = 0;
    472   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_INPUT;
    473   int should_create_jack = 1;
    474 
    475   ResetStubData();
    476 
    477   /* CapturePCM matched, so create jack even if this is not the first device.*/
    478   ucm_get_dev_for_jack_return = true;
    479   ucm_get_device_name_for_dev_value = strdup("hw:c1,1");
    480 
    481   run_gpio_jack_test(
    482       device_index, is_first_device, direction, should_create_jack,
    483       "c1 Mic Jack");
    484 }
    485 
    486 TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotMatched) {
    487   int device_index = 0;
    488   int is_first_device = 1;
    489   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT;
    490   int should_create_jack = 0;
    491 
    492   ResetStubData();
    493 
    494   /* PlaybackPCM not matched, do not create jack. */
    495   ucm_get_dev_for_jack_return = true;
    496   ucm_get_device_name_for_dev_value = strdup("hw:c1,2");
    497 
    498   run_gpio_jack_test(
    499       device_index, is_first_device, direction, should_create_jack,
    500       "c1 Headset Jack");
    501 }
    502 
    503 TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotSpecifiedFirstDevice) {
    504   int device_index = 1;
    505   int is_first_device = 1;
    506   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT;
    507   int should_create_jack = 1;
    508 
    509   ResetStubData();
    510 
    511   /* PlaybackPCM not specified, create jack for the first device. */
    512   ucm_get_dev_for_jack_return = true;
    513   ucm_get_device_name_for_dev_value = NULL;
    514 
    515   run_gpio_jack_test(
    516       device_index, is_first_device, direction, should_create_jack,
    517       "c1 Headset Jack");
    518 }
    519 
    520 TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotSpecifiedSecondDevice) {
    521   int device_index = 1;
    522   int is_first_device = 0;
    523   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT;
    524   int should_create_jack = 0;
    525 
    526   ResetStubData();
    527 
    528   /* PlaybackPCM not specified, do not create jack for the second device. */
    529   ucm_get_dev_for_jack_return = true;
    530   ucm_get_device_name_for_dev_value = NULL;
    531 
    532   run_gpio_jack_test(
    533       device_index, is_first_device, direction, should_create_jack,
    534       "c1 Headset Jack");
    535 }
    536 
    537 TEST(AlsaJacks, CreateGPIOHpNoUCMFirstDevice) {
    538   int device_index = 1;
    539   int is_first_device = 1;
    540   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT;
    541   int should_create_jack = 1;
    542 
    543   ResetStubData();
    544 
    545   /* No UCM for this jack, create jack for the first device. */
    546   ucm_get_dev_for_jack_return = false;
    547   ucm_get_device_name_for_dev_value = NULL;
    548 
    549   run_gpio_jack_test(
    550       device_index, is_first_device, direction, should_create_jack,
    551       "c1 Headset Jack");
    552 }
    553 
    554 TEST(AlsaJacks, CreateGPIOHpNoUCMSecondDevice) {
    555   int device_index = 1;
    556   int is_first_device = 0;
    557   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT;
    558   int should_create_jack = 0;
    559 
    560   ResetStubData();
    561 
    562   /* No UCM for this jack, dot not create jack for the second device. */
    563   ucm_get_dev_for_jack_return = false;
    564   ucm_get_device_name_for_dev_value = NULL;
    565 
    566   run_gpio_jack_test(
    567       device_index, is_first_device, direction, should_create_jack,
    568       "c1 Headset Jack");
    569 }
    570 
    571 TEST(AlsaJacks, CreateGPIOMicNoUCMFirstDeviceMicJack) {
    572   int device_index = 1;
    573   int is_first_device = 1;
    574   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_INPUT;
    575   int should_create_jack = 1;
    576 
    577   ResetStubData();
    578 
    579   // No UCM for this jack, create jack for the first device.
    580   ucm_get_dev_for_jack_return = false;
    581   ucm_get_device_name_for_dev_value = NULL;
    582 
    583   // Mic Jack is a valid name for microphone jack.
    584   run_gpio_jack_test(
    585       device_index, is_first_device, direction, should_create_jack,
    586       "c1 Mic Jack");
    587 }
    588 
    589 TEST(AlsaJacks, CreateGPIOMicNoUCMFirstDeviceHeadsetJack) {
    590   int device_index = 1;
    591   int is_first_device = 1;
    592   enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_INPUT;
    593   int should_create_jack = 1;
    594 
    595   ResetStubData();
    596 
    597   // No UCM for this jack, create jack for the first device.
    598   ucm_get_dev_for_jack_return = false;
    599   ucm_get_device_name_for_dev_value = NULL;
    600 
    601   // Headset Jack is a valid name for microphone jack.
    602   run_gpio_jack_test(
    603       device_index, is_first_device, direction, should_create_jack,
    604       "c1 Headset Jack");
    605 }
    606 
    607 TEST(AlsaJacks, GPIOHdmiWithEdid) {
    608   cras_alsa_jack_list* jack_list;
    609 
    610   ResetStubData();
    611   ucm_get_dev_for_jack_return = 1;
    612   edid_file_ret = static_cast<char*>(calloc(1, 1));  // Freed in destroy.
    613   gpio_switch_list_for_each_dev_names.push_back("c1 HDMI Jack");
    614   eviocbit_ret[LONG(SW_LINEOUT_INSERT)] |= 1 << OFF(SW_LINEOUT_INSERT);
    615   gpio_switch_eviocgbit_fd = 3;
    616   snd_hctl_first_elem_return_val = NULL;
    617   jack_list = cras_alsa_jack_list_create(
    618       0,
    619       "c1",
    620       0,
    621       1,
    622       fake_mixer,
    623       reinterpret_cast<struct cras_use_case_mgr *>(0x55),
    624       fake_hctl,
    625       CRAS_STREAM_OUTPUT,
    626       fake_jack_cb,
    627       fake_jack_cb_arg);
    628   ASSERT_NE(static_cast<cras_alsa_jack_list*>(NULL), jack_list);
    629   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    630   EXPECT_EQ(1, gpio_switch_eviocgsw_called);
    631 
    632   // EDID shouldn't open, callback should be skipped until re-try.
    633   fake_jack_cb_called = 0;
    634   cras_alsa_jack_list_report(jack_list);
    635   EXPECT_EQ(0, fake_jack_cb_called);
    636 
    637   cras_alsa_jack_list_destroy(jack_list);
    638   EXPECT_EQ(1, gpio_switch_list_for_each_called);
    639   EXPECT_GT(gpio_switch_open_called, 1);
    640   EXPECT_GT(gpio_switch_eviocgbit_called, 1);
    641   EXPECT_EQ(1, cras_system_add_select_fd_called);
    642   EXPECT_EQ(1, cras_system_rm_select_fd_called);
    643 }
    644 
    645 TEST(AlsaJacks, CreateGPIOHpNoNameMatch) {
    646   struct cras_alsa_jack_list *jack_list;
    647 
    648   ResetStubData();
    649   gpio_switch_list_for_each_dev_names.push_back("some-other-device one");
    650   gpio_switch_list_for_each_dev_names.push_back("some-other-device two");
    651   snd_hctl_first_elem_return_val = NULL;
    652   jack_list = cras_alsa_jack_list_create(0, "c2", 0, 1,
    653                                          fake_mixer,
    654                                          NULL, fake_hctl,
    655                                          CRAS_STREAM_OUTPUT,
    656                                          fake_jack_cb,
    657                                          fake_jack_cb_arg);
    658   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    659   EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
    660 
    661   cras_alsa_jack_list_destroy(jack_list);
    662   EXPECT_EQ(1, gpio_switch_list_for_each_called);
    663   EXPECT_EQ(0, gpio_switch_open_called);
    664   EXPECT_EQ(0, cras_system_add_select_fd_called);
    665   EXPECT_EQ(0, cras_system_rm_select_fd_called);
    666 }
    667 
    668 TEST(AlsaJacks, CreateOneHpJack) {
    669   std::string elem_names[] = {
    670     "asdf",
    671     "Headphone Jack, klasdjf",
    672     "Mic Jack",
    673   };
    674   struct cras_alsa_jack_list *jack_list;
    675 
    676   ResetStubData();
    677   jack_list = run_test_with_elem_list(CRAS_STREAM_OUTPUT,
    678                                       elem_names,
    679                                       0,
    680                                       NULL,
    681                                       ARRAY_SIZE(elem_names),
    682                                       0,
    683                                       1);
    684   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    685   ASSERT_NE(reinterpret_cast<snd_hctl_elem_callback_t>(NULL),
    686             snd_hctl_elem_set_callback_value);
    687   EXPECT_EQ(1, snd_hctl_elem_set_callback_called);
    688 
    689   snd_hctl_elem_get_hctl_return_value = reinterpret_cast<snd_hctl_t *>(0x33);
    690   snd_hctl_elem_get_name_called = 0;
    691   snd_ctl_elem_value_get_boolean_return_value = 1;
    692   snd_hctl_elem_set_callback_value(
    693       reinterpret_cast<snd_hctl_elem_t *>(&elem_names[1]), 0);
    694   EXPECT_EQ(1, snd_hctl_elem_get_name_called);
    695   EXPECT_EQ(1, fake_jack_cb_plugged);
    696   EXPECT_EQ(1, fake_jack_cb_called);
    697   EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data);
    698   EXPECT_EQ(reinterpret_cast<snd_hctl_elem_t *>(&elem_names[1]),
    699             snd_hctl_elem_set_callback_obj);
    700 
    701   fake_jack_cb_called = 0;
    702   cras_alsa_jack_list_report(jack_list);
    703   EXPECT_EQ(1, fake_jack_cb_plugged);
    704   EXPECT_EQ(1, fake_jack_cb_called);
    705 
    706   cras_alsa_jack_list_destroy(jack_list);
    707   EXPECT_EQ(2, snd_hctl_elem_set_callback_called);
    708   EXPECT_EQ(reinterpret_cast<snd_hctl_elem_callback_t>(NULL),
    709             snd_hctl_elem_set_callback_value);
    710 }
    711 
    712 TEST(AlsaJacks, CreateOneMicJack) {
    713   static std::string elem_names[] = {
    714     "asdf",
    715     "Headphone Jack",
    716     "HDMI/DP,pcm=5 Jack",
    717     "HDMI/DP,pcm=6 Jack",
    718     "Mic Jack",
    719   };
    720   struct cras_alsa_jack_list *jack_list;
    721 
    722   ResetStubData();
    723   jack_list = run_test_with_elem_list(CRAS_STREAM_INPUT,
    724                                       elem_names,
    725                                       0,
    726                                       NULL,
    727                                       ARRAY_SIZE(elem_names),
    728                                       0,
    729                                       1);
    730   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    731   ASSERT_NE(reinterpret_cast<snd_hctl_elem_callback_t>(NULL),
    732             snd_hctl_elem_set_callback_value);
    733   EXPECT_EQ(1, snd_hctl_elem_set_callback_called);
    734 
    735   cras_alsa_jack_list_destroy(jack_list);
    736   EXPECT_EQ(0, cras_system_rm_select_fd_called);
    737   EXPECT_EQ(2, snd_hctl_elem_set_callback_called);
    738   EXPECT_EQ(reinterpret_cast<snd_hctl_elem_callback_t>(NULL),
    739             snd_hctl_elem_set_callback_value);
    740 }
    741 
    742 TEST(AlsaJacks, CreateHDMIJacksWithELD) {
    743   std::string elem_names[] = {
    744     "asdf",
    745     "HDMI/DP,pcm=3 Jack",
    746     "ELD",
    747     "HDMI/DP,pcm=4 Jack"
    748   };
    749   struct cras_alsa_jack_list *jack_list;
    750 
    751   ResetStubData();
    752   snd_hctl_elem_get_device_return_val = 3;
    753 
    754   jack_list = run_test_with_elem_list(
    755       CRAS_STREAM_OUTPUT,
    756       elem_names,
    757       3,
    758       NULL,
    759       ARRAY_SIZE(elem_names),
    760       1,
    761       1);
    762   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    763 
    764   /* Assert get device is called for the ELD control */
    765   EXPECT_EQ(1, snd_hctl_elem_get_device_called);
    766   cras_alsa_jack_list_destroy(jack_list);
    767 }
    768 
    769 TEST(AlsaJacks, CreateOneHpTwoHDMIJacks) {
    770   std::string elem_names[] = {
    771     "asdf",
    772     "Headphone Jack, klasdjf",
    773     "HDMI/DP,pcm=5 Jack",
    774     "HDMI/DP,pcm=6 Jack",
    775     "Mic Jack",
    776   };
    777   struct cras_alsa_jack_list *jack_list;
    778 
    779   ResetStubData();
    780   ucm_get_dev_for_jack_return = true;
    781   jack_list = run_test_with_elem_list(
    782       CRAS_STREAM_OUTPUT,
    783       elem_names,
    784       5,
    785       reinterpret_cast<struct cras_use_case_mgr *>(0x55),
    786       ARRAY_SIZE(elem_names),
    787       1,
    788       1);
    789   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    790 
    791   snd_hctl_elem_get_hctl_return_value = reinterpret_cast<snd_hctl_t *>(0x33);
    792   snd_hctl_elem_get_name_called = 0;
    793   snd_ctl_elem_value_get_boolean_return_value = 1;
    794   snd_hctl_elem_set_callback_value(
    795       reinterpret_cast<snd_hctl_elem_t *>(&elem_names[2]), 0);
    796   EXPECT_EQ(1, snd_hctl_elem_get_name_called);
    797   EXPECT_EQ(1, fake_jack_cb_plugged);
    798   EXPECT_EQ(1, fake_jack_cb_called);
    799   EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data);
    800   EXPECT_EQ(reinterpret_cast<snd_hctl_elem_t *>(&elem_names[2]),
    801             snd_hctl_elem_set_callback_obj);
    802 
    803   fake_jack_cb_called = 0;
    804   cras_alsa_jack_list_report(jack_list);
    805   EXPECT_EQ(1, fake_jack_cb_plugged);
    806   EXPECT_EQ(1, fake_jack_cb_called);
    807 
    808   cras_alsa_jack_list_destroy(jack_list);
    809 }
    810 
    811 TEST(AlsaJacks, CreateHCTLHeadphoneJackFromUCM) {
    812   std::string elem_names[] = {
    813     "HP/DP,pcm=5 Jack",
    814     "Headphone Jack",
    815   };
    816   struct cras_alsa_jack_list *jack_list;
    817   struct ucm_section *section;
    818 
    819   section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
    820                                "Headphone Jack", "hctl");
    821 
    822   ResetStubData();
    823   ucm_get_dev_for_jack_return = true;
    824 
    825   jack_list = run_test_with_section(
    826       CRAS_STREAM_OUTPUT,
    827       elem_names,
    828       ARRAY_SIZE(elem_names),
    829       5,
    830       reinterpret_cast<struct cras_use_case_mgr *>(0x55),
    831       section,
    832       0,
    833       1);
    834   ASSERT_NE(reinterpret_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    835 
    836   snd_hctl_elem_get_hctl_return_value = reinterpret_cast<snd_hctl_t *>(0x33);
    837   snd_ctl_elem_value_get_boolean_return_value = 1;
    838   snd_hctl_elem_set_callback_value(
    839       reinterpret_cast<snd_hctl_elem_t *>(&elem_names[1]), 0);
    840   EXPECT_EQ(1, snd_hctl_elem_get_name_called);
    841   EXPECT_EQ(1, fake_jack_cb_plugged);
    842   EXPECT_EQ(1, fake_jack_cb_called);
    843   EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data);
    844   EXPECT_EQ(reinterpret_cast<snd_hctl_elem_t *>(&elem_names[1]),
    845             snd_hctl_elem_set_callback_obj);
    846 
    847   fake_jack_cb_called = 0;
    848   cras_alsa_jack_list_report(jack_list);
    849   EXPECT_EQ(1, fake_jack_cb_plugged);
    850   EXPECT_EQ(1, fake_jack_cb_called);
    851 
    852   ucm_section_free_list(section);
    853   cras_alsa_jack_list_destroy(jack_list);
    854 }
    855 
    856 TEST(AlsaJacks, CreateGPIOHeadphoneJackFromUCM) {
    857   struct cras_alsa_jack_list *jack_list;
    858   struct cras_alsa_jack *jack;
    859   struct ucm_section *section;
    860 
    861   section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
    862                                "c1 Headphone Jack", "gpio");
    863 
    864   ResetStubData();
    865   gpio_switch_list_for_each_dev_names.push_back("some-other-device");
    866   gpio_switch_list_for_each_dev_names.push_back("c1 Headphone Jack");
    867   eviocbit_ret[LONG(SW_HEADPHONE_INSERT)] |= 1 << OFF(SW_HEADPHONE_INSERT);
    868   gpio_switch_eviocgbit_fd = 2;
    869   snd_hctl_first_elem_return_val = NULL;
    870   jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1,
    871                                          fake_mixer,
    872                                          NULL, fake_hctl,
    873                                          CRAS_STREAM_OUTPUT,
    874                                          fake_jack_cb,
    875                                          fake_jack_cb_arg);
    876   ASSERT_NE(static_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    877   EXPECT_EQ(0, cras_alsa_jack_list_add_jack_for_section(
    878                    jack_list, section, &jack));
    879   EXPECT_EQ(1, gpio_switch_list_for_each_called);
    880   EXPECT_GT(gpio_switch_open_called, 1);
    881   EXPECT_EQ(1, gpio_switch_eviocgsw_called);
    882   EXPECT_GT(gpio_switch_eviocgbit_called, 1);
    883   EXPECT_EQ(1, cras_system_add_select_fd_called);
    884   EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called);
    885 
    886   fake_jack_cb_called = 0;
    887   ucm_get_dev_for_jack_return = true;
    888   cras_alsa_jack_list_report(jack_list);
    889   EXPECT_EQ(1, fake_jack_cb_plugged);
    890   EXPECT_EQ(1, fake_jack_cb_called);
    891   EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data);
    892 
    893   ucm_section_free_list(section);
    894   cras_alsa_jack_list_destroy(jack_list);
    895   EXPECT_EQ(1, cras_system_rm_select_fd_called);
    896 }
    897 
    898 TEST(AlsaJacks, BadJackTypeFromUCM) {
    899   std::string elem_names[] = {
    900     "HP/DP,pcm=5 Jack",
    901     "Headphone Jack",
    902   };
    903   struct cras_alsa_jack_list *jack_list;
    904   struct ucm_section *section;
    905 
    906   section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
    907                                "Headphone Jack", "badtype");
    908 
    909   ResetStubData();
    910   ucm_get_dev_for_jack_return = true;
    911 
    912   jack_list = run_test_with_section(
    913       CRAS_STREAM_OUTPUT,
    914       elem_names,
    915       ARRAY_SIZE(elem_names),
    916       5,
    917       reinterpret_cast<struct cras_use_case_mgr *>(0x55),
    918       section,
    919       -22,
    920       1);
    921   EXPECT_EQ(reinterpret_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    922 
    923   ucm_section_free_list(section);
    924 }
    925 
    926 TEST(AlsaJacks, NoJackTypeFromUCM) {
    927   std::string elem_names[] = {
    928     "HP/DP,pcm=5 Jack",
    929     "Headphone Jack",
    930   };
    931   struct cras_alsa_jack_list *jack_list;
    932   struct ucm_section *section;
    933 
    934   section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
    935                                "Headphone Jack", NULL);
    936 
    937   ResetStubData();
    938   ucm_get_dev_for_jack_return = true;
    939 
    940   jack_list = run_test_with_section(
    941       CRAS_STREAM_OUTPUT,
    942       elem_names,
    943       ARRAY_SIZE(elem_names),
    944       5,
    945       reinterpret_cast<struct cras_use_case_mgr *>(0x55),
    946       section,
    947       -22,
    948       1);
    949   EXPECT_EQ(reinterpret_cast<struct cras_alsa_jack_list *>(NULL), jack_list);
    950 
    951   ucm_section_free_list(section);
    952 }
    953 
    954 /* Stubs */
    955 
    956 extern "C" {
    957 
    958 // From cras_system_state
    959 int cras_system_add_select_fd(int fd,
    960 			      void (*callback)(void *data),
    961 			      void *callback_data)
    962 {
    963   cras_system_add_select_fd_called++;
    964   cras_system_add_select_fd_values.push_back(fd);
    965   return 0;
    966 }
    967 void cras_system_rm_select_fd(int fd)
    968 {
    969   cras_system_rm_select_fd_called++;
    970   cras_system_rm_select_fd_values.push_back(fd);
    971 }
    972 
    973 // From alsa-lib hcontrol.c
    974 unsigned int snd_hctl_elem_get_device(const snd_hctl_elem_t *obj) {
    975   snd_hctl_elem_get_device_called = 1;
    976   return snd_hctl_elem_get_device_return_val;
    977 }
    978 snd_hctl_elem_t *snd_hctl_first_elem(snd_hctl_t *hctl) {
    979   snd_hctl_first_elem_called++;
    980 
    981   /* When first elem is called, restored the poped ret values */
    982   while (!snd_hctl_elem_next_ret_vals_poped.empty()) {
    983     snd_hctl_elem_t *tmp = snd_hctl_elem_next_ret_vals_poped.back();
    984     snd_hctl_elem_next_ret_vals_poped.pop_back();
    985     snd_hctl_elem_next_ret_vals.push_back(tmp);
    986   }
    987   return snd_hctl_first_elem_return_val;
    988 }
    989 snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem) {
    990   snd_hctl_elem_next_called++;
    991   if (snd_hctl_elem_next_ret_vals.empty())
    992     return NULL;
    993   snd_hctl_elem_t *ret_elem = snd_hctl_elem_next_ret_vals.back();
    994   snd_hctl_elem_next_ret_vals.pop_back();
    995   snd_hctl_elem_next_ret_vals_poped.push_back(ret_elem);
    996   return ret_elem;
    997 }
    998 const char *snd_hctl_elem_get_name(const snd_hctl_elem_t *obj) {
    999   snd_hctl_elem_get_name_called++;
   1000   const std::string *name = reinterpret_cast<const std::string *>(obj);
   1001   return name->c_str();
   1002 }
   1003 snd_ctl_elem_iface_t snd_hctl_elem_get_interface(const snd_hctl_elem_t *obj) {
   1004   return SND_CTL_ELEM_IFACE_CARD;
   1005 }
   1006 void snd_hctl_elem_set_callback(snd_hctl_elem_t *obj,
   1007                                 snd_hctl_elem_callback_t val) {
   1008   snd_hctl_elem_set_callback_called++;
   1009   snd_hctl_elem_set_callback_obj = obj;
   1010   snd_hctl_elem_set_callback_value = val;
   1011 }
   1012 void snd_hctl_elem_set_callback_private(snd_hctl_elem_t *obj, void * val) {
   1013   snd_hctl_elem_set_callback_private_called++;
   1014   snd_hctl_elem_set_callback_private_value = val;
   1015 }
   1016 void *snd_hctl_elem_get_callback_private(const snd_hctl_elem_t *obj) {
   1017   return snd_hctl_elem_set_callback_private_value;
   1018 }
   1019 snd_hctl_t *snd_hctl_elem_get_hctl(snd_hctl_elem_t *elem) {
   1020   snd_hctl_elem_get_hctl_called++;
   1021   return snd_hctl_elem_get_hctl_return_value;
   1022 }
   1023 int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value) {
   1024   return 0;
   1025 }
   1026 snd_hctl_elem_t *snd_hctl_find_elem(snd_hctl_t *hctl,
   1027                                     const snd_ctl_elem_id_t *id) {
   1028   const size_t* index = reinterpret_cast<const size_t*>(id);
   1029   snd_hctl_find_elem_called++;
   1030   if (*index < snd_hctl_find_elem_return_vals.size())
   1031     return snd_hctl_find_elem_return_vals[*index];
   1032   return NULL;
   1033 }
   1034 void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj,
   1035                                    snd_ctl_elem_iface_t val) {
   1036 }
   1037 void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val) {
   1038 }
   1039 void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val) {
   1040   size_t *obj_id = reinterpret_cast<size_t*>(obj);
   1041   std::map<std::string, size_t>::iterator id_name_it =
   1042       snd_ctl_elem_id_set_name_map.find(val);
   1043   if (id_name_it != snd_ctl_elem_id_set_name_map.end())
   1044     *obj_id = id_name_it->second;
   1045   else
   1046     *obj_id = INT_MAX;
   1047 }
   1048 
   1049 // From alsa-lib control.c
   1050 int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj,
   1051                                    unsigned int idx) {
   1052   snd_ctl_elem_value_get_boolean_called++;
   1053   return snd_ctl_elem_value_get_boolean_return_value;
   1054 }
   1055 
   1056 // From cras_alsa_mixer
   1057 struct mixer_control *cras_alsa_mixer_get_output_matching_name(
   1058     const struct cras_alsa_mixer *cras_mixer,
   1059     size_t device_index,
   1060     const char * const name)
   1061 {
   1062   cras_alsa_mixer_get_output_matching_name_called++;
   1063   return cras_alsa_mixer_get_output_matching_name_return_value;
   1064 }
   1065 
   1066 struct mixer_control *cras_alsa_mixer_get_input_matching_name(
   1067     struct cras_alsa_mixer *cras_mixer,
   1068     const char *control_name)
   1069 {
   1070   cras_alsa_mixer_get_input_matching_name_called++;
   1071   return cras_alsa_mixer_get_input_matching_name_return_value;
   1072 }
   1073 
   1074 struct mixer_control *cras_alsa_mixer_get_control_for_section(
   1075     struct cras_alsa_mixer *cras_mixer,
   1076     struct ucm_section *section)
   1077 {
   1078   cras_alsa_mixer_get_control_for_section_called++;
   1079   return cras_alsa_mixer_get_control_for_section_return_value;
   1080 }
   1081 
   1082 int gpio_switch_eviocgbit(int fd, void *buf, size_t n_bytes)
   1083 {
   1084   unsigned char *p = (unsigned char *)buf;
   1085 
   1086   /* Returns >= 0 if 'sw' is supported, negative if not.
   1087    *
   1088    *  Set the bit corresponding to 'sw' in 'buf'.  'buf' must have
   1089    *  been allocated by the caller to accommodate this.
   1090    */
   1091   if (fd  == gpio_switch_eviocgbit_fd)
   1092     memcpy(p, eviocbit_ret, n_bytes);
   1093   else
   1094     memset(p, 0, n_bytes);
   1095 
   1096   gpio_switch_eviocgbit_called++;
   1097   return 1;
   1098 }
   1099 
   1100 int gpio_switch_eviocgsw(int fd, void *bits, size_t n_bytes)
   1101 {
   1102   /* Bits set to '1' indicate a switch is enabled.
   1103    * Bits set to '0' indicate a switch is disabled
   1104    */
   1105   gpio_switch_eviocgsw_called++;
   1106   memset(bits, 0xff, n_bytes);
   1107   return 1;
   1108 }
   1109 
   1110 int gpio_switch_read(int fd, void *buf, size_t n_bytes)
   1111 {
   1112   /* This function is only invoked when the 'switch has changed'
   1113    * callback is invoked.  That code is not exercised by this
   1114    * unittest.
   1115    */
   1116   assert(0);
   1117   return 0;
   1118 }
   1119 
   1120 int gpio_switch_open(const char *pathname)
   1121 {
   1122   ++gpio_switch_open_called;
   1123   if (strstr(pathname, "event2"))
   1124 	  return 2;
   1125   if (strstr(pathname, "event3"))
   1126 	  return 3;
   1127   return 0;
   1128 }
   1129 
   1130 void gpio_switch_list_for_each(gpio_switch_list_callback callback, void *arg)
   1131 {
   1132   size_t i = 0;
   1133 
   1134   ++gpio_switch_list_for_each_called;
   1135 
   1136   while (i < gpio_switch_list_for_each_dev_names.size() &&
   1137          i < gpio_switch_list_for_each_dev_paths.size()) {
   1138     callback(gpio_switch_list_for_each_dev_paths[i].c_str(),
   1139              gpio_switch_list_for_each_dev_names[i].c_str(),
   1140              arg);
   1141     i++;
   1142   }
   1143 }
   1144 
   1145 int ucm_set_enabled(
   1146     struct cras_use_case_mgr *mgr, const char *dev, int enable) {
   1147   ucm_set_enabled_value = enable;
   1148   return 0;
   1149 }
   1150 
   1151 char *ucm_get_cap_control(struct cras_use_case_mgr *mgr, const char *ucm_dev) {
   1152   ++ucm_get_cap_control_called;
   1153   return ucm_get_cap_control_value;
   1154 }
   1155 
   1156 char *ucm_get_dev_for_jack(struct cras_use_case_mgr *mgr, const char *jack,
   1157                            CRAS_STREAM_DIRECTION direction) {
   1158   ++ucm_get_dev_for_jack_called;
   1159   if (ucm_get_dev_for_jack_return)
   1160     return static_cast<char*>(malloc(1)); // Will be freed in jack_list_destroy.
   1161   return NULL;
   1162 }
   1163 
   1164 const char *ucm_get_dsp_name(struct cras_use_case_mgr *mgr, const char *ucm_dev,
   1165                        int direction) {
   1166   ++ucm_get_dsp_name_called;
   1167   return NULL;
   1168 }
   1169 
   1170 const char *ucm_get_edid_file_for_dev(struct cras_use_case_mgr *mgr,
   1171 				      const char *dev) {
   1172   return edid_file_ret;
   1173 }
   1174 
   1175 const char *ucm_get_override_type_name(struct cras_use_case_mgr *mgr,
   1176                                        const char *ucm_dev)
   1177 {
   1178   ++ucm_get_override_type_name_called;
   1179   return NULL;
   1180 }
   1181 
   1182 const char *ucm_get_device_name_for_dev(struct cras_use_case_mgr *mgr,
   1183                                         const char *dev,
   1184                                         enum CRAS_STREAM_DIRECTION direction)
   1185 {
   1186   return ucm_get_device_name_for_dev_value;
   1187 }
   1188 
   1189 cras_timer *cras_tm_create_timer(
   1190     cras_tm *tm,
   1191     unsigned int ms,
   1192     void (*cb)(cras_timer *t, void *data),
   1193     void *cb_data) {
   1194   return reinterpret_cast<cras_timer*>(0x55);
   1195 }
   1196 
   1197 void cras_tm_cancel_timer(cras_tm *tm, cras_timer *t) {
   1198 }
   1199 
   1200 cras_tm *cras_system_state_get_tm() {
   1201   return reinterpret_cast<cras_tm*>(0x66);
   1202 }
   1203 
   1204 int edid_valid(const unsigned char *edid_data) {
   1205   return 0;
   1206 }
   1207 
   1208 int edid_lpcm_support(const unsigned char *edid_data, int ext) {
   1209   return 0;
   1210 }
   1211 
   1212 int edid_get_monitor_name(const unsigned char *edid_data,
   1213                           char *buf,
   1214                           unsigned int buf_size) {
   1215   return 0;
   1216 }
   1217 
   1218 // Overwrite this function so unittest can run without 2 seconds of wait
   1219 // in find_gpio_jacks.
   1220 int wait_for_dev_input_access() {
   1221   return 0;
   1222 }
   1223 
   1224 } /* extern "C" */
   1225 
   1226 }  //  namespace
   1227 
   1228 int main(int argc, char **argv) {
   1229   ::testing::InitGoogleTest(&argc, argv);
   1230   openlog(NULL, LOG_PERROR, LOG_USER);
   1231   return RUN_ALL_TESTS();
   1232 }
   1233