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