diff options
Diffstat (limited to 'cras/src/tests/alsa_jack_unittest.cc')
-rw-r--r-- | cras/src/tests/alsa_jack_unittest.cc | 1104 |
1 files changed, 0 insertions, 1104 deletions
diff --git a/cras/src/tests/alsa_jack_unittest.cc b/cras/src/tests/alsa_jack_unittest.cc deleted file mode 100644 index 1aa95491..00000000 --- a/cras/src/tests/alsa_jack_unittest.cc +++ /dev/null @@ -1,1104 +0,0 @@ -// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <gtest/gtest.h> -#include <linux/input.h> -#include <poll.h> -#include <stdio.h> -#include <sys/param.h> -#include <syslog.h> - -#include <deque> -#include <map> -#include <string> -#include <vector> - -extern "C" { -#include "cras_alsa_jack.h" -#include "cras_alsa_ucm_section.h" -#include "cras_gpio_jack.h" -#include "cras_tm.h" -#include "cras_types.h" -#include "cras_util.h" -} - -namespace { - -#define BITS_PER_BYTE (8) -#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE) -#define NBITS(x) ((((x)-1) / BITS_PER_LONG) + 1) -#define OFF(x) ((x) % BITS_PER_LONG) -#define BIT(x) (1UL << OFF(x)) -#define LONG(x) ((x) / BITS_PER_LONG) -#define IS_BIT_SET(bit, array) !!((array[LONG(bit)]) & (1UL << OFF(bit))) - -static int fake_jack_cb_plugged; -static void* fake_jack_cb_data; -static size_t fake_jack_cb_called; -unsigned int snd_hctl_elem_get_device_return_val; -unsigned int snd_hctl_elem_get_device_called; -static size_t snd_hctl_first_elem_called; -static snd_hctl_elem_t* snd_hctl_first_elem_return_val; -static size_t snd_hctl_elem_next_called; -std::deque<snd_hctl_elem_t*> snd_hctl_elem_next_ret_vals; -std::deque<snd_hctl_elem_t*> snd_hctl_elem_next_ret_vals_poped; -static size_t snd_hctl_elem_get_name_called; -static size_t snd_hctl_elem_set_callback_called; -static snd_hctl_elem_t* snd_hctl_elem_set_callback_obj; -static snd_hctl_elem_callback_t snd_hctl_elem_set_callback_value; -static size_t snd_hctl_find_elem_called; -static std::vector<snd_hctl_elem_t*> snd_hctl_find_elem_return_vals; -static std::map<std::string, size_t> snd_ctl_elem_id_set_name_map; -static size_t cras_system_add_select_fd_called; -static std::vector<int> cras_system_add_select_fd_values; -static size_t cras_system_rm_select_fd_called; -static std::vector<int> cras_system_rm_select_fd_values; -static size_t snd_hctl_elem_set_callback_private_called; -static void* snd_hctl_elem_set_callback_private_value; -static size_t snd_hctl_elem_get_hctl_called; -static snd_hctl_t* snd_hctl_elem_get_hctl_return_value; -static size_t snd_ctl_elem_value_get_boolean_called; -static int snd_ctl_elem_value_get_boolean_return_value; -static void* fake_jack_cb_arg; -static struct cras_alsa_mixer* fake_mixer; -static size_t cras_alsa_mixer_get_output_matching_name_called; -static size_t cras_alsa_mixer_get_input_matching_name_called; -static size_t cras_alsa_mixer_get_control_for_section_called; -static struct mixer_control* - cras_alsa_mixer_get_output_matching_name_return_value; -static struct mixer_control* - cras_alsa_mixer_get_input_matching_name_return_value; -static struct mixer_control* - cras_alsa_mixer_get_control_for_section_return_value; -static size_t gpio_switch_list_for_each_called; -static std::vector<std::string> gpio_switch_list_for_each_dev_paths; -static std::vector<std::string> gpio_switch_list_for_each_dev_names; -static size_t gpio_switch_open_called; -static size_t gpio_switch_eviocgsw_called; -static size_t gpio_switch_eviocgbit_called; -static unsigned ucm_get_dev_for_jack_called; -static unsigned ucm_get_cap_control_called; -static char* ucm_get_cap_control_value; -static bool ucm_get_dev_for_jack_return; -static int ucm_set_enabled_value; -static unsigned long eviocbit_ret[NBITS(SW_CNT)]; -static int gpio_switch_eviocgbit_fd; -static const char* edid_file_ret; -static unsigned ucm_get_override_type_name_called; -static int ucm_get_alsa_dev_idx_for_dev_value; -static snd_hctl_t* fake_hctl = (snd_hctl_t*)2; - -static void ResetStubData() { - gpio_switch_list_for_each_called = 0; - gpio_switch_list_for_each_dev_paths.clear(); - gpio_switch_list_for_each_dev_paths.push_back("/dev/input/event3"); - gpio_switch_list_for_each_dev_paths.push_back("/dev/input/event2"); - gpio_switch_list_for_each_dev_names.clear(); - gpio_switch_open_called = 0; - gpio_switch_eviocgsw_called = 0; - gpio_switch_eviocgbit_called = 0; - snd_hctl_elem_get_device_return_val = 0; - snd_hctl_elem_get_device_called = 0; - snd_hctl_first_elem_called = 0; - snd_hctl_first_elem_return_val = reinterpret_cast<snd_hctl_elem_t*>(0x87); - snd_hctl_elem_next_called = 0; - snd_hctl_elem_next_ret_vals.clear(); - snd_hctl_elem_next_ret_vals_poped.clear(); - snd_hctl_elem_get_name_called = 0; - snd_hctl_elem_set_callback_called = 0; - snd_hctl_elem_set_callback_obj = NULL; - snd_hctl_elem_set_callback_value = NULL; - snd_hctl_find_elem_called = 0; - snd_hctl_find_elem_return_vals.clear(); - snd_ctl_elem_id_set_name_map.clear(); - cras_system_add_select_fd_called = 0; - cras_system_add_select_fd_values.clear(); - cras_system_rm_select_fd_called = 0; - cras_system_rm_select_fd_values.clear(); - snd_hctl_elem_set_callback_private_called = 0; - snd_hctl_elem_get_hctl_called = 0; - snd_ctl_elem_value_get_boolean_called = 0; - fake_jack_cb_called = 0; - fake_jack_cb_plugged = 0; - fake_jack_cb_arg = reinterpret_cast<void*>(0x987); - fake_mixer = reinterpret_cast<struct cras_alsa_mixer*>(0x789); - cras_alsa_mixer_get_output_matching_name_called = 0; - cras_alsa_mixer_get_input_matching_name_called = 0; - cras_alsa_mixer_get_control_for_section_called = 0; - cras_alsa_mixer_get_output_matching_name_return_value = - reinterpret_cast<struct mixer_control*>(0x456); - cras_alsa_mixer_get_input_matching_name_return_value = NULL; - cras_alsa_mixer_get_control_for_section_return_value = - reinterpret_cast<struct mixer_control*>(0x456); - ucm_get_dev_for_jack_called = 0; - ucm_get_cap_control_called = 0; - ucm_get_cap_control_value = NULL; - ucm_get_dev_for_jack_return = false; - edid_file_ret = NULL; - ucm_get_override_type_name_called = 0; - ucm_get_alsa_dev_idx_for_dev_value = -1; - - memset(eviocbit_ret, 0, sizeof(eviocbit_ret)); -} - -static void fake_jack_cb(const struct cras_alsa_jack* jack, - int plugged, - void* data) { - fake_jack_cb_called++; - fake_jack_cb_plugged = plugged; - fake_jack_cb_data = data; - - // Check that jack enable callback is called if there is a ucm device. - ucm_set_enabled_value = !plugged; - cras_alsa_jack_enable_ucm(jack, plugged); - EXPECT_EQ(ucm_get_dev_for_jack_return ? plugged : !plugged, - ucm_set_enabled_value); -} - -TEST(AlsaJacks, CreateNullHctl) { - struct cras_alsa_jack_list* jack_list; - ResetStubData(); - jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1, fake_mixer, NULL, NULL, - CRAS_STREAM_OUTPUT, fake_jack_cb, - fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - EXPECT_EQ(1, gpio_switch_list_for_each_called); - EXPECT_EQ(0, gpio_switch_open_called); - EXPECT_EQ(0, gpio_switch_eviocgsw_called); - EXPECT_EQ(0, gpio_switch_eviocgbit_called); - - cras_alsa_jack_list_destroy(jack_list); -} - -TEST(AlsaJacks, CreateNoElements) { - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - snd_hctl_first_elem_return_val = NULL; - jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1, fake_mixer, NULL, - fake_hctl, CRAS_STREAM_OUTPUT, - fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - EXPECT_EQ(1, gpio_switch_list_for_each_called); - EXPECT_EQ(0, gpio_switch_open_called); - EXPECT_EQ(0, gpio_switch_eviocgsw_called); - EXPECT_EQ(0, gpio_switch_eviocgbit_called); - EXPECT_EQ(1, snd_hctl_first_elem_called); - EXPECT_EQ(0, snd_hctl_elem_next_called); - - cras_alsa_jack_list_destroy(jack_list); -} - -static struct cras_alsa_jack_list* run_test_with_elem_list( - CRAS_STREAM_DIRECTION direction, - std::string* elems, - unsigned int device_index, - struct cras_use_case_mgr* ucm, - size_t nelems, - size_t nhdmi_jacks, - size_t njacks) { - struct cras_alsa_jack_list* jack_list; - - snd_hctl_first_elem_return_val = - reinterpret_cast<snd_hctl_elem_t*>(&elems[0]); - for (unsigned int i = 1; i < nelems; i++) - snd_hctl_elem_next_ret_vals.push_front( - reinterpret_cast<snd_hctl_elem_t*>(&elems[i])); - - jack_list = cras_alsa_jack_list_create(0, "card_name", device_index, 1, - fake_mixer, ucm, fake_hctl, direction, - fake_jack_cb, fake_jack_cb_arg); - if (jack_list == NULL) - return jack_list; - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - EXPECT_EQ(ucm ? njacks : 0, ucm_get_dev_for_jack_called); - EXPECT_EQ(ucm ? njacks : 0, ucm_get_override_type_name_called); - EXPECT_EQ(1, snd_hctl_first_elem_called); - EXPECT_EQ(njacks, snd_hctl_elem_set_callback_called); - EXPECT_EQ(nhdmi_jacks, snd_hctl_find_elem_called); - - /* For some functions, the number of calls to them could - * be larger then expected count if there is ELD control - * in given elements. */ - EXPECT_GE(snd_hctl_elem_next_called, nelems); - EXPECT_GE(snd_hctl_elem_get_name_called, nelems); - - if (direction == CRAS_STREAM_OUTPUT) { - EXPECT_EQ(njacks, cras_alsa_mixer_get_output_matching_name_called); - } - if (direction == CRAS_STREAM_INPUT && ucm_get_dev_for_jack_return) { - EXPECT_EQ(njacks, ucm_get_cap_control_called); - } - - return jack_list; -} - -static struct cras_alsa_jack_list* run_test_with_section( - CRAS_STREAM_DIRECTION direction, - std::string* elems, - size_t nelems, - unsigned int device_index, - struct cras_use_case_mgr* ucm, - struct ucm_section* ucm_section, - int add_jack_rc, - size_t njacks) { - struct cras_alsa_jack_list* jack_list; - struct cras_alsa_jack* jack; - - for (size_t i = 0; i < nelems; i++) { - snd_ctl_elem_id_set_name_map[elems[i]] = i; - snd_hctl_find_elem_return_vals.push_back( - reinterpret_cast<snd_hctl_elem_t*>(&elems[i])); - } - - jack_list = cras_alsa_jack_list_create(0, "card_name", device_index, 1, - fake_mixer, ucm, fake_hctl, direction, - fake_jack_cb, fake_jack_cb_arg); - if (jack_list == NULL) - return jack_list; - EXPECT_EQ(add_jack_rc, cras_alsa_jack_list_add_jack_for_section( - jack_list, ucm_section, &jack)); - if (add_jack_rc == 0) { - EXPECT_NE(jack, reinterpret_cast<struct cras_alsa_jack*>(NULL)); - } else { - EXPECT_EQ(jack, reinterpret_cast<struct cras_alsa_jack*>(NULL)); - } - if (add_jack_rc != 0) { - cras_alsa_jack_list_destroy(jack_list); - return NULL; - } - EXPECT_EQ(njacks, snd_hctl_elem_set_callback_called); - EXPECT_EQ(njacks, cras_alsa_mixer_get_control_for_section_called); - - return jack_list; -} - -TEST(AlsaJacks, ReportNull) { - cras_alsa_jack_list_report(NULL); -} - -TEST(AlsaJacks, CreateNoJacks) { - static std::string elem_names[] = { - "Mic Jack", - "foo", - "bar", - }; - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - jack_list = run_test_with_elem_list(CRAS_STREAM_OUTPUT, elem_names, 0, NULL, - ARRAY_SIZE(elem_names), 0, 0); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(0, cras_system_rm_select_fd_called); -} - -TEST(AlsaJacks, CreateGPIOHp) { - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - gpio_switch_list_for_each_dev_names.push_back("some-other-device"); - gpio_switch_list_for_each_dev_names.push_back("c1 Headphone Jack"); - eviocbit_ret[LONG(SW_HEADPHONE_INSERT)] |= 1 << OFF(SW_HEADPHONE_INSERT); - gpio_switch_eviocgbit_fd = 2; - snd_hctl_first_elem_return_val = NULL; - jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1, fake_mixer, NULL, - fake_hctl, CRAS_STREAM_OUTPUT, - fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(1, gpio_switch_list_for_each_called); - EXPECT_GT(gpio_switch_open_called, 1); - EXPECT_EQ(1, gpio_switch_eviocgsw_called); - EXPECT_GT(gpio_switch_eviocgbit_called, 1); - EXPECT_EQ(1, cras_system_add_select_fd_called); - EXPECT_EQ(1, cras_system_rm_select_fd_called); -} - -TEST(AlsaJacks, CreateGPIOMic) { - struct cras_alsa_jack_list* jack_list; - ResetStubData(); - ucm_get_dev_for_jack_return = true; - gpio_switch_list_for_each_dev_names.push_back("c1 Mic Jack"); - gpio_switch_list_for_each_dev_names.push_back("c1 Headphone Jack"); - eviocbit_ret[LONG(SW_MICROPHONE_INSERT)] |= 1 << OFF(SW_MICROPHONE_INSERT); - gpio_switch_eviocgbit_fd = 3; - snd_hctl_first_elem_return_val = NULL; - ucm_get_cap_control_value = reinterpret_cast<char*>(0x1); - - cras_alsa_mixer_get_input_matching_name_return_value = - reinterpret_cast<struct mixer_control*>(malloc(1)); - - jack_list = cras_alsa_jack_list_create( - 0, "c1", 0, 1, fake_mixer, - reinterpret_cast<struct cras_use_case_mgr*>(0x55), fake_hctl, - CRAS_STREAM_INPUT, fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - EXPECT_EQ(ucm_get_cap_control_called, 1); - EXPECT_EQ(cras_alsa_mixer_get_input_matching_name_called, 1); - cras_alsa_jack_list_destroy(jack_list); - // Mixer will be free by alsa_card_destroy, we should free it explicitly here - free(cras_alsa_mixer_get_input_matching_name_return_value); -} - -TEST(AlsaJacks, CreateGPIOHdmi) { - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - gpio_switch_list_for_each_dev_names.push_back("c1 HDMI Jack"); - gpio_switch_list_for_each_dev_names.push_back("c1 Mic Jack"); - eviocbit_ret[LONG(SW_LINEOUT_INSERT)] |= 1 << OFF(SW_LINEOUT_INSERT); - gpio_switch_eviocgbit_fd = 3; - snd_hctl_first_elem_return_val = NULL; - jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1, fake_mixer, NULL, - fake_hctl, CRAS_STREAM_OUTPUT, - fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - EXPECT_EQ(1, gpio_switch_eviocgsw_called); - - fake_jack_cb_called = 0; - cras_alsa_jack_list_report(jack_list); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(1, gpio_switch_list_for_each_called); - EXPECT_GT(gpio_switch_open_called, 1); - EXPECT_GT(gpio_switch_eviocgbit_called, 1); - EXPECT_EQ(1, cras_system_add_select_fd_called); - EXPECT_EQ(1, cras_system_rm_select_fd_called); -} - -void run_gpio_jack_test(int device_index, - int is_first_device, - enum CRAS_STREAM_DIRECTION direction, - int should_create_jack, - const char* jack_name) { - struct cras_alsa_jack_list* jack_list; - struct cras_use_case_mgr* ucm = - reinterpret_cast<struct cras_use_case_mgr*>(0x55); - - gpio_switch_list_for_each_dev_names.push_back("some-other-device one"); - gpio_switch_eviocgbit_fd = 2; - if (direction == CRAS_STREAM_OUTPUT) { - eviocbit_ret[LONG(SW_HEADPHONE_INSERT)] |= 1 << OFF(SW_HEADPHONE_INSERT); - } else { - eviocbit_ret[LONG(SW_MICROPHONE_INSERT)] |= 1 << OFF(SW_MICROPHONE_INSERT); - } - gpio_switch_list_for_each_dev_names.push_back(jack_name); - snd_hctl_first_elem_return_val = NULL; - - jack_list = cras_alsa_jack_list_create(0, "c1", device_index, is_first_device, - fake_mixer, ucm, fake_hctl, direction, - fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - - cras_alsa_jack_list_report(jack_list); - EXPECT_EQ(should_create_jack, fake_jack_cb_plugged); - EXPECT_EQ(should_create_jack, fake_jack_cb_called); - - cras_alsa_jack_list_destroy(jack_list); -} - -TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMMatched) { - int device_index = 1; - int is_first_device = 0; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT; - int should_create_jack = 1; - - ResetStubData(); - - /* PlaybackPCM matched, so create jack even if this is not the first device.*/ - ucm_get_dev_for_jack_return = true; - ucm_get_alsa_dev_idx_for_dev_value = 1; - - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Headset Jack"); -} - -TEST(AlsaJacks, CreateGPIOHpUCMCapturePCMMatched) { - int device_index = 1; - int is_first_device = 0; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_INPUT; - int should_create_jack = 1; - - ResetStubData(); - - /* CapturePCM matched, so create jack even if this is not the first device.*/ - ucm_get_dev_for_jack_return = true; - ucm_get_alsa_dev_idx_for_dev_value = 1; - - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Mic Jack"); -} - -TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotMatched) { - int device_index = 0; - int is_first_device = 1; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT; - int should_create_jack = 0; - - ResetStubData(); - - /* PlaybackPCM not matched, do not create jack. */ - ucm_get_dev_for_jack_return = true; - ucm_get_alsa_dev_idx_for_dev_value = 2; - - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Headset Jack"); -} - -TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotSpecifiedFirstDevice) { - int device_index = 1; - int is_first_device = 1; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT; - int should_create_jack = 1; - - ResetStubData(); - - /* PlaybackPCM not specified, create jack for the first device. */ - ucm_get_dev_for_jack_return = true; - ucm_get_alsa_dev_idx_for_dev_value = -1; - - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Headset Jack"); -} - -TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotSpecifiedSecondDevice) { - int device_index = 1; - int is_first_device = 0; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT; - int should_create_jack = 0; - - ResetStubData(); - - /* PlaybackPCM not specified, do not create jack for the second device. */ - ucm_get_dev_for_jack_return = true; - ucm_get_alsa_dev_idx_for_dev_value = -1; - - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Headset Jack"); -} - -TEST(AlsaJacks, CreateGPIOHpNoUCMFirstDevice) { - int device_index = 1; - int is_first_device = 1; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT; - int should_create_jack = 1; - - ResetStubData(); - - /* No UCM for this jack, create jack for the first device. */ - ucm_get_dev_for_jack_return = false; - ucm_get_alsa_dev_idx_for_dev_value = -1; - - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Headset Jack"); -} - -TEST(AlsaJacks, CreateGPIOHpNoUCMSecondDevice) { - int device_index = 1; - int is_first_device = 0; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_OUTPUT; - int should_create_jack = 0; - - ResetStubData(); - - /* No UCM for this jack, dot not create jack for the second device. */ - ucm_get_dev_for_jack_return = false; - ucm_get_alsa_dev_idx_for_dev_value = -1; - - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Headset Jack"); -} - -TEST(AlsaJacks, CreateGPIOMicNoUCMFirstDeviceMicJack) { - int device_index = 1; - int is_first_device = 1; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_INPUT; - int should_create_jack = 1; - - ResetStubData(); - - // No UCM for this jack, create jack for the first device. - ucm_get_dev_for_jack_return = false; - ucm_get_alsa_dev_idx_for_dev_value = -1; - - // Mic Jack is a valid name for microphone jack. - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Mic Jack"); -} - -TEST(AlsaJacks, CreateGPIOMicNoUCMFirstDeviceHeadsetJack) { - int device_index = 1; - int is_first_device = 1; - enum CRAS_STREAM_DIRECTION direction = CRAS_STREAM_INPUT; - int should_create_jack = 1; - - ResetStubData(); - - // No UCM for this jack, create jack for the first device. - ucm_get_dev_for_jack_return = false; - ucm_get_alsa_dev_idx_for_dev_value = -1; - - // Headset Jack is a valid name for microphone jack. - run_gpio_jack_test(device_index, is_first_device, direction, - should_create_jack, "c1 Headset Jack"); -} - -TEST(AlsaJacks, GPIOHdmiWithEdid) { - cras_alsa_jack_list* jack_list; - - ResetStubData(); - ucm_get_dev_for_jack_return = 1; - edid_file_ret = static_cast<char*>(calloc(1, 1)); // Freed in destroy. - gpio_switch_list_for_each_dev_names.push_back("c1 HDMI Jack"); - eviocbit_ret[LONG(SW_LINEOUT_INSERT)] |= 1 << OFF(SW_LINEOUT_INSERT); - gpio_switch_eviocgbit_fd = 3; - snd_hctl_first_elem_return_val = NULL; - jack_list = cras_alsa_jack_list_create( - 0, "c1", 0, 1, fake_mixer, - reinterpret_cast<struct cras_use_case_mgr*>(0x55), fake_hctl, - CRAS_STREAM_OUTPUT, fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - EXPECT_EQ(1, gpio_switch_eviocgsw_called); - - // EDID shouldn't open, callback should be skipped until re-try. - fake_jack_cb_called = 0; - cras_alsa_jack_list_report(jack_list); - EXPECT_EQ(0, fake_jack_cb_called); - - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(1, gpio_switch_list_for_each_called); - EXPECT_GT(gpio_switch_open_called, 1); - EXPECT_GT(gpio_switch_eviocgbit_called, 1); - EXPECT_EQ(1, cras_system_add_select_fd_called); - EXPECT_EQ(1, cras_system_rm_select_fd_called); -} - -TEST(AlsaJacks, CreateGPIOHpNoNameMatch) { - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - gpio_switch_list_for_each_dev_names.push_back("some-other-device one"); - gpio_switch_list_for_each_dev_names.push_back("some-other-device two"); - snd_hctl_first_elem_return_val = NULL; - jack_list = cras_alsa_jack_list_create(0, "c2", 0, 1, fake_mixer, NULL, - fake_hctl, CRAS_STREAM_OUTPUT, - fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list)); - - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(1, gpio_switch_list_for_each_called); - EXPECT_EQ(0, gpio_switch_open_called); - EXPECT_EQ(0, cras_system_add_select_fd_called); - EXPECT_EQ(0, cras_system_rm_select_fd_called); -} - -TEST(AlsaJacks, CreateOneHpJack) { - std::string elem_names[] = { - "asdf", - "Headphone Jack, klasdjf", - "Mic Jack", - }; - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - jack_list = run_test_with_elem_list(CRAS_STREAM_OUTPUT, elem_names, 0, NULL, - ARRAY_SIZE(elem_names), 0, 1); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - ASSERT_NE(reinterpret_cast<snd_hctl_elem_callback_t>(NULL), - snd_hctl_elem_set_callback_value); - EXPECT_EQ(1, snd_hctl_elem_set_callback_called); - - snd_hctl_elem_get_hctl_return_value = reinterpret_cast<snd_hctl_t*>(0x33); - snd_hctl_elem_get_name_called = 0; - snd_ctl_elem_value_get_boolean_return_value = 1; - snd_hctl_elem_set_callback_value( - reinterpret_cast<snd_hctl_elem_t*>(&elem_names[1]), 0); - EXPECT_EQ(1, snd_hctl_elem_get_name_called); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data); - EXPECT_EQ(reinterpret_cast<snd_hctl_elem_t*>(&elem_names[1]), - snd_hctl_elem_set_callback_obj); - - fake_jack_cb_called = 0; - cras_alsa_jack_list_report(jack_list); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(2, snd_hctl_elem_set_callback_called); - EXPECT_EQ(reinterpret_cast<snd_hctl_elem_callback_t>(NULL), - snd_hctl_elem_set_callback_value); -} - -TEST(AlsaJacks, CreateOneMicJack) { - static std::string elem_names[] = { - "asdf", "Headphone Jack", "HDMI/DP,pcm=5 Jack", "HDMI/DP,pcm=6 Jack", - "Mic Jack", - }; - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - jack_list = run_test_with_elem_list(CRAS_STREAM_INPUT, elem_names, 0, NULL, - ARRAY_SIZE(elem_names), 0, 1); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - ASSERT_NE(reinterpret_cast<snd_hctl_elem_callback_t>(NULL), - snd_hctl_elem_set_callback_value); - EXPECT_EQ(1, snd_hctl_elem_set_callback_called); - - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(0, cras_system_rm_select_fd_called); - EXPECT_EQ(2, snd_hctl_elem_set_callback_called); - EXPECT_EQ(reinterpret_cast<snd_hctl_elem_callback_t>(NULL), - snd_hctl_elem_set_callback_value); -} - -TEST(AlsaJacks, CreateHDMIJacksWithELD) { - std::string elem_names[] = {"asdf", "HDMI/DP,pcm=3 Jack", "ELD", - "HDMI/DP,pcm=4 Jack"}; - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - snd_hctl_elem_get_device_return_val = 3; - - jack_list = run_test_with_elem_list(CRAS_STREAM_OUTPUT, elem_names, 3, NULL, - ARRAY_SIZE(elem_names), 1, 1); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - - /* Assert get device is called for the ELD control */ - EXPECT_EQ(1, snd_hctl_find_elem_called); - cras_alsa_jack_list_destroy(jack_list); -} - -TEST(AlsaJacks, CreateOneHpTwoHDMIJacks) { - std::string elem_names[] = { - "asdf", - "Headphone Jack, klasdjf", - "HDMI/DP,pcm=5 Jack", - "HDMI/DP,pcm=6 Jack", - "Mic Jack", - }; - struct cras_alsa_jack_list* jack_list; - - ResetStubData(); - ucm_get_dev_for_jack_return = true; - jack_list = - run_test_with_elem_list(CRAS_STREAM_OUTPUT, elem_names, 5, - reinterpret_cast<struct cras_use_case_mgr*>(0x55), - ARRAY_SIZE(elem_names), 1, 1); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - - snd_hctl_elem_get_hctl_return_value = reinterpret_cast<snd_hctl_t*>(0x33); - snd_hctl_elem_get_name_called = 0; - snd_ctl_elem_value_get_boolean_return_value = 1; - snd_hctl_elem_set_callback_value( - reinterpret_cast<snd_hctl_elem_t*>(&elem_names[2]), 0); - EXPECT_EQ(1, snd_hctl_elem_get_name_called); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data); - EXPECT_EQ(reinterpret_cast<snd_hctl_elem_t*>(&elem_names[2]), - snd_hctl_elem_set_callback_obj); - - fake_jack_cb_called = 0; - cras_alsa_jack_list_report(jack_list); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - - cras_alsa_jack_list_destroy(jack_list); -} - -TEST(AlsaJacks, CreateHCTLHeadphoneJackFromUCM) { - std::string elem_names[] = { - "HP/DP,pcm=5 Jack", - "Headphone Jack", - }; - struct cras_alsa_jack_list* jack_list; - struct ucm_section* section; - - section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT, - "Headphone Jack", "hctl"); - - ResetStubData(); - ucm_get_dev_for_jack_return = true; - - jack_list = run_test_with_section( - CRAS_STREAM_OUTPUT, elem_names, ARRAY_SIZE(elem_names), 5, - reinterpret_cast<struct cras_use_case_mgr*>(0x55), section, 0, 1); - ASSERT_NE(reinterpret_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - - snd_hctl_elem_get_hctl_return_value = reinterpret_cast<snd_hctl_t*>(0x33); - snd_ctl_elem_value_get_boolean_return_value = 1; - snd_hctl_elem_set_callback_value( - reinterpret_cast<snd_hctl_elem_t*>(&elem_names[1]), 0); - EXPECT_EQ(1, snd_hctl_elem_get_name_called); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data); - EXPECT_EQ(reinterpret_cast<snd_hctl_elem_t*>(&elem_names[1]), - snd_hctl_elem_set_callback_obj); - - fake_jack_cb_called = 0; - cras_alsa_jack_list_report(jack_list); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - - ucm_section_free_list(section); - cras_alsa_jack_list_destroy(jack_list); -} - -TEST(AlsaJacks, CreateGPIOHeadphoneJackFromUCM) { - struct cras_alsa_jack_list* jack_list; - struct cras_alsa_jack* jack; - struct ucm_section* section; - - section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT, - "c1 Headphone Jack", "gpio"); - - ResetStubData(); - gpio_switch_list_for_each_dev_names.push_back("some-other-device"); - gpio_switch_list_for_each_dev_names.push_back("c1 Headphone Jack"); - eviocbit_ret[LONG(SW_HEADPHONE_INSERT)] |= 1 << OFF(SW_HEADPHONE_INSERT); - gpio_switch_eviocgbit_fd = 2; - snd_hctl_first_elem_return_val = NULL; - jack_list = cras_alsa_jack_list_create(0, "c1", 0, 1, fake_mixer, NULL, - fake_hctl, CRAS_STREAM_OUTPUT, - fake_jack_cb, fake_jack_cb_arg); - ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - EXPECT_EQ( - 0, cras_alsa_jack_list_add_jack_for_section(jack_list, section, &jack)); - EXPECT_EQ(1, gpio_switch_list_for_each_called); - EXPECT_GT(gpio_switch_open_called, 1); - EXPECT_EQ(1, gpio_switch_eviocgsw_called); - EXPECT_GT(gpio_switch_eviocgbit_called, 1); - EXPECT_EQ(1, cras_system_add_select_fd_called); - EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called); - - fake_jack_cb_called = 0; - ucm_get_dev_for_jack_return = true; - cras_alsa_jack_list_report(jack_list); - EXPECT_EQ(1, fake_jack_cb_plugged); - EXPECT_EQ(1, fake_jack_cb_called); - EXPECT_EQ(fake_jack_cb_arg, fake_jack_cb_data); - - ucm_section_free_list(section); - cras_alsa_jack_list_destroy(jack_list); - EXPECT_EQ(1, cras_system_rm_select_fd_called); -} - -TEST(AlsaJacks, BadJackTypeFromUCM) { - std::string elem_names[] = { - "HP/DP,pcm=5 Jack", - "Headphone Jack", - }; - struct cras_alsa_jack_list* jack_list; - struct ucm_section* section; - - section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT, - "Headphone Jack", "badtype"); - - ResetStubData(); - ucm_get_dev_for_jack_return = true; - - jack_list = run_test_with_section( - CRAS_STREAM_OUTPUT, elem_names, ARRAY_SIZE(elem_names), 5, - reinterpret_cast<struct cras_use_case_mgr*>(0x55), section, -22, 1); - EXPECT_EQ(reinterpret_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - - ucm_section_free_list(section); -} - -TEST(AlsaJacks, NoJackTypeFromUCM) { - std::string elem_names[] = { - "HP/DP,pcm=5 Jack", - "Headphone Jack", - }; - struct cras_alsa_jack_list* jack_list; - struct ucm_section* section; - - section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT, - "Headphone Jack", NULL); - - ResetStubData(); - ucm_get_dev_for_jack_return = true; - - jack_list = run_test_with_section( - CRAS_STREAM_OUTPUT, elem_names, ARRAY_SIZE(elem_names), 5, - reinterpret_cast<struct cras_use_case_mgr*>(0x55), section, -22, 1); - EXPECT_EQ(reinterpret_cast<struct cras_alsa_jack_list*>(NULL), jack_list); - - ucm_section_free_list(section); -} - -/* Stubs */ - -extern "C" { - -// From cras_system_state -int cras_system_add_select_fd(int fd, - void (*callback)(void* data), - void* callback_data) { - cras_system_add_select_fd_called++; - cras_system_add_select_fd_values.push_back(fd); - return 0; -} -void cras_system_rm_select_fd(int fd) { - cras_system_rm_select_fd_called++; - cras_system_rm_select_fd_values.push_back(fd); -} - -// From alsa-lib hcontrol.c -unsigned int snd_hctl_elem_get_device(const snd_hctl_elem_t* obj) { - snd_hctl_elem_get_device_called = 1; - return snd_hctl_elem_get_device_return_val; -} -snd_hctl_elem_t* snd_hctl_first_elem(snd_hctl_t* hctl) { - snd_hctl_first_elem_called++; - - /* When first elem is called, restored the poped ret values */ - while (!snd_hctl_elem_next_ret_vals_poped.empty()) { - snd_hctl_elem_t* tmp = snd_hctl_elem_next_ret_vals_poped.back(); - snd_hctl_elem_next_ret_vals_poped.pop_back(); - snd_hctl_elem_next_ret_vals.push_back(tmp); - } - return snd_hctl_first_elem_return_val; -} -snd_hctl_elem_t* snd_hctl_elem_next(snd_hctl_elem_t* elem) { - snd_hctl_elem_next_called++; - if (snd_hctl_elem_next_ret_vals.empty()) - return NULL; - snd_hctl_elem_t* ret_elem = snd_hctl_elem_next_ret_vals.back(); - snd_hctl_elem_next_ret_vals.pop_back(); - snd_hctl_elem_next_ret_vals_poped.push_back(ret_elem); - return ret_elem; -} -const char* snd_hctl_elem_get_name(const snd_hctl_elem_t* obj) { - snd_hctl_elem_get_name_called++; - const std::string* name = reinterpret_cast<const std::string*>(obj); - return name->c_str(); -} -snd_ctl_elem_iface_t snd_hctl_elem_get_interface(const snd_hctl_elem_t* obj) { - return SND_CTL_ELEM_IFACE_CARD; -} -void snd_hctl_elem_set_callback(snd_hctl_elem_t* obj, - snd_hctl_elem_callback_t val) { - snd_hctl_elem_set_callback_called++; - snd_hctl_elem_set_callback_obj = obj; - snd_hctl_elem_set_callback_value = val; -} -void snd_hctl_elem_set_callback_private(snd_hctl_elem_t* obj, void* val) { - snd_hctl_elem_set_callback_private_called++; - snd_hctl_elem_set_callback_private_value = val; -} -void* snd_hctl_elem_get_callback_private(const snd_hctl_elem_t* obj) { - return snd_hctl_elem_set_callback_private_value; -} -snd_hctl_t* snd_hctl_elem_get_hctl(snd_hctl_elem_t* elem) { - snd_hctl_elem_get_hctl_called++; - return snd_hctl_elem_get_hctl_return_value; -} -int snd_hctl_elem_read(snd_hctl_elem_t* elem, snd_ctl_elem_value_t* value) { - return 0; -} -snd_hctl_elem_t* snd_hctl_find_elem(snd_hctl_t* hctl, - const snd_ctl_elem_id_t* id) { - const size_t* index = reinterpret_cast<const size_t*>(id); - snd_hctl_find_elem_called++; - if (*index < snd_hctl_find_elem_return_vals.size()) - return snd_hctl_find_elem_return_vals[*index]; - return NULL; -} -void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t* obj, - snd_ctl_elem_iface_t val) {} -void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t* obj, unsigned int val) {} -void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t* obj, const char* val) { - size_t* obj_id = reinterpret_cast<size_t*>(obj); - std::map<std::string, size_t>::iterator id_name_it = - snd_ctl_elem_id_set_name_map.find(val); - if (id_name_it != snd_ctl_elem_id_set_name_map.end()) - *obj_id = id_name_it->second; - else - *obj_id = INT_MAX; -} - -// From alsa-lib control.c -int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t* obj, - unsigned int idx) { - snd_ctl_elem_value_get_boolean_called++; - return snd_ctl_elem_value_get_boolean_return_value; -} - -// From cras_alsa_mixer -struct mixer_control* cras_alsa_mixer_get_output_matching_name( - const struct cras_alsa_mixer* cras_mixer, - size_t device_index, - const char* const name) { - cras_alsa_mixer_get_output_matching_name_called++; - return cras_alsa_mixer_get_output_matching_name_return_value; -} - -struct mixer_control* cras_alsa_mixer_get_input_matching_name( - struct cras_alsa_mixer* cras_mixer, - const char* control_name) { - cras_alsa_mixer_get_input_matching_name_called++; - return cras_alsa_mixer_get_input_matching_name_return_value; -} - -struct mixer_control* cras_alsa_mixer_get_control_for_section( - struct cras_alsa_mixer* cras_mixer, - struct ucm_section* section) { - cras_alsa_mixer_get_control_for_section_called++; - return cras_alsa_mixer_get_control_for_section_return_value; -} - -int gpio_switch_eviocgbit(int fd, void* buf, size_t n_bytes) { - unsigned char* p = (unsigned char*)buf; - - /* Returns >= 0 if 'sw' is supported, negative if not. - * - * Set the bit corresponding to 'sw' in 'buf'. 'buf' must have - * been allocated by the caller to accommodate this. - */ - if (fd == gpio_switch_eviocgbit_fd) - memcpy(p, eviocbit_ret, n_bytes); - else - memset(p, 0, n_bytes); - - gpio_switch_eviocgbit_called++; - return 1; -} - -int gpio_switch_eviocgsw(int fd, void* bits, size_t n_bytes) { - /* Bits set to '1' indicate a switch is enabled. - * Bits set to '0' indicate a switch is disabled - */ - gpio_switch_eviocgsw_called++; - memset(bits, 0xff, n_bytes); - return 1; -} - -int gpio_switch_read(int fd, void* buf, size_t n_bytes) { - /* This function is only invoked when the 'switch has changed' - * callback is invoked. That code is not exercised by this - * unittest. - */ - assert(0); - return 0; -} - -int gpio_switch_open(const char* pathname) { - ++gpio_switch_open_called; - if (strstr(pathname, "event2")) - return 2; - if (strstr(pathname, "event3")) - return 3; - return 0; -} - -void gpio_switch_list_for_each(gpio_switch_list_callback callback, void* arg) { - size_t i = 0; - - ++gpio_switch_list_for_each_called; - - while (i < gpio_switch_list_for_each_dev_names.size() && - i < gpio_switch_list_for_each_dev_paths.size()) { - callback(gpio_switch_list_for_each_dev_paths[i].c_str(), - gpio_switch_list_for_each_dev_names[i].c_str(), arg); - i++; - } -} - -int ucm_set_enabled(struct cras_use_case_mgr* mgr, - const char* dev, - int enable) { - ucm_set_enabled_value = enable; - return 0; -} - -char* ucm_get_cap_control(struct cras_use_case_mgr* mgr, const char* ucm_dev) { - ++ucm_get_cap_control_called; - return ucm_get_cap_control_value; -} - -char* ucm_get_dev_for_jack(struct cras_use_case_mgr* mgr, - const char* jack, - CRAS_STREAM_DIRECTION direction) { - ++ucm_get_dev_for_jack_called; - if (ucm_get_dev_for_jack_return) - return static_cast<char*>( - malloc(1)); // Will be freed in jack_list_destroy. - return NULL; -} - -const char* ucm_get_edid_file_for_dev(struct cras_use_case_mgr* mgr, - const char* dev) { - return edid_file_ret; -} - -const char* ucm_get_override_type_name(struct cras_use_case_mgr* mgr, - const char* ucm_dev) { - ++ucm_get_override_type_name_called; - return NULL; -} - -int ucm_get_alsa_dev_idx_for_dev(struct cras_use_case_mgr* mgr, - const char* dev, - enum CRAS_STREAM_DIRECTION direction) { - return ucm_get_alsa_dev_idx_for_dev_value; -} - -cras_timer* cras_tm_create_timer(cras_tm* tm, - unsigned int ms, - void (*cb)(cras_timer* t, void* data), - void* cb_data) { - return reinterpret_cast<cras_timer*>(0x55); -} - -void cras_tm_cancel_timer(cras_tm* tm, cras_timer* t) {} - -cras_tm* cras_system_state_get_tm() { - return reinterpret_cast<cras_tm*>(0x66); -} - -int edid_valid(const unsigned char* edid_data) { - return 0; -} - -int edid_lpcm_support(const unsigned char* edid_data, int ext) { - return 0; -} - -int edid_get_monitor_name(const unsigned char* edid_data, - char* buf, - unsigned int buf_size) { - return 0; -} - -// Overwrite this function so unittest can run without 2 seconds of wait -// in find_gpio_jacks. -int wait_for_dev_input_access() { - return 0; -} - -} /* extern "C" */ - -} // namespace - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - openlog(NULL, LOG_PERROR, LOG_USER); - return RUN_ALL_TESTS(); -} |