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 <gtest/gtest.h>
6 #include <stdio.h>
7 #include <syslog.h>
8
9 #include <map>
10 #include <vector>
11
12 extern "C" {
13
14 #include "cras_alsa_mixer.h"
15 #include "cras_iodev.h"
16 #include "cras_shm.h"
17 #include "cras_system_state.h"
18 #include "cras_types.h"
19
20 // Include C file to test static functions.
21 #include "cras_alsa_io.c"
22 }
23
24 #define BUFFER_SIZE 8192
25
26 // Data for simulating functions stubbed below.
27 static int cras_alsa_open_called;
28 static int cras_iodev_append_stream_ret;
29 static int cras_alsa_get_avail_frames_ret;
30 static int cras_alsa_get_avail_frames_avail;
31 static int cras_alsa_start_called;
32 static uint8_t* cras_alsa_mmap_begin_buffer;
33 static size_t cras_alsa_mmap_begin_frames;
34 static size_t cras_alsa_fill_properties_called;
35 static bool cras_alsa_support_8_channels;
36 static size_t alsa_mixer_set_dBFS_called;
37 static int alsa_mixer_set_dBFS_value;
38 static const struct mixer_control* alsa_mixer_set_dBFS_output;
39 static size_t alsa_mixer_set_capture_dBFS_called;
40 static int alsa_mixer_set_capture_dBFS_value;
41 static const struct mixer_control* alsa_mixer_set_capture_dBFS_input;
42 static const struct mixer_control*
43 cras_alsa_mixer_get_minimum_capture_gain_mixer_input;
44 static const struct mixer_control*
45 cras_alsa_mixer_get_maximum_capture_gain_mixer_input;
46 static size_t cras_alsa_mixer_list_outputs_called;
47 static size_t cras_alsa_mixer_list_inputs_called;
48 static size_t cras_alsa_mixer_get_control_for_section_called;
49 static struct mixer_control*
50 cras_alsa_mixer_get_control_for_section_return_value;
51 static size_t sys_get_volume_called;
52 static size_t sys_get_volume_return_value;
53 static size_t alsa_mixer_set_mute_called;
54 static int alsa_mixer_set_mute_value;
55 static size_t alsa_mixer_get_dB_range_called;
56 static long alsa_mixer_get_dB_range_value;
57 static size_t alsa_mixer_get_output_dB_range_called;
58 static long alsa_mixer_get_output_dB_range_value;
59 static const struct mixer_control* alsa_mixer_set_mute_output;
60 static size_t alsa_mixer_set_capture_mute_called;
61 static int alsa_mixer_set_capture_mute_value;
62 static const struct mixer_control* alsa_mixer_set_capture_mute_input;
63 static size_t sys_get_mute_called;
64 static int sys_get_mute_return_value;
65 static size_t sys_get_capture_mute_called;
66 static int sys_get_capture_mute_return_value;
67 static struct cras_alsa_mixer* fake_mixer = (struct cras_alsa_mixer*)1;
68 static struct cras_card_config* fake_config = (struct cras_card_config*)2;
69 static struct mixer_control** cras_alsa_mixer_list_outputs_outputs;
70 static size_t cras_alsa_mixer_list_outputs_outputs_length;
71 static struct mixer_control** cras_alsa_mixer_list_inputs_outputs;
72 static size_t cras_alsa_mixer_list_inputs_outputs_length;
73 static size_t cras_alsa_mixer_set_output_active_state_called;
74 static std::vector<struct mixer_control*>
75 cras_alsa_mixer_set_output_active_state_outputs;
76 static std::vector<int> cras_alsa_mixer_set_output_active_state_values;
77 static cras_audio_format* fake_format;
78 static size_t sys_set_volume_limits_called;
79 static size_t cras_alsa_mixer_get_minimum_capture_gain_called;
80 static size_t cras_alsa_mixer_get_maximum_capture_gain_called;
81 static struct mixer_control* cras_alsa_jack_get_mixer_output_ret;
82 static struct mixer_control* cras_alsa_jack_get_mixer_input_ret;
83 static size_t cras_alsa_mixer_get_output_volume_curve_called;
84 typedef std::map<const struct mixer_control*, std::string> ControlNameMap;
85 static ControlNameMap cras_alsa_mixer_get_control_name_values;
86 static size_t cras_alsa_mixer_get_control_name_called;
87 static size_t cras_alsa_jack_list_create_called;
88 static size_t cras_alsa_jack_list_find_jacks_by_name_matching_called;
89 static size_t cras_alsa_jack_list_add_jack_for_section_called;
90 static struct cras_alsa_jack*
91 cras_alsa_jack_list_add_jack_for_section_result_jack;
92 static size_t cras_alsa_jack_list_destroy_called;
93 static int cras_alsa_jack_list_has_hctl_jacks_return_val;
94 static jack_state_change_callback* cras_alsa_jack_list_create_cb;
95 static void* cras_alsa_jack_list_create_cb_data;
96 static char test_card_name[] = "TestCard";
97 static char test_pcm_name[] = "TestPCM";
98 static char test_dev_name[] = "TestDev";
99 static char test_dev_id[] = "TestDevId";
100 static size_t cras_iodev_add_node_called;
101 static struct cras_ionode* cras_iodev_set_node_plugged_ionode;
102 static size_t cras_iodev_set_node_plugged_called;
103 static int cras_iodev_set_node_plugged_value;
104 static unsigned cras_alsa_jack_enable_ucm_called;
105 static unsigned ucm_set_enabled_called;
106 static size_t cras_iodev_update_dsp_called;
107 static const char* cras_iodev_update_dsp_name;
108 typedef std::map<const char*, std::string> DspNameMap;
109 static size_t ucm_get_dsp_name_for_dev_called;
110 static DspNameMap ucm_get_dsp_name_for_dev_values;
111 static size_t cras_iodev_free_resources_called;
112 static size_t cras_alsa_jack_update_node_type_called;
113 static int ucm_swap_mode_exists_ret_value;
114 static int ucm_enable_swap_mode_ret_value;
115 static size_t ucm_enable_swap_mode_called;
116 static int is_utf8_string_ret_value;
117 static const char* cras_alsa_jack_update_monitor_fake_name = 0;
118 static int cras_alsa_jack_get_name_called;
119 static const char* cras_alsa_jack_get_name_ret_value = 0;
120 static char default_jack_name[] = "Something Jack";
121 static int auto_unplug_input_node_ret = 0;
122 static int auto_unplug_output_node_ret = 0;
123 static long cras_alsa_mixer_get_minimum_capture_gain_ret_value;
124 static long cras_alsa_mixer_get_maximum_capture_gain_ret_value;
125 static snd_pcm_state_t snd_pcm_state_ret;
126 static int cras_alsa_attempt_resume_called;
127 static snd_hctl_t* fake_hctl = (snd_hctl_t*)2;
128 static size_t ucm_get_dma_period_for_dev_called;
129 static unsigned int ucm_get_dma_period_for_dev_ret;
130 static int cras_card_config_get_volume_curve_for_control_called;
131 typedef std::map<std::string, struct cras_volume_curve*> VolCurveMap;
132 static VolCurveMap cras_card_config_get_volume_curve_vals;
133 static int cras_alsa_mmap_get_whole_buffer_called;
134 static int cras_iodev_fill_odev_zeros_called;
135 static unsigned int cras_iodev_fill_odev_zeros_frames;
136 static int cras_iodev_frames_queued_ret;
137 static int cras_iodev_buffer_avail_ret;
138 static int cras_alsa_resume_appl_ptr_called;
139 static int cras_alsa_resume_appl_ptr_ahead;
140 static const struct cras_volume_curve* fake_get_dBFS_volume_curve_val;
141 static int cras_iodev_dsp_set_swap_mode_for_node_called;
142 static std::map<std::string, long> ucm_get_default_node_gain_values;
143 static std::map<std::string, long> ucm_get_intrinsic_sensitivity_values;
144 static thread_callback audio_thread_cb;
145 static void* audio_thread_cb_data;
146 static int hotword_send_triggered_msg_called;
147 static struct timespec clock_gettime_retspec;
148 static unsigned cras_iodev_reset_rate_estimator_called;
149
ResetStubData()150 void ResetStubData() {
151 cras_alsa_open_called = 0;
152 cras_iodev_append_stream_ret = 0;
153 cras_alsa_get_avail_frames_ret = 0;
154 cras_alsa_get_avail_frames_avail = 0;
155 cras_alsa_start_called = 0;
156 cras_alsa_fill_properties_called = 0;
157 cras_alsa_support_8_channels = false;
158 sys_get_volume_called = 0;
159 alsa_mixer_set_dBFS_called = 0;
160 alsa_mixer_set_capture_dBFS_called = 0;
161 sys_get_mute_called = 0;
162 sys_get_capture_mute_called = 0;
163 alsa_mixer_set_mute_called = 0;
164 alsa_mixer_get_dB_range_called = 0;
165 alsa_mixer_get_output_dB_range_called = 0;
166 alsa_mixer_set_capture_mute_called = 0;
167 cras_alsa_mixer_get_control_for_section_called = 0;
168 cras_alsa_mixer_get_control_for_section_return_value = NULL;
169 cras_alsa_mixer_list_outputs_called = 0;
170 cras_alsa_mixer_list_outputs_outputs_length = 0;
171 cras_alsa_mixer_list_inputs_called = 0;
172 cras_alsa_mixer_list_inputs_outputs_length = 0;
173 cras_alsa_mixer_set_output_active_state_called = 0;
174 cras_alsa_mixer_set_output_active_state_outputs.clear();
175 cras_alsa_mixer_set_output_active_state_values.clear();
176 sys_set_volume_limits_called = 0;
177 cras_alsa_mixer_get_minimum_capture_gain_called = 0;
178 cras_alsa_mixer_get_maximum_capture_gain_called = 0;
179 cras_alsa_mixer_get_output_volume_curve_called = 0;
180 cras_alsa_jack_get_mixer_output_ret = NULL;
181 cras_alsa_jack_get_mixer_input_ret = NULL;
182 cras_alsa_mixer_get_control_name_values.clear();
183 cras_alsa_mixer_get_control_name_called = 0;
184 cras_alsa_jack_list_create_called = 0;
185 cras_alsa_jack_list_find_jacks_by_name_matching_called = 0;
186 cras_alsa_jack_list_add_jack_for_section_called = 0;
187 cras_alsa_jack_list_add_jack_for_section_result_jack = NULL;
188 cras_alsa_jack_list_destroy_called = 0;
189 cras_alsa_jack_list_has_hctl_jacks_return_val = 1;
190 cras_iodev_add_node_called = 0;
191 cras_iodev_set_node_plugged_called = 0;
192 cras_alsa_jack_enable_ucm_called = 0;
193 ucm_set_enabled_called = 0;
194 cras_iodev_update_dsp_called = 0;
195 cras_iodev_update_dsp_name = 0;
196 ucm_get_dsp_name_for_dev_called = 0;
197 ucm_get_dsp_name_for_dev_values.clear();
198 cras_iodev_free_resources_called = 0;
199 cras_alsa_jack_update_node_type_called = 0;
200 ucm_swap_mode_exists_ret_value = 0;
201 ucm_enable_swap_mode_ret_value = 0;
202 ucm_enable_swap_mode_called = 0;
203 is_utf8_string_ret_value = 1;
204 cras_alsa_jack_get_name_called = 0;
205 cras_alsa_jack_get_name_ret_value = default_jack_name;
206 cras_alsa_jack_update_monitor_fake_name = 0;
207 cras_card_config_get_volume_curve_for_control_called = 0;
208 cras_card_config_get_volume_curve_vals.clear();
209 cras_alsa_mixer_get_minimum_capture_gain_ret_value = 0;
210 cras_alsa_mixer_get_maximum_capture_gain_ret_value = 0;
211 snd_pcm_state_ret = SND_PCM_STATE_RUNNING;
212 cras_alsa_attempt_resume_called = 0;
213 ucm_get_dma_period_for_dev_called = 0;
214 ucm_get_dma_period_for_dev_ret = 0;
215 cras_alsa_mmap_get_whole_buffer_called = 0;
216 cras_iodev_fill_odev_zeros_called = 0;
217 cras_iodev_fill_odev_zeros_frames = 0;
218 cras_iodev_frames_queued_ret = 0;
219 cras_iodev_buffer_avail_ret = 0;
220 cras_alsa_resume_appl_ptr_called = 0;
221 cras_alsa_resume_appl_ptr_ahead = 0;
222 fake_get_dBFS_volume_curve_val = NULL;
223 cras_iodev_dsp_set_swap_mode_for_node_called = 0;
224 ucm_get_default_node_gain_values.clear();
225 ucm_get_intrinsic_sensitivity_values.clear();
226 cras_iodev_reset_rate_estimator_called = 0;
227 }
228
fake_get_dBFS(const struct cras_volume_curve * curve,size_t volume)229 static long fake_get_dBFS(const struct cras_volume_curve* curve,
230 size_t volume) {
231 fake_get_dBFS_volume_curve_val = curve;
232 return (volume - 100) * 100;
233 }
234 static cras_volume_curve default_curve = {
235 .get_dBFS = fake_get_dBFS,
236 };
237
alsa_iodev_create_with_default_parameters(size_t card_index,const char * dev_id,enum CRAS_ALSA_CARD_TYPE card_type,int is_first,struct cras_alsa_mixer * mixer,struct cras_card_config * config,struct cras_use_case_mgr * ucm,enum CRAS_STREAM_DIRECTION direction)238 static struct cras_iodev* alsa_iodev_create_with_default_parameters(
239 size_t card_index,
240 const char* dev_id,
241 enum CRAS_ALSA_CARD_TYPE card_type,
242 int is_first,
243 struct cras_alsa_mixer* mixer,
244 struct cras_card_config* config,
245 struct cras_use_case_mgr* ucm,
246 enum CRAS_STREAM_DIRECTION direction) {
247 return alsa_iodev_create(card_index, test_card_name, 0, test_pcm_name,
248 test_dev_name, dev_id, card_type, is_first, mixer,
249 config, ucm, fake_hctl, direction, 0, 0,
250 (char*)"123");
251 }
252
253 namespace {
TEST(AlsaIoInit,InitializeInvalidDirection)254 TEST(AlsaIoInit, InitializeInvalidDirection) {
255 struct alsa_io* aio;
256
257 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
258 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
259 CRAS_NUM_DIRECTIONS);
260 ASSERT_EQ(aio, (void*)NULL);
261 }
262
TEST(AlsaIoInit,InitializePlayback)263 TEST(AlsaIoInit, InitializePlayback) {
264 struct alsa_io* aio;
265 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
266
267 ResetStubData();
268 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
269 0, test_dev_id, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
270 CRAS_STREAM_OUTPUT);
271 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
272 /* Get volume curve twice for iodev, and default node. */
273 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
274 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
275 /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
276 EXPECT_EQ(1, cras_alsa_fill_properties_called);
277 EXPECT_EQ(1, cras_alsa_mixer_list_outputs_called);
278 EXPECT_EQ(
279 0, strncmp(test_card_name, aio->base.info.name, strlen(test_card_name)));
280 EXPECT_EQ(1, cras_iodev_update_dsp_called);
281 EXPECT_EQ("", cras_iodev_update_dsp_name);
282 ASSERT_NE(reinterpret_cast<const char*>(NULL), aio->dev_name);
283 EXPECT_EQ(0, strcmp(test_dev_name, aio->dev_name));
284 ASSERT_NE(reinterpret_cast<const char*>(NULL), aio->dev_id);
285 EXPECT_EQ(0, strcmp(test_dev_id, aio->dev_id));
286
287 alsa_iodev_destroy((struct cras_iodev*)aio);
288 EXPECT_EQ(1, cras_iodev_free_resources_called);
289 }
290
TEST(AlsaIoInit,DefaultNodeInternalCard)291 TEST(AlsaIoInit, DefaultNodeInternalCard) {
292 struct alsa_io* aio;
293 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
294
295 ResetStubData();
296 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
297 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
298 CRAS_STREAM_OUTPUT);
299 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
300 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
301 ASSERT_STREQ(DEFAULT, aio->base.active_node->name);
302 ASSERT_EQ(1, aio->base.active_node->plugged);
303 ASSERT_EQ((void*)no_stream, (void*)aio->base.no_stream);
304 ASSERT_EQ((void*)is_free_running, (void*)aio->base.is_free_running);
305 alsa_iodev_destroy((struct cras_iodev*)aio);
306
307 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
308 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
309 CRAS_STREAM_OUTPUT);
310 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
311 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
312 ASSERT_STREQ(INTERNAL_SPEAKER, aio->base.active_node->name);
313 ASSERT_EQ(1, aio->base.active_node->plugged);
314 ASSERT_EQ((void*)no_stream, (void*)aio->base.no_stream);
315 ASSERT_EQ((void*)is_free_running, (void*)aio->base.is_free_running);
316 alsa_iodev_destroy((struct cras_iodev*)aio);
317
318 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
319 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
320 CRAS_STREAM_INPUT);
321 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
322 /* No more call to get volume curve for input device. */
323 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
324 ASSERT_STREQ(DEFAULT, aio->base.active_node->name);
325 ASSERT_EQ(1, aio->base.active_node->plugged);
326 ASSERT_EQ((void*)no_stream, (void*)aio->base.no_stream);
327 ASSERT_EQ((void*)is_free_running, (void*)aio->base.is_free_running);
328 alsa_iodev_destroy((struct cras_iodev*)aio);
329
330 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
331 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
332 CRAS_STREAM_INPUT);
333 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
334 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
335 ASSERT_STREQ(INTERNAL_MICROPHONE, aio->base.active_node->name);
336 ASSERT_EQ(1, aio->base.active_node->plugged);
337 ASSERT_EQ((void*)no_stream, (void*)aio->base.no_stream);
338 ASSERT_EQ((void*)is_free_running, (void*)aio->base.is_free_running);
339 alsa_iodev_destroy((struct cras_iodev*)aio);
340 }
341
TEST(AlsaIoInit,DefaultNodeUSBCard)342 TEST(AlsaIoInit, DefaultNodeUSBCard) {
343 struct alsa_io* aio;
344 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
345
346 ResetStubData();
347 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
348 0, NULL, ALSA_CARD_TYPE_USB, 1, fake_mixer, fake_config, NULL,
349 CRAS_STREAM_OUTPUT);
350 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
351 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
352 ASSERT_STREQ(DEFAULT, aio->base.active_node->name);
353 ASSERT_EQ(1, aio->base.active_node->plugged);
354 EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
355 alsa_iodev_destroy((struct cras_iodev*)aio);
356
357 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
358 0, NULL, ALSA_CARD_TYPE_USB, 1, fake_mixer, fake_config, NULL,
359 CRAS_STREAM_INPUT);
360 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
361 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
362 ASSERT_STREQ(DEFAULT, aio->base.active_node->name);
363 ASSERT_EQ(1, aio->base.active_node->plugged);
364 EXPECT_EQ(2, cras_iodev_set_node_plugged_called);
365
366 /* No extra gain applied. */
367 ASSERT_EQ(DEFAULT_CAPTURE_VOLUME_DBFS,
368 aio->base.active_node->intrinsic_sensitivity);
369 ASSERT_EQ(0, aio->base.active_node->capture_gain);
370 alsa_iodev_destroy((struct cras_iodev*)aio);
371 }
372
TEST(AlsaIoInit,OpenPlayback)373 TEST(AlsaIoInit, OpenPlayback) {
374 struct cras_iodev* iodev;
375 struct cras_audio_format format;
376 struct alsa_io* aio;
377
378 ResetStubData();
379 iodev = alsa_iodev_create_with_default_parameters(
380 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
381 CRAS_STREAM_OUTPUT);
382 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
383 /* Call open_dev once on update_max_supported_channels. */
384 EXPECT_EQ(1, cras_alsa_open_called);
385 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
386 aio = (struct alsa_io*)iodev;
387 format.frame_rate = 48000;
388 format.num_channels = 1;
389 cras_iodev_set_format(iodev, &format);
390
391 // Test that these flags are cleared after open_dev.
392 aio->free_running = 1;
393 aio->filled_zeros_for_draining = 512;
394 iodev->open_dev(iodev);
395 EXPECT_EQ(2, cras_alsa_open_called);
396 iodev->configure_dev(iodev);
397 EXPECT_EQ(2, cras_alsa_open_called);
398 EXPECT_EQ(1, sys_set_volume_limits_called);
399 EXPECT_EQ(1, alsa_mixer_set_dBFS_called);
400 EXPECT_EQ(0, cras_alsa_start_called);
401 EXPECT_EQ(0, cras_iodev_set_node_plugged_called);
402 EXPECT_EQ(0, aio->free_running);
403 EXPECT_EQ(0, aio->filled_zeros_for_draining);
404 EXPECT_EQ(SEVERE_UNDERRUN_MS * format.frame_rate / 1000,
405 aio->severe_underrun_frames);
406
407 alsa_iodev_destroy(iodev);
408 free(fake_format);
409 }
410
TEST(AlsaIoInit,UsbCardAutoPlug)411 TEST(AlsaIoInit, UsbCardAutoPlug) {
412 struct cras_iodev* iodev;
413
414 ResetStubData();
415 iodev = alsa_iodev_create_with_default_parameters(
416 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
417 CRAS_STREAM_OUTPUT);
418 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
419 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
420 EXPECT_EQ(0, cras_iodev_set_node_plugged_called);
421 alsa_iodev_destroy(iodev);
422
423 ResetStubData();
424 iodev = alsa_iodev_create_with_default_parameters(0, NULL, ALSA_CARD_TYPE_USB,
425 0, fake_mixer, fake_config,
426 NULL, CRAS_STREAM_OUTPUT);
427 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
428 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
429 EXPECT_EQ(0, cras_iodev_set_node_plugged_called);
430 alsa_iodev_destroy(iodev);
431
432 ResetStubData();
433 iodev = alsa_iodev_create_with_default_parameters(0, NULL, ALSA_CARD_TYPE_USB,
434 1, fake_mixer, fake_config,
435 NULL, CRAS_STREAM_OUTPUT);
436 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
437 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
438 // Should assume USB devs are plugged when they appear.
439 EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
440 EXPECT_EQ(1, iodev->active_node->plugged);
441 alsa_iodev_destroy(iodev);
442 }
443
TEST(AlsaIoInit,UsbCardUseSoftwareVolume)444 TEST(AlsaIoInit, UsbCardUseSoftwareVolume) {
445 struct cras_iodev* iodev;
446
447 alsa_mixer_get_dB_range_value = 1000;
448 alsa_mixer_get_output_dB_range_value = 1000;
449 ResetStubData();
450 iodev = alsa_iodev_create_with_default_parameters(0, NULL, ALSA_CARD_TYPE_USB,
451 1, fake_mixer, fake_config,
452 NULL, CRAS_STREAM_OUTPUT);
453 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
454 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
455 EXPECT_EQ(1, alsa_mixer_get_dB_range_called);
456 EXPECT_EQ(1, alsa_mixer_get_output_dB_range_called);
457 EXPECT_EQ(1, iodev->active_node->software_volume_needed);
458 alsa_iodev_destroy(iodev);
459
460 alsa_mixer_get_dB_range_value = 3000;
461 alsa_mixer_get_output_dB_range_value = 2000;
462 ResetStubData();
463 iodev = alsa_iodev_create_with_default_parameters(0, NULL, ALSA_CARD_TYPE_USB,
464 1, fake_mixer, fake_config,
465 NULL, CRAS_STREAM_OUTPUT);
466 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
467 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
468 EXPECT_EQ(1, alsa_mixer_get_dB_range_called);
469 EXPECT_EQ(1, alsa_mixer_get_output_dB_range_called);
470 EXPECT_EQ(0, iodev->active_node->software_volume_needed);
471 alsa_iodev_destroy(iodev);
472 }
473
TEST(AlsaIoInit,SoftwareGainIntrinsicSensitivity)474 TEST(AlsaIoInit, SoftwareGainIntrinsicSensitivity) {
475 struct cras_iodev* iodev;
476 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
477 long intrinsic_sensitivity = -2700;
478
479 ResetStubData();
480
481 // Set intrinsic sensitivity to -2700 * 0.01 dBFS/Pa.
482 ucm_get_intrinsic_sensitivity_values[INTERNAL_MICROPHONE] =
483 intrinsic_sensitivity;
484
485 // Assume this is the first device so it gets internal mic node name.
486 iodev = alsa_iodev_create_with_default_parameters(
487 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
488 CRAS_STREAM_INPUT);
489 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
490 ASSERT_EQ(intrinsic_sensitivity, iodev->active_node->intrinsic_sensitivity);
491 ASSERT_EQ(DEFAULT_CAPTURE_VOLUME_DBFS - intrinsic_sensitivity,
492 iodev->active_node->capture_gain);
493
494 alsa_iodev_destroy(iodev);
495 }
496
TEST(AlsaIoInit,RouteBasedOnJackCallback)497 TEST(AlsaIoInit, RouteBasedOnJackCallback) {
498 struct alsa_io* aio;
499 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
500
501 ResetStubData();
502 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
503 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
504 CRAS_STREAM_OUTPUT);
505 ASSERT_NE(aio, (void*)NULL);
506 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
507 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
508 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
509 /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
510 EXPECT_EQ(1, cras_alsa_fill_properties_called);
511 EXPECT_EQ(1, cras_alsa_mixer_list_outputs_called);
512 EXPECT_EQ(1, cras_alsa_jack_list_create_called);
513 EXPECT_EQ(1, cras_alsa_jack_list_find_jacks_by_name_matching_called);
514 EXPECT_EQ(0, cras_alsa_jack_list_add_jack_for_section_called);
515
516 cras_alsa_jack_list_create_cb(NULL, 1, cras_alsa_jack_list_create_cb_data);
517 EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
518 EXPECT_EQ(1, cras_iodev_set_node_plugged_value);
519 cras_alsa_jack_list_create_cb(NULL, 0, cras_alsa_jack_list_create_cb_data);
520 EXPECT_EQ(2, cras_iodev_set_node_plugged_called);
521 EXPECT_EQ(0, cras_iodev_set_node_plugged_value);
522
523 alsa_iodev_destroy((struct cras_iodev*)aio);
524 EXPECT_EQ(1, cras_alsa_jack_list_destroy_called);
525 }
526
TEST(AlsaIoInit,RouteBasedOnInputJackCallback)527 TEST(AlsaIoInit, RouteBasedOnInputJackCallback) {
528 struct alsa_io* aio;
529 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
530
531 ResetStubData();
532 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
533 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
534 CRAS_STREAM_INPUT);
535 ASSERT_NE(aio, (void*)NULL);
536 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
537
538 EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
539 /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
540 EXPECT_EQ(1, cras_alsa_fill_properties_called);
541 EXPECT_EQ(1, cras_alsa_jack_list_create_called);
542 EXPECT_EQ(1, cras_alsa_jack_list_find_jacks_by_name_matching_called);
543 EXPECT_EQ(0, cras_alsa_jack_list_add_jack_for_section_called);
544
545 cras_alsa_jack_list_create_cb(NULL, 1, cras_alsa_jack_list_create_cb_data);
546 EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
547 EXPECT_EQ(1, cras_iodev_set_node_plugged_value);
548 cras_alsa_jack_list_create_cb(NULL, 0, cras_alsa_jack_list_create_cb_data);
549 EXPECT_EQ(2, cras_iodev_set_node_plugged_called);
550 EXPECT_EQ(0, cras_iodev_set_node_plugged_value);
551
552 alsa_iodev_destroy((struct cras_iodev*)aio);
553 EXPECT_EQ(1, cras_alsa_jack_list_destroy_called);
554 }
555
TEST(AlsaIoInit,InitializeCapture)556 TEST(AlsaIoInit, InitializeCapture) {
557 struct alsa_io* aio;
558
559 ResetStubData();
560 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
561 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
562 CRAS_STREAM_INPUT);
563 ASSERT_NE(aio, (void*)NULL);
564 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
565
566 EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
567 /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
568 EXPECT_EQ(1, cras_alsa_fill_properties_called);
569 EXPECT_EQ(1, cras_alsa_mixer_list_inputs_called);
570
571 alsa_iodev_destroy((struct cras_iodev*)aio);
572 }
573
TEST(AlsaIoInit,OpenCapture)574 TEST(AlsaIoInit, OpenCapture) {
575 struct cras_iodev* iodev;
576 struct cras_audio_format format;
577 struct alsa_io* aio;
578
579 iodev = alsa_iodev_create_with_default_parameters(
580 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
581 CRAS_STREAM_INPUT);
582 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
583
584 aio = (struct alsa_io*)iodev;
585 format.frame_rate = 48000;
586 format.num_channels = 1;
587 cras_iodev_set_format(iodev, &format);
588
589 ResetStubData();
590 iodev->open_dev(iodev);
591 EXPECT_EQ(1, cras_alsa_open_called);
592 iodev->configure_dev(iodev);
593 EXPECT_EQ(1, cras_alsa_open_called);
594 EXPECT_EQ(1, cras_alsa_mixer_get_minimum_capture_gain_called);
595 EXPECT_EQ(1, cras_alsa_mixer_get_maximum_capture_gain_called);
596 EXPECT_EQ(1, alsa_mixer_set_capture_dBFS_called);
597 EXPECT_EQ(1, sys_get_capture_mute_called);
598 EXPECT_EQ(1, alsa_mixer_set_capture_mute_called);
599 EXPECT_EQ(1, cras_alsa_start_called);
600 EXPECT_EQ(SEVERE_UNDERRUN_MS * format.frame_rate / 1000,
601 aio->severe_underrun_frames);
602
603 alsa_iodev_destroy(iodev);
604 free(fake_format);
605 }
606
TEST(AlsaIoInit,OpenCaptureSetCaptureGainWithDefaultNodeGain)607 TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithDefaultNodeGain) {
608 struct cras_iodev* iodev;
609 struct cras_audio_format format;
610 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
611 long default_node_gain = 1000;
612
613 ResetStubData();
614 // Set default node gain to -1000 * 0.01 dB.
615 ucm_get_default_node_gain_values[INTERNAL_MICROPHONE] = default_node_gain;
616
617 // Assume this is the first device so it gets internal mic node name.
618 iodev = alsa_iodev_create_with_default_parameters(
619 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
620 CRAS_STREAM_INPUT);
621 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
622
623 cras_iodev_set_format(iodev, &format);
624
625 // Check the default node gain is the same as what specified in UCM.
626 EXPECT_EQ(default_node_gain, iodev->active_node->capture_gain);
627 cras_alsa_mixer_get_minimum_capture_gain_ret_value = 0;
628 cras_alsa_mixer_get_maximum_capture_gain_ret_value = 2000;
629
630 iodev->open_dev(iodev);
631 iodev->configure_dev(iodev);
632 iodev->close_dev(iodev);
633
634 // Hardware gain is in the hardware gain range and set to 1000 * 0.01 dB.
635 EXPECT_EQ(default_node_gain, alsa_mixer_set_capture_dBFS_value);
636
637 // Check we do respect the hardware maximum capture gain.
638 cras_alsa_mixer_get_maximum_capture_gain_ret_value = 500;
639
640 iodev->open_dev(iodev);
641 iodev->configure_dev(iodev);
642 iodev->close_dev(iodev);
643
644 EXPECT_EQ(500, alsa_mixer_set_capture_dBFS_value);
645
646 alsa_iodev_destroy(iodev);
647 free(fake_format);
648 }
649
TEST(AlsaIoInit,OpenCaptureSetCaptureGainWithSoftwareGain)650 TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithSoftwareGain) {
651 struct cras_iodev* iodev;
652 struct cras_audio_format format;
653 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
654
655 /* Meet the requirements of using software gain. */
656 ResetStubData();
657
658 iodev = alsa_iodev_create_with_default_parameters(
659 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
660 CRAS_STREAM_INPUT);
661 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
662
663 format.frame_rate = 48000;
664 format.num_channels = 1;
665 cras_iodev_set_format(iodev, &format);
666
667 iodev->open_dev(iodev);
668 iodev->configure_dev(iodev);
669 iodev->close_dev(iodev);
670
671 /* Hardware gain is set to 0dB when software gain is used. */
672 EXPECT_EQ(0, alsa_mixer_set_capture_dBFS_value);
673
674 /* Test the case where software gain is not needed. */
675 iodev->active_node->software_volume_needed = 0;
676 iodev->active_node->capture_gain = 1000;
677 iodev->open_dev(iodev);
678 iodev->configure_dev(iodev);
679 iodev->close_dev(iodev);
680
681 /* Hardware gain is set to 1000 * 0.01 dB as got from catpure_gain.*/
682 EXPECT_EQ(0, alsa_mixer_set_capture_dBFS_value);
683
684 alsa_iodev_destroy(iodev);
685 free(fake_format);
686 }
687
TEST(AlsaIoInit,OpenCaptureSetCaptureGainWithDefaultUsbDevice)688 TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithDefaultUsbDevice) {
689 struct cras_iodev* iodev;
690 struct cras_audio_format format;
691
692 iodev = alsa_iodev_create_with_default_parameters(0, NULL, ALSA_CARD_TYPE_USB,
693 0, fake_mixer, fake_config,
694 NULL, CRAS_STREAM_INPUT);
695 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
696
697 format.frame_rate = 48000;
698 format.num_channels = 1;
699 cras_iodev_set_format(iodev, &format);
700
701 iodev->active_node->intrinsic_sensitivity = DEFAULT_CAPTURE_VOLUME_DBFS;
702 iodev->active_node->capture_gain = 0;
703
704 ResetStubData();
705 iodev->open_dev(iodev);
706 iodev->configure_dev(iodev);
707
708 EXPECT_EQ(1, sys_get_capture_mute_called);
709 EXPECT_EQ(1, alsa_mixer_set_capture_mute_called);
710
711 /* Not change mixer controls for USB devices without UCM config. */
712 EXPECT_EQ(0, alsa_mixer_set_capture_dBFS_called);
713
714 alsa_iodev_destroy(iodev);
715 free(fake_format);
716 }
717
TEST(AlsaIoInit,UpdateActiveNode)718 TEST(AlsaIoInit, UpdateActiveNode) {
719 struct cras_iodev* iodev;
720 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
721
722 ResetStubData();
723 iodev = alsa_iodev_create_with_default_parameters(
724 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
725 CRAS_STREAM_OUTPUT);
726 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
727 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
728
729 iodev->update_active_node(iodev, 0, 1);
730
731 alsa_iodev_destroy(iodev);
732 }
733
TEST(AlsaIoInit,StartDevice)734 TEST(AlsaIoInit, StartDevice) {
735 struct cras_iodev* iodev;
736 int rc;
737
738 ResetStubData();
739 iodev = alsa_iodev_create_with_default_parameters(
740 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, NULL, fake_config, NULL,
741 CRAS_STREAM_OUTPUT);
742 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
743 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
744
745 // Return right away if it is already running.
746 snd_pcm_state_ret = SND_PCM_STATE_RUNNING;
747 rc = iodev->start(iodev);
748 EXPECT_EQ(0, rc);
749 EXPECT_EQ(0, cras_alsa_start_called);
750
751 // Otherwise, start the device.
752 snd_pcm_state_ret = SND_PCM_STATE_SETUP;
753 rc = iodev->start(iodev);
754 EXPECT_EQ(0, rc);
755 EXPECT_EQ(1, cras_alsa_start_called);
756
757 alsa_iodev_destroy(iodev);
758 }
759
TEST(AlsaIoInit,ResumeDevice)760 TEST(AlsaIoInit, ResumeDevice) {
761 struct cras_iodev* iodev;
762 int rc;
763
764 ResetStubData();
765 iodev = alsa_iodev_create_with_default_parameters(
766 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, NULL, fake_config, NULL,
767 CRAS_STREAM_OUTPUT);
768 ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
769 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
770
771 // Attempt to resume if the device is suspended.
772 snd_pcm_state_ret = SND_PCM_STATE_SUSPENDED;
773 rc = iodev->start(iodev);
774 EXPECT_EQ(0, rc);
775 EXPECT_EQ(1, cras_alsa_attempt_resume_called);
776
777 alsa_iodev_destroy(iodev);
778 }
779
TEST(AlsaIoInit,DspNameDefault)780 TEST(AlsaIoInit, DspNameDefault) {
781 struct alsa_io* aio;
782 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
783 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
784
785 ResetStubData();
786 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
787 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
788 CRAS_STREAM_OUTPUT);
789 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
790 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
791 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
792 EXPECT_EQ(1, ucm_get_dsp_name_for_dev_called);
793 EXPECT_STREQ("", cras_iodev_update_dsp_name);
794
795 alsa_iodev_destroy((struct cras_iodev*)aio);
796 }
797
TEST(AlsaIoInit,DspName)798 TEST(AlsaIoInit, DspName) {
799 struct alsa_io* aio;
800 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
801 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
802
803 ResetStubData();
804 ucm_get_dsp_name_for_dev_values[DEFAULT] = "hello";
805 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
806 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
807 CRAS_STREAM_OUTPUT);
808 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
809 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
810 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
811 EXPECT_EQ(1, ucm_get_dsp_name_for_dev_called);
812 EXPECT_STREQ("hello", cras_iodev_update_dsp_name);
813
814 alsa_iodev_destroy((struct cras_iodev*)aio);
815 }
816
TEST(AlsaIoInit,DspNameJackOverride)817 TEST(AlsaIoInit, DspNameJackOverride) {
818 struct alsa_io* aio;
819 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
820 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
821 const struct cras_alsa_jack* jack = (struct cras_alsa_jack*)4;
822 static const char* jack_name = "jack";
823
824 ResetStubData();
825 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
826 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
827 CRAS_STREAM_OUTPUT);
828 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
829 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
830 EXPECT_EQ(1, ucm_get_dsp_name_for_dev_called);
831 EXPECT_EQ(1, cras_iodev_update_dsp_called);
832 EXPECT_STREQ("", cras_iodev_update_dsp_name);
833
834 cras_alsa_jack_get_name_ret_value = jack_name;
835 ucm_get_dsp_name_for_dev_values[jack_name] = "override_dsp";
836 // Add the jack node.
837 cras_alsa_jack_list_create_cb(jack, 1, cras_alsa_jack_list_create_cb_data);
838 EXPECT_EQ(2, cras_alsa_jack_get_name_called);
839 EXPECT_EQ(2, ucm_get_dsp_name_for_dev_called);
840
841 // Mark the jack node as active.
842 alsa_iodev_set_active_node(&aio->base, aio->base.nodes->next, 1);
843 EXPECT_EQ(2, ucm_get_dsp_name_for_dev_called);
844 EXPECT_EQ(2, cras_iodev_update_dsp_called);
845 EXPECT_STREQ("override_dsp", cras_iodev_update_dsp_name);
846
847 // Mark the default node as active.
848 alsa_iodev_set_active_node(&aio->base, aio->base.nodes, 1);
849 EXPECT_EQ(2, ucm_get_dsp_name_for_dev_called);
850 EXPECT_EQ(3, cras_iodev_update_dsp_called);
851 EXPECT_STREQ("", cras_iodev_update_dsp_name);
852
853 alsa_iodev_destroy((struct cras_iodev*)aio);
854 }
855
TEST(AlsaIoInit,NodeTypeOverride)856 TEST(AlsaIoInit, NodeTypeOverride) {
857 struct alsa_io* aio;
858 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
859 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
860 const struct cras_alsa_jack* jack = (struct cras_alsa_jack*)4;
861
862 ResetStubData();
863 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
864 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
865 CRAS_STREAM_OUTPUT);
866 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
867 // Add the jack node.
868 cras_alsa_jack_list_create_cb(jack, 1, cras_alsa_jack_list_create_cb_data);
869 // Verify that cras_alsa_jack_update_node_type is called when an output device
870 // is created.
871 EXPECT_EQ(1, cras_alsa_jack_update_node_type_called);
872
873 alsa_iodev_destroy((struct cras_iodev*)aio);
874 }
875
TEST(AlsaIoInit,SwapMode)876 TEST(AlsaIoInit, SwapMode) {
877 struct alsa_io* aio;
878 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
879 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
880 struct cras_ionode* const fake_node =
881 (cras_ionode*)calloc(1, sizeof(struct cras_ionode));
882 ResetStubData();
883 // Stub replies that swap mode does not exist.
884 ucm_swap_mode_exists_ret_value = 0;
885
886 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
887 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
888 CRAS_STREAM_OUTPUT);
889 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
890
891 aio->base.set_swap_mode_for_node((cras_iodev*)aio, fake_node, 1);
892 /* Swap mode is implemented by dsp. */
893 EXPECT_EQ(1, cras_iodev_dsp_set_swap_mode_for_node_called);
894
895 // Stub replies that swap mode exists.
896 ucm_swap_mode_exists_ret_value = 1;
897 alsa_iodev_destroy((struct cras_iodev*)aio);
898
899 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
900 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
901 CRAS_STREAM_OUTPUT);
902 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
903 // Enable swap mode.
904 aio->base.set_swap_mode_for_node((cras_iodev*)aio, fake_node, 1);
905
906 // Verify that ucm_enable_swap_mode is called when callback to enable
907 // swap mode is called.
908 EXPECT_EQ(1, ucm_enable_swap_mode_called);
909
910 alsa_iodev_destroy((struct cras_iodev*)aio);
911 free(fake_node);
912 }
913
TEST(AlsaIoInit,MaxSupportedChannels)914 TEST(AlsaIoInit, MaxSupportedChannels) {
915 struct alsa_io* aio;
916 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
917 int i;
918
919 // i = 0: cras_alsa_support_8_channels is false, support 2 channels only.
920 // i = 1: cras_alsa_support_8_channels is true, support up to 8 channels.
921 for (i = 0; i < 2; i++) {
922 ResetStubData();
923 cras_alsa_support_8_channels = (bool)i;
924
925 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
926 0, test_dev_id, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config,
927 NULL, CRAS_STREAM_OUTPUT);
928 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
929 /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
930 EXPECT_EQ(1, cras_alsa_fill_properties_called);
931 uint32_t max_channels = (cras_alsa_support_8_channels) ? 8 : 2;
932 EXPECT_EQ(max_channels, aio->base.info.max_supported_channels);
933 alsa_iodev_destroy((struct cras_iodev*)aio);
934 EXPECT_EQ(1, cras_iodev_free_resources_called);
935 }
936 }
937
938 // Test that system settins aren't touched if no streams active.
TEST(AlsaOutputNode,SystemSettingsWhenInactive)939 TEST(AlsaOutputNode, SystemSettingsWhenInactive) {
940 int rc;
941 struct alsa_io* aio;
942 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
943 struct mixer_control* outputs[2];
944
945 ResetStubData();
946 outputs[0] = reinterpret_cast<struct mixer_control*>(3);
947 outputs[1] = reinterpret_cast<struct mixer_control*>(4);
948 cras_alsa_mixer_list_outputs_outputs = outputs;
949 cras_alsa_mixer_list_outputs_outputs_length = ARRAY_SIZE(outputs);
950 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
951 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
952 CRAS_STREAM_OUTPUT);
953 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
954 /* Two mixer controls calls get volume curve. */
955 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
956 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
957 EXPECT_EQ(1, cras_alsa_mixer_list_outputs_called);
958
959 ResetStubData();
960 rc = alsa_iodev_set_active_node((struct cras_iodev*)aio,
961 aio->base.nodes->next, 1);
962 EXPECT_EQ(0, rc);
963 EXPECT_EQ(0, alsa_mixer_set_mute_called);
964 EXPECT_EQ(0, alsa_mixer_set_dBFS_called);
965 ASSERT_EQ(2, cras_alsa_mixer_set_output_active_state_called);
966 EXPECT_EQ(outputs[0], cras_alsa_mixer_set_output_active_state_outputs[0]);
967 EXPECT_EQ(0, cras_alsa_mixer_set_output_active_state_values[0]);
968 EXPECT_EQ(outputs[1], cras_alsa_mixer_set_output_active_state_outputs[1]);
969 EXPECT_EQ(1, cras_alsa_mixer_set_output_active_state_values[1]);
970 EXPECT_EQ(1, cras_iodev_update_dsp_called);
971 // No jack is defined, and UCM is not used.
972 EXPECT_EQ(0, cras_alsa_jack_enable_ucm_called);
973 EXPECT_EQ(0, ucm_set_enabled_called);
974
975 alsa_iodev_destroy((struct cras_iodev*)aio);
976 }
977
978 // Test handling of different amounts of outputs.
TEST(AlsaOutputNode,TwoOutputs)979 TEST(AlsaOutputNode, TwoOutputs) {
980 int rc;
981 struct alsa_io* aio;
982 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
983 struct mixer_control* outputs[2];
984
985 ResetStubData();
986 outputs[0] = reinterpret_cast<struct mixer_control*>(3);
987 outputs[1] = reinterpret_cast<struct mixer_control*>(4);
988 cras_alsa_mixer_list_outputs_outputs = outputs;
989 cras_alsa_mixer_list_outputs_outputs_length = ARRAY_SIZE(outputs);
990 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
991 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
992 CRAS_STREAM_OUTPUT);
993 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
994 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
995 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
996 EXPECT_EQ(1, cras_alsa_mixer_list_outputs_called);
997
998 aio->handle = (snd_pcm_t*)0x24;
999
1000 ResetStubData();
1001 rc = alsa_iodev_set_active_node((struct cras_iodev*)aio,
1002 aio->base.nodes->next, 1);
1003 EXPECT_EQ(0, rc);
1004 EXPECT_EQ(1, alsa_mixer_set_mute_called);
1005 EXPECT_EQ(outputs[1], alsa_mixer_set_mute_output);
1006 EXPECT_EQ(1, alsa_mixer_set_dBFS_called);
1007 EXPECT_EQ(outputs[1], alsa_mixer_set_dBFS_output);
1008 ASSERT_EQ(2, cras_alsa_mixer_set_output_active_state_called);
1009 EXPECT_EQ(outputs[0], cras_alsa_mixer_set_output_active_state_outputs[0]);
1010 EXPECT_EQ(0, cras_alsa_mixer_set_output_active_state_values[0]);
1011 EXPECT_EQ(outputs[1], cras_alsa_mixer_set_output_active_state_outputs[1]);
1012 EXPECT_EQ(1, cras_alsa_mixer_set_output_active_state_values[1]);
1013 EXPECT_EQ(1, cras_iodev_update_dsp_called);
1014 // No jacks defined, and UCM is not used.
1015 EXPECT_EQ(0, cras_alsa_jack_enable_ucm_called);
1016 EXPECT_EQ(0, ucm_set_enabled_called);
1017
1018 alsa_iodev_destroy((struct cras_iodev*)aio);
1019 }
1020
TEST(AlsaOutputNode,TwoJacksHeadphoneLineout)1021 TEST(AlsaOutputNode, TwoJacksHeadphoneLineout) {
1022 struct alsa_io* aio;
1023 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
1024 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1025 struct cras_iodev* iodev;
1026 struct mixer_control* output;
1027 struct ucm_section* section;
1028
1029 ResetStubData();
1030 output = reinterpret_cast<struct mixer_control*>(3);
1031 cras_alsa_mixer_get_control_name_values[output] = HEADPHONE;
1032
1033 // Create the iodev
1034 iodev = alsa_iodev_create_with_default_parameters(
1035 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1036 CRAS_STREAM_OUTPUT);
1037 ASSERT_NE(iodev, (void*)NULL);
1038 aio = reinterpret_cast<struct alsa_io*>(iodev);
1039 EXPECT_EQ(1, cras_card_config_get_volume_curve_for_control_called);
1040
1041 // First node 'Headphone'
1042 section = ucm_section_create(HEADPHONE, "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
1043 "fake-jack", "gpio");
1044 ucm_section_set_mixer_name(section, HEADPHONE);
1045 cras_alsa_jack_list_add_jack_for_section_result_jack =
1046 reinterpret_cast<struct cras_alsa_jack*>(10);
1047 cras_alsa_mixer_get_control_for_section_return_value = output;
1048 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1049 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
1050 ucm_section_free_list(section);
1051
1052 // Second node 'Line Out'
1053 section = ucm_section_create("Line Out", "hw:0.1", 0, -1, CRAS_STREAM_OUTPUT,
1054 "fake-jack", "gpio");
1055 ucm_section_set_mixer_name(section, HEADPHONE);
1056 cras_alsa_jack_list_add_jack_for_section_result_jack =
1057 reinterpret_cast<struct cras_alsa_jack*>(20);
1058 cras_alsa_mixer_get_control_for_section_return_value = output;
1059 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1060 EXPECT_EQ(7, cras_card_config_get_volume_curve_for_control_called);
1061 ucm_section_free_list(section);
1062
1063 // Both nodes are associated with the same mixer output. Different jack plug
1064 // report should trigger different node attribute change.
1065 cras_alsa_jack_get_mixer_output_ret = output;
1066 jack_output_plug_event(reinterpret_cast<struct cras_alsa_jack*>(10), 0, aio);
1067 EXPECT_STREQ(cras_iodev_set_node_plugged_ionode->name, HEADPHONE);
1068
1069 jack_output_plug_event(reinterpret_cast<struct cras_alsa_jack*>(20), 0, aio);
1070 EXPECT_STREQ(cras_iodev_set_node_plugged_ionode->name, "Line Out");
1071
1072 alsa_iodev_destroy(iodev);
1073 }
1074
TEST(AlsaOutputNode,MaxSupportedChannels)1075 TEST(AlsaOutputNode, MaxSupportedChannels) {
1076 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1077 struct cras_iodev* iodev;
1078 struct ucm_section* section;
1079 int i;
1080
1081 // i = 0: cras_alsa_support_8_channels is false, support 2 channels only.
1082 // i = 1: cras_alsa_support_8_channels is true, support up to 8 channels.
1083 for (i = 0; i < 2; i++) {
1084 ResetStubData();
1085 cras_alsa_support_8_channels = (bool)i;
1086
1087 // Create the IO device.
1088 iodev = alsa_iodev_create_with_default_parameters(
1089 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1090 CRAS_STREAM_OUTPUT);
1091 ASSERT_NE(iodev, (void*)NULL);
1092
1093 // Node without controls or jacks.
1094 section = ucm_section_create(INTERNAL_SPEAKER, "hw:0,1", 1, -1,
1095 CRAS_STREAM_OUTPUT, NULL, NULL);
1096 // Device index doesn't match.
1097 EXPECT_EQ(-22, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1098 section->dev_idx = 0;
1099 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1100 ucm_section_free_list(section);
1101
1102 // Complete initialization, and make first node active.
1103 alsa_iodev_ucm_complete_init(iodev);
1104 /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
1105 EXPECT_EQ(1, cras_alsa_fill_properties_called);
1106 uint32_t max_channels = (cras_alsa_support_8_channels) ? 8 : 2;
1107 EXPECT_EQ(max_channels, iodev->info.max_supported_channels);
1108 alsa_iodev_destroy(iodev);
1109 }
1110 }
1111
TEST(AlsaOutputNode,OutputsFromUCM)1112 TEST(AlsaOutputNode, OutputsFromUCM) {
1113 struct alsa_io* aio;
1114 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
1115 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1116 struct cras_iodev* iodev;
1117 static const char* jack_name = "TestCard - Headset Jack";
1118 struct mixer_control* outputs[2];
1119 int rc;
1120 struct ucm_section* section;
1121
1122 ResetStubData();
1123 outputs[0] = reinterpret_cast<struct mixer_control*>(3);
1124 outputs[1] = reinterpret_cast<struct mixer_control*>(4);
1125 cras_alsa_mixer_list_outputs_outputs = outputs;
1126 cras_alsa_mixer_list_outputs_outputs_length = ARRAY_SIZE(outputs);
1127 cras_alsa_mixer_get_control_name_values[outputs[0]] = INTERNAL_SPEAKER;
1128 cras_alsa_mixer_get_control_name_values[outputs[1]] = HEADPHONE;
1129 ucm_get_dma_period_for_dev_ret = 1000;
1130
1131 // Create the IO device.
1132 iodev = alsa_iodev_create_with_default_parameters(
1133 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1134 CRAS_STREAM_OUTPUT);
1135 ASSERT_NE(iodev, (void*)NULL);
1136 aio = reinterpret_cast<struct alsa_io*>(iodev);
1137 EXPECT_EQ(1, cras_card_config_get_volume_curve_for_control_called);
1138
1139 // First node.
1140 section = ucm_section_create(INTERNAL_SPEAKER, "hw:0,1", 0, -1,
1141 CRAS_STREAM_OUTPUT, NULL, NULL);
1142 ucm_section_set_mixer_name(section, INTERNAL_SPEAKER);
1143 cras_alsa_jack_list_add_jack_for_section_result_jack =
1144 reinterpret_cast<struct cras_alsa_jack*>(1);
1145 cras_alsa_mixer_get_control_for_section_return_value = outputs[0];
1146 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1147 ucm_section_free_list(section);
1148 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
1149
1150 // Add a second node (will use the same iodev).
1151 section = ucm_section_create(HEADPHONE, "hw:0,2", 0, -1, CRAS_STREAM_OUTPUT,
1152 jack_name, "hctl");
1153 ucm_section_add_coupled(section, "HP-L", MIXER_NAME_VOLUME);
1154 ucm_section_add_coupled(section, "HP-R", MIXER_NAME_VOLUME);
1155 cras_alsa_jack_list_add_jack_for_section_result_jack = NULL;
1156 cras_alsa_mixer_get_control_for_section_return_value = outputs[1];
1157 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1158 ucm_section_free_list(section);
1159 /* New nodes creation calls get volume curve once, NULL jack doesn't make
1160 * more calls. */
1161 EXPECT_EQ(5, cras_card_config_get_volume_curve_for_control_called);
1162
1163 // Jack plug of an unkonwn device should do nothing.
1164 cras_alsa_jack_get_mixer_output_ret = NULL;
1165 cras_alsa_jack_get_name_ret_value = "Some other jack";
1166 jack_output_plug_event(reinterpret_cast<struct cras_alsa_jack*>(4), 0, aio);
1167 EXPECT_EQ(0, cras_iodev_set_node_plugged_called);
1168
1169 // Complete initialization, and make first node active.
1170 cras_alsa_support_8_channels = false; // Support 2 channels only.
1171 alsa_iodev_ucm_complete_init(iodev);
1172 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
1173 EXPECT_EQ(2, cras_alsa_jack_list_add_jack_for_section_called);
1174 EXPECT_EQ(2, cras_alsa_mixer_get_control_for_section_called);
1175 EXPECT_EQ(1, ucm_get_dma_period_for_dev_called);
1176 EXPECT_EQ(ucm_get_dma_period_for_dev_ret, aio->dma_period_set_microsecs);
1177 /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
1178 EXPECT_EQ(1, cras_alsa_fill_properties_called);
1179 EXPECT_EQ(2, iodev->info.max_supported_channels);
1180
1181 aio->handle = (snd_pcm_t*)0x24;
1182
1183 ResetStubData();
1184 rc = alsa_iodev_set_active_node(iodev, aio->base.nodes->next, 1);
1185 EXPECT_EQ(0, rc);
1186 EXPECT_EQ(1, alsa_mixer_set_mute_called);
1187 EXPECT_EQ(outputs[1], alsa_mixer_set_mute_output);
1188 EXPECT_EQ(1, alsa_mixer_set_dBFS_called);
1189 EXPECT_EQ(outputs[1], alsa_mixer_set_dBFS_output);
1190 ASSERT_EQ(2, cras_alsa_mixer_set_output_active_state_called);
1191 EXPECT_EQ(outputs[0], cras_alsa_mixer_set_output_active_state_outputs[0]);
1192 EXPECT_EQ(0, cras_alsa_mixer_set_output_active_state_values[0]);
1193 EXPECT_EQ(outputs[1], cras_alsa_mixer_set_output_active_state_outputs[1]);
1194 EXPECT_EQ(1, cras_alsa_mixer_set_output_active_state_values[1]);
1195 EXPECT_EQ(1, cras_iodev_update_dsp_called);
1196 EXPECT_EQ(1, cras_alsa_jack_enable_ucm_called);
1197 EXPECT_EQ(1, ucm_set_enabled_called);
1198
1199 // Simulate jack plug event.
1200 cras_alsa_support_8_channels = true; // Support up to 8 channels.
1201 cras_alsa_jack_get_mixer_output_ret = outputs[1];
1202 cras_alsa_jack_get_name_ret_value = jack_name;
1203 jack_output_plug_event(reinterpret_cast<struct cras_alsa_jack*>(4), 0, aio);
1204 EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
1205 /* Headphone plug event shouldn't trigger update_max_supported_channels. */
1206 EXPECT_EQ(0, cras_alsa_fill_properties_called);
1207 EXPECT_EQ(2, iodev->info.max_supported_channels);
1208
1209 alsa_iodev_destroy(iodev);
1210 }
1211
TEST(AlsaOutputNode,OutputNoControlsUCM)1212 TEST(AlsaOutputNode, OutputNoControlsUCM) {
1213 struct alsa_io* aio;
1214 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1215 struct cras_iodev* iodev;
1216 struct ucm_section* section;
1217
1218 ResetStubData();
1219
1220 // Create the IO device.
1221 iodev = alsa_iodev_create_with_default_parameters(
1222 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1223 CRAS_STREAM_OUTPUT);
1224 ASSERT_NE(iodev, (void*)NULL);
1225 aio = reinterpret_cast<struct alsa_io*>(iodev);
1226 EXPECT_EQ(1, cras_card_config_get_volume_curve_for_control_called);
1227
1228 // Node without controls or jacks.
1229 section = ucm_section_create(INTERNAL_SPEAKER, "hw:0,1", 1, -1,
1230 CRAS_STREAM_OUTPUT, NULL, NULL);
1231 // Device index doesn't match.
1232 EXPECT_EQ(-22, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1233 section->dev_idx = 0;
1234 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1235 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
1236 EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called);
1237 EXPECT_EQ(1, cras_iodev_add_node_called);
1238 ucm_section_free_list(section);
1239
1240 // Complete initialization, and make first node active.
1241 alsa_iodev_ucm_complete_init(iodev);
1242 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
1243 EXPECT_EQ(0, cras_alsa_mixer_get_control_name_called);
1244 EXPECT_EQ(1, cras_iodev_update_dsp_called);
1245 EXPECT_EQ(0, cras_alsa_jack_enable_ucm_called);
1246 EXPECT_EQ(1, ucm_set_enabled_called);
1247
1248 alsa_iodev_destroy(iodev);
1249 }
1250
TEST(AlsaOutputNode,OutputFromJackUCM)1251 TEST(AlsaOutputNode, OutputFromJackUCM) {
1252 struct alsa_io* aio;
1253 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1254 struct cras_iodev* iodev;
1255 static const char* jack_name = "TestCard - Headset Jack";
1256 struct ucm_section* section;
1257
1258 ResetStubData();
1259
1260 // Create the IO device.
1261 iodev = alsa_iodev_create_with_default_parameters(
1262 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1263 CRAS_STREAM_OUTPUT);
1264 ASSERT_NE(iodev, (void*)NULL);
1265 aio = reinterpret_cast<struct alsa_io*>(iodev);
1266 EXPECT_EQ(1, cras_card_config_get_volume_curve_for_control_called);
1267
1268 // Node without controls or jacks.
1269 cras_alsa_jack_list_add_jack_for_section_result_jack =
1270 reinterpret_cast<struct cras_alsa_jack*>(1);
1271 section = ucm_section_create(HEADPHONE, "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
1272 jack_name, "hctl");
1273 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1274 EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
1275 EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called);
1276 EXPECT_EQ(1, cras_iodev_add_node_called);
1277 EXPECT_EQ(1, cras_alsa_jack_list_add_jack_for_section_called);
1278 ucm_section_free_list(section);
1279
1280 // Complete initialization, and make first node active.
1281 alsa_iodev_ucm_complete_init(iodev);
1282 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
1283 EXPECT_EQ(0, cras_alsa_mixer_get_control_name_called);
1284 EXPECT_EQ(1, cras_iodev_update_dsp_called);
1285 EXPECT_EQ(1, cras_alsa_jack_enable_ucm_called);
1286 EXPECT_EQ(0, ucm_set_enabled_called);
1287
1288 alsa_iodev_destroy(iodev);
1289 }
1290
TEST(AlsaOutputNode,InputsFromUCM)1291 TEST(AlsaOutputNode, InputsFromUCM) {
1292 struct alsa_io* aio;
1293 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
1294 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1295 struct mixer_control* inputs[2];
1296 struct cras_iodev* iodev;
1297 static const char* jack_name = "TestCard - Headset Jack";
1298 int rc;
1299 struct ucm_section* section;
1300 long intrinsic_sensitivity = -2700;
1301
1302 ResetStubData();
1303 inputs[0] = reinterpret_cast<struct mixer_control*>(3);
1304 inputs[1] = reinterpret_cast<struct mixer_control*>(4);
1305 cras_alsa_mixer_list_inputs_outputs = inputs;
1306 cras_alsa_mixer_list_inputs_outputs_length = ARRAY_SIZE(inputs);
1307 cras_alsa_mixer_get_control_name_values[inputs[0]] = INTERNAL_MICROPHONE;
1308 cras_alsa_mixer_get_control_name_values[inputs[1]] = MIC;
1309
1310 // Create the IO device.
1311 iodev = alsa_iodev_create_with_default_parameters(
1312 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1313 CRAS_STREAM_INPUT);
1314 ASSERT_NE(iodev, (void*)NULL);
1315 aio = reinterpret_cast<struct alsa_io*>(iodev);
1316
1317 // First node.
1318 cras_alsa_mixer_get_control_for_section_return_value = inputs[0];
1319 section = ucm_section_create(INTERNAL_MICROPHONE, "hw:0,1", 0, -1,
1320 CRAS_STREAM_INPUT, NULL, NULL);
1321 ucm_section_add_coupled(section, "MIC-L", MIXER_NAME_VOLUME);
1322 ucm_section_add_coupled(section, "MIC-R", MIXER_NAME_VOLUME);
1323 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1324 ucm_section_free_list(section);
1325
1326 // Add a second node (will use the same iodev).
1327 cras_alsa_mixer_get_control_name_called = 0;
1328 // Set intrinsic sensitivity to enable software gain.
1329 ucm_get_intrinsic_sensitivity_values[MIC] = intrinsic_sensitivity;
1330 cras_alsa_jack_list_add_jack_for_section_result_jack =
1331 reinterpret_cast<struct cras_alsa_jack*>(1);
1332 cras_alsa_mixer_get_control_for_section_return_value = inputs[1];
1333 section = ucm_section_create(MIC, "hw:0,2", 0, -1, CRAS_STREAM_INPUT,
1334 jack_name, "hctl");
1335 ucm_section_set_mixer_name(section, MIC);
1336 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1337 ucm_section_free_list(section);
1338
1339 // Jack plug of an unknown device should do nothing.
1340 cras_alsa_jack_get_mixer_input_ret = NULL;
1341 cras_alsa_jack_get_name_ret_value = "Some other jack";
1342 jack_input_plug_event(reinterpret_cast<struct cras_alsa_jack*>(4), 0, aio);
1343 EXPECT_EQ(0, cras_iodev_set_node_plugged_called);
1344
1345 // Simulate jack plug event.
1346 cras_alsa_jack_get_mixer_input_ret = inputs[1];
1347 cras_alsa_jack_get_name_ret_value = jack_name;
1348 jack_input_plug_event(reinterpret_cast<struct cras_alsa_jack*>(4), 0, aio);
1349 EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
1350
1351 // Complete initialization, and make first node active.
1352 alsa_iodev_ucm_complete_init(iodev);
1353 EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
1354 EXPECT_EQ(2, cras_alsa_jack_list_add_jack_for_section_called);
1355 EXPECT_EQ(2, cras_alsa_mixer_get_control_for_section_called);
1356 EXPECT_EQ(1, cras_alsa_mixer_get_control_name_called);
1357 EXPECT_EQ(2, cras_iodev_add_node_called);
1358 EXPECT_EQ(2, ucm_get_dma_period_for_dev_called);
1359 EXPECT_EQ(0, aio->dma_period_set_microsecs);
1360
1361 aio->handle = (snd_pcm_t*)0x24;
1362
1363 ResetStubData();
1364 rc = alsa_iodev_set_active_node(iodev, aio->base.nodes->next, 1);
1365 EXPECT_EQ(0, rc);
1366 EXPECT_EQ(1, alsa_mixer_set_capture_dBFS_called);
1367 EXPECT_EQ(inputs[1], alsa_mixer_set_capture_dBFS_input);
1368 EXPECT_EQ(0, alsa_mixer_set_capture_dBFS_value);
1369 EXPECT_EQ(1, cras_iodev_update_dsp_called);
1370 EXPECT_EQ(1, cras_alsa_jack_enable_ucm_called);
1371 EXPECT_EQ(1, ucm_set_enabled_called);
1372 EXPECT_EQ(1, alsa_mixer_set_capture_mute_called);
1373 ASSERT_EQ(DEFAULT_CAPTURE_VOLUME_DBFS - intrinsic_sensitivity,
1374 iodev->active_node->capture_gain);
1375
1376 alsa_iodev_destroy(iodev);
1377 }
1378
TEST(AlsaOutputNode,InputNoControlsUCM)1379 TEST(AlsaOutputNode, InputNoControlsUCM) {
1380 struct alsa_io* aio;
1381 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1382 struct cras_iodev* iodev;
1383 struct ucm_section* section;
1384
1385 ResetStubData();
1386
1387 // Create the IO device.
1388 iodev = alsa_iodev_create_with_default_parameters(
1389 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1390 CRAS_STREAM_INPUT);
1391 ASSERT_NE(iodev, (void*)NULL);
1392 aio = reinterpret_cast<struct alsa_io*>(iodev);
1393
1394 // Node without controls or jacks.
1395 section = ucm_section_create(INTERNAL_MICROPHONE, "hw:0,1", 1, -1,
1396 CRAS_STREAM_INPUT, NULL, NULL);
1397 // Device index doesn't match.
1398 EXPECT_EQ(-22, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1399 section->dev_idx = 0;
1400 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1401 EXPECT_EQ(1, cras_alsa_jack_list_add_jack_for_section_called);
1402 EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called);
1403 EXPECT_EQ(0, cras_alsa_mixer_get_control_name_called);
1404 EXPECT_EQ(1, cras_iodev_add_node_called);
1405 ucm_section_free_list(section);
1406
1407 // Complete initialization, and make first node active.
1408 alsa_iodev_ucm_complete_init(iodev);
1409 EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
1410 EXPECT_EQ(0, cras_alsa_mixer_get_control_name_called);
1411 EXPECT_EQ(1, cras_iodev_update_dsp_called);
1412 EXPECT_EQ(0, cras_alsa_jack_enable_ucm_called);
1413 EXPECT_EQ(1, ucm_set_enabled_called);
1414
1415 alsa_iodev_destroy(iodev);
1416 }
1417
TEST(AlsaOutputNode,InputFromJackUCM)1418 TEST(AlsaOutputNode, InputFromJackUCM) {
1419 struct alsa_io* aio;
1420 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1421 struct cras_iodev* iodev;
1422 static const char* jack_name = "TestCard - Headset Jack";
1423 struct ucm_section* section;
1424
1425 ResetStubData();
1426
1427 // Create the IO device.
1428 iodev = alsa_iodev_create_with_default_parameters(
1429 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1430 CRAS_STREAM_INPUT);
1431 ASSERT_NE(iodev, (void*)NULL);
1432 aio = reinterpret_cast<struct alsa_io*>(iodev);
1433
1434 // Node without controls or jacks.
1435 cras_alsa_jack_list_add_jack_for_section_result_jack =
1436 reinterpret_cast<struct cras_alsa_jack*>(1);
1437 section = ucm_section_create(MIC, "hw:0,1", 0, -1, CRAS_STREAM_INPUT,
1438 jack_name, "hctl");
1439 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1440 EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called);
1441 EXPECT_EQ(1, cras_iodev_add_node_called);
1442 EXPECT_EQ(1, cras_alsa_jack_list_add_jack_for_section_called);
1443 ucm_section_free_list(section);
1444
1445 // Complete initialization, and make first node active.
1446 alsa_iodev_ucm_complete_init(iodev);
1447 EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
1448 EXPECT_EQ(0, cras_alsa_mixer_get_control_name_called);
1449 EXPECT_EQ(1, cras_iodev_update_dsp_called);
1450 EXPECT_EQ(1, cras_alsa_jack_enable_ucm_called);
1451 EXPECT_EQ(0, ucm_set_enabled_called);
1452
1453 alsa_iodev_destroy(iodev);
1454 }
1455
TEST(AlsaOutputNode,AutoUnplugOutputNode)1456 TEST(AlsaOutputNode, AutoUnplugOutputNode) {
1457 struct alsa_io* aio;
1458 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
1459 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1460 struct mixer_control* outputs[2];
1461 const struct cras_alsa_jack* jack = (struct cras_alsa_jack*)4;
1462
1463 ResetStubData();
1464 outputs[0] = reinterpret_cast<struct mixer_control*>(5);
1465 outputs[1] = reinterpret_cast<struct mixer_control*>(6);
1466
1467 cras_alsa_mixer_list_outputs_outputs = outputs;
1468 cras_alsa_mixer_list_outputs_outputs_length = ARRAY_SIZE(outputs);
1469
1470 cras_alsa_mixer_get_control_name_values[outputs[0]] = INTERNAL_SPEAKER;
1471 cras_alsa_mixer_get_control_name_values[outputs[1]] = HEADPHONE;
1472 auto_unplug_output_node_ret = 1;
1473
1474 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
1475 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1476 CRAS_STREAM_OUTPUT);
1477
1478 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
1479 EXPECT_EQ(3, cras_card_config_get_volume_curve_for_control_called);
1480 EXPECT_EQ(1, cras_alsa_mixer_list_outputs_called);
1481 EXPECT_EQ(2, cras_alsa_mixer_get_control_name_called);
1482
1483 // Assert that the the internal speaker is plugged and other nodes aren't.
1484 ASSERT_NE(aio->base.nodes, (void*)NULL);
1485 EXPECT_EQ(aio->base.nodes->plugged, 1);
1486 ASSERT_NE(aio->base.nodes->next, (void*)NULL);
1487 EXPECT_EQ(aio->base.nodes->next->plugged, 0);
1488
1489 // Plug headphone jack
1490 cras_alsa_jack_get_name_ret_value = "Headphone Jack";
1491 is_utf8_string_ret_value = 1;
1492 cras_alsa_jack_get_mixer_output_ret = outputs[1];
1493 cras_alsa_jack_list_create_cb(jack, 1, cras_alsa_jack_list_create_cb_data);
1494
1495 // Assert internal speaker is auto unplugged
1496 EXPECT_EQ(aio->base.nodes->plugged, 0);
1497 EXPECT_EQ(aio->base.nodes->next->plugged, 1);
1498
1499 alsa_iodev_destroy((struct cras_iodev*)aio);
1500 }
1501
TEST(AlsaOutputNode,AutoUnplugInputNode)1502 TEST(AlsaOutputNode, AutoUnplugInputNode) {
1503 struct alsa_io* aio;
1504 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
1505 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1506 struct mixer_control* inputs[2];
1507 const struct cras_alsa_jack* jack = (struct cras_alsa_jack*)4;
1508
1509 ResetStubData();
1510 inputs[0] = reinterpret_cast<struct mixer_control*>(5);
1511 inputs[1] = reinterpret_cast<struct mixer_control*>(6);
1512
1513 cras_alsa_mixer_list_inputs_outputs = inputs;
1514 cras_alsa_mixer_list_inputs_outputs_length = ARRAY_SIZE(inputs);
1515
1516 cras_alsa_mixer_get_control_name_values[inputs[0]] = INTERNAL_MICROPHONE;
1517 cras_alsa_mixer_get_control_name_values[inputs[1]] = MIC;
1518 auto_unplug_input_node_ret = 1;
1519
1520 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
1521 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1522 CRAS_STREAM_INPUT);
1523 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
1524 EXPECT_EQ(1, cras_alsa_mixer_list_inputs_called);
1525 EXPECT_EQ(2, cras_alsa_mixer_get_control_name_called);
1526
1527 // Assert that the the internal speaker is plugged and other nodes aren't.
1528 ASSERT_NE(aio->base.nodes, (void*)NULL);
1529 EXPECT_EQ(aio->base.nodes->plugged, 1);
1530 ASSERT_NE(aio->base.nodes->next, (void*)NULL);
1531 EXPECT_EQ(aio->base.nodes->next->plugged, 0);
1532
1533 // Plug headphone jack
1534 cras_alsa_jack_get_name_ret_value = "Mic Jack";
1535 is_utf8_string_ret_value = 1;
1536 cras_alsa_jack_get_mixer_input_ret = inputs[1];
1537 cras_alsa_jack_list_create_cb(jack, 1, cras_alsa_jack_list_create_cb_data);
1538
1539 // Assert internal speaker is auto unplugged
1540 EXPECT_EQ(aio->base.nodes->plugged, 0);
1541 EXPECT_EQ(aio->base.nodes->next->plugged, 1);
1542
1543 alsa_iodev_destroy((struct cras_iodev*)aio);
1544 }
1545
TEST(AlsaLoopback,InitializePlayback)1546 TEST(AlsaLoopback, InitializePlayback) {
1547 struct alsa_io* aio;
1548 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
1549 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1550 struct cras_iodev* iodev;
1551 static const char* jack_name = "TestCard - Alsa Loopback";
1552 struct mixer_control* outputs[1];
1553 struct ucm_section* section;
1554
1555 ResetStubData();
1556 outputs[0] = reinterpret_cast<struct mixer_control*>(3);
1557 cras_alsa_mixer_list_outputs_outputs = outputs;
1558 cras_alsa_mixer_list_outputs_outputs_length = ARRAY_SIZE(outputs);
1559 cras_alsa_mixer_get_control_name_values[outputs[0]] = LOOPBACK_PLAYBACK;
1560
1561 // Create the IO device.
1562 iodev = alsa_iodev_create_with_default_parameters(
1563 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1564 CRAS_STREAM_OUTPUT);
1565 ASSERT_NE(iodev, (void*)NULL);
1566 aio = reinterpret_cast<struct alsa_io*>(iodev);
1567
1568 // Add node.
1569 section = ucm_section_create(LOOPBACK_PLAYBACK, "hw:0,1", 0, -1,
1570 CRAS_STREAM_OUTPUT, jack_name, NULL);
1571 ucm_section_set_mixer_name(section, LOOPBACK_PLAYBACK);
1572 cras_alsa_jack_list_add_jack_for_section_result_jack = NULL;
1573 cras_alsa_mixer_get_control_for_section_return_value = outputs[0];
1574 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1575 ucm_section_free_list(section);
1576
1577 // Complete initialization, and check the loopback playback node is plugged as
1578 // the active node.
1579 alsa_iodev_ucm_complete_init(iodev);
1580 EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
1581 ASSERT_NE(aio->base.active_node, (void*)NULL);
1582 EXPECT_STREQ(LOOPBACK_PLAYBACK, aio->base.active_node->name);
1583 EXPECT_EQ(1, aio->base.active_node->plugged);
1584
1585 alsa_iodev_destroy(iodev);
1586 }
1587
TEST(AlsaLoopback,InitializeCapture)1588 TEST(AlsaLoopback, InitializeCapture) {
1589 struct alsa_io* aio;
1590 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1591 struct cras_iodev* iodev;
1592 static const char* jack_name = "TestCard - Alsa Loopback";
1593 struct ucm_section* section;
1594
1595 ResetStubData();
1596
1597 // Create the IO device.
1598 iodev = alsa_iodev_create_with_default_parameters(
1599 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
1600 CRAS_STREAM_INPUT);
1601 ASSERT_NE(iodev, (void*)NULL);
1602 aio = reinterpret_cast<struct alsa_io*>(iodev);
1603
1604 // Node without controls or jacks.
1605 cras_alsa_jack_list_add_jack_for_section_result_jack =
1606 reinterpret_cast<struct cras_alsa_jack*>(1);
1607 section = ucm_section_create(LOOPBACK_CAPTURE, "hw:0,1", 0, -1,
1608 CRAS_STREAM_INPUT, jack_name, NULL);
1609 ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
1610 ucm_section_free_list(section);
1611
1612 // Complete initialization, and check the loopback capture node is plugged as
1613 // the active node.
1614 alsa_iodev_ucm_complete_init(iodev);
1615 EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
1616 ASSERT_NE(aio->base.active_node, (void*)NULL);
1617 EXPECT_STREQ(LOOPBACK_CAPTURE, aio->base.active_node->name);
1618 EXPECT_EQ(1, aio->base.active_node->plugged);
1619
1620 alsa_iodev_destroy(iodev);
1621 }
1622
TEST(AlsaInitNode,SetNodeInitialState)1623 TEST(AlsaInitNode, SetNodeInitialState) {
1624 struct cras_ionode node;
1625 struct cras_iodev dev;
1626
1627 memset(&dev, 0, sizeof(dev));
1628 memset(&node, 0, sizeof(node));
1629 node.dev = &dev;
1630 strcpy(node.name, "Unknown");
1631 dev.direction = CRAS_STREAM_OUTPUT;
1632 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1633 ASSERT_EQ(0, node.plugged);
1634 ASSERT_EQ(0, node.plugged_time.tv_sec);
1635 ASSERT_EQ(CRAS_NODE_TYPE_UNKNOWN, node.type);
1636 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1637
1638 memset(&node, 0, sizeof(node));
1639 node.dev = &dev;
1640 strcpy(node.name, INTERNAL_SPEAKER);
1641 dev.direction = CRAS_STREAM_OUTPUT;
1642 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1643 ASSERT_EQ(1, node.plugged);
1644 ASSERT_GT(node.plugged_time.tv_sec, 0);
1645 ASSERT_EQ(CRAS_NODE_TYPE_INTERNAL_SPEAKER, node.type);
1646 ASSERT_EQ(NODE_POSITION_INTERNAL, node.position);
1647
1648 memset(&node, 0, sizeof(node));
1649 node.dev = &dev;
1650 strcpy(node.name, INTERNAL_MICROPHONE);
1651 dev.direction = CRAS_STREAM_INPUT;
1652 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1653 ASSERT_EQ(1, node.plugged);
1654 ASSERT_GT(node.plugged_time.tv_sec, 0);
1655 ASSERT_EQ(CRAS_NODE_TYPE_MIC, node.type);
1656 ASSERT_EQ(NODE_POSITION_INTERNAL, node.position);
1657
1658 memset(&node, 0, sizeof(node));
1659 node.dev = &dev;
1660 strcpy(node.name, HDMI);
1661 dev.direction = CRAS_STREAM_OUTPUT;
1662 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1663 ASSERT_EQ(0, node.plugged);
1664 ASSERT_EQ(0, node.plugged_time.tv_sec);
1665 ASSERT_EQ(CRAS_NODE_TYPE_HDMI, node.type);
1666 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1667
1668 memset(&node, 0, sizeof(node));
1669 node.dev = &dev;
1670 strcpy(node.name, "IEC958");
1671 dev.direction = CRAS_STREAM_OUTPUT;
1672 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1673 ASSERT_EQ(0, node.plugged);
1674 ASSERT_EQ(CRAS_NODE_TYPE_HDMI, node.type);
1675 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1676
1677 memset(&node, 0, sizeof(node));
1678 node.dev = &dev;
1679 strcpy(node.name, "HDMI Jack");
1680 dev.direction = CRAS_STREAM_OUTPUT;
1681 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1682 ASSERT_EQ(0, node.plugged);
1683 ASSERT_EQ(CRAS_NODE_TYPE_HDMI, node.type);
1684 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1685
1686 memset(&node, 0, sizeof(node));
1687 node.dev = &dev;
1688 strcpy(node.name, "Something HDMI Jack");
1689 dev.direction = CRAS_STREAM_OUTPUT;
1690 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1691 ASSERT_EQ(0, node.plugged);
1692 ASSERT_EQ(CRAS_NODE_TYPE_HDMI, node.type);
1693 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1694
1695 memset(&node, 0, sizeof(node));
1696 node.dev = &dev;
1697 strcpy(node.name, HEADPHONE);
1698 dev.direction = CRAS_STREAM_OUTPUT;
1699 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1700 ASSERT_EQ(0, node.plugged);
1701 ASSERT_EQ(CRAS_NODE_TYPE_HEADPHONE, node.type);
1702 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1703
1704 memset(&node, 0, sizeof(node));
1705 node.dev = &dev;
1706 strcpy(node.name, "Headphone Jack");
1707 dev.direction = CRAS_STREAM_OUTPUT;
1708 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1709 ASSERT_EQ(0, node.plugged);
1710 ASSERT_EQ(CRAS_NODE_TYPE_HEADPHONE, node.type);
1711 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1712
1713 memset(&node, 0, sizeof(node));
1714 node.dev = &dev;
1715 strcpy(node.name, MIC);
1716 dev.direction = CRAS_STREAM_INPUT;
1717 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1718 ASSERT_EQ(0, node.plugged);
1719 ASSERT_EQ(CRAS_NODE_TYPE_MIC, node.type);
1720 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1721
1722 memset(&node, 0, sizeof(node));
1723 node.dev = &dev;
1724 strcpy(node.name, "Front Mic");
1725 dev.direction = CRAS_STREAM_INPUT;
1726 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1727 ASSERT_EQ(1, node.plugged);
1728 ASSERT_EQ(CRAS_NODE_TYPE_MIC, node.type);
1729 ASSERT_EQ(NODE_POSITION_FRONT, node.position);
1730
1731 memset(&node, 0, sizeof(node));
1732 node.dev = &dev;
1733 strcpy(node.name, "Rear Mic");
1734 dev.direction = CRAS_STREAM_INPUT;
1735 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1736 ASSERT_EQ(1, node.plugged);
1737 ASSERT_EQ(CRAS_NODE_TYPE_MIC, node.type);
1738 ASSERT_EQ(NODE_POSITION_REAR, node.position);
1739
1740 memset(&node, 0, sizeof(node));
1741 node.dev = &dev;
1742 strcpy(node.name, "Mic Jack");
1743 dev.direction = CRAS_STREAM_INPUT;
1744 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1745 ASSERT_EQ(0, node.plugged);
1746 ASSERT_EQ(CRAS_NODE_TYPE_MIC, node.type);
1747 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1748
1749 memset(&node, 0, sizeof(node));
1750 node.dev = &dev;
1751 strcpy(node.name, "Unknown");
1752 dev.direction = CRAS_STREAM_OUTPUT;
1753 set_node_initial_state(&node, ALSA_CARD_TYPE_USB);
1754 ASSERT_EQ(0, node.plugged);
1755 ASSERT_EQ(CRAS_NODE_TYPE_USB, node.type);
1756 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1757
1758 memset(&node, 0, sizeof(node));
1759 node.dev = &dev;
1760 dev.direction = CRAS_STREAM_INPUT;
1761 strcpy(node.name, "DAISY-I2S Mic Jack");
1762 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1763 ASSERT_EQ(0, node.plugged);
1764 ASSERT_EQ(CRAS_NODE_TYPE_MIC, node.type);
1765 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1766 // Node name is changed to "MIC".
1767 ASSERT_EQ(0, strcmp(node.name, MIC));
1768
1769 memset(&node, 0, sizeof(node));
1770 node.dev = &dev;
1771 dev.direction = CRAS_STREAM_OUTPUT;
1772 strcpy(node.name, "DAISY-I2S Headphone Jack");
1773 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1774 ASSERT_EQ(0, node.plugged);
1775 ASSERT_EQ(CRAS_NODE_TYPE_HEADPHONE, node.type);
1776 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1777 // Node name is changed to "Headphone".
1778 ASSERT_EQ(0, strcmp(node.name, HEADPHONE));
1779
1780 memset(&node, 0, sizeof(node));
1781 node.dev = &dev;
1782 strcpy(node.name, INTERNAL_SPEAKER);
1783 dev.direction = CRAS_STREAM_OUTPUT;
1784 set_node_initial_state(&node, ALSA_CARD_TYPE_USB);
1785 ASSERT_EQ(1, node.plugged);
1786 ASSERT_GT(node.plugged_time.tv_sec, 0);
1787 ASSERT_EQ(CRAS_NODE_TYPE_USB, node.type);
1788 ASSERT_EQ(NODE_POSITION_EXTERNAL, node.position);
1789
1790 memset(&node, 0, sizeof(node));
1791 node.dev = &dev;
1792 strcpy(node.name, "Haptic");
1793 dev.direction = CRAS_STREAM_OUTPUT;
1794 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1795 ASSERT_EQ(1, node.plugged);
1796 ASSERT_GT(node.plugged_time.tv_sec, 0);
1797 ASSERT_EQ(CRAS_NODE_TYPE_HAPTIC, node.type);
1798 ASSERT_EQ(NODE_POSITION_INTERNAL, node.position);
1799
1800 memset(&node, 0, sizeof(node));
1801 node.dev = &dev;
1802 strcpy(node.name, "Rumbler");
1803 dev.direction = CRAS_STREAM_OUTPUT;
1804 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1805 ASSERT_EQ(1, node.plugged);
1806 ASSERT_GT(node.plugged_time.tv_sec, 0);
1807 ASSERT_EQ(CRAS_NODE_TYPE_HAPTIC, node.type);
1808 ASSERT_EQ(NODE_POSITION_INTERNAL, node.position);
1809 }
1810
TEST(AlsaInitNode,SetNodeInitialStateDropInvalidUTF8NodeName)1811 TEST(AlsaInitNode, SetNodeInitialStateDropInvalidUTF8NodeName) {
1812 struct cras_ionode node;
1813 struct cras_iodev dev;
1814
1815 memset(&dev, 0, sizeof(dev));
1816 memset(&node, 0, sizeof(node));
1817 node.dev = &dev;
1818
1819 memset(&node, 0, sizeof(node));
1820 node.dev = &dev;
1821 strcpy(node.name, "Something USB");
1822 // 0xfe can not appear in a valid UTF-8 string.
1823 node.name[0] = 0xfe;
1824 is_utf8_string_ret_value = 0;
1825 dev.direction = CRAS_STREAM_OUTPUT;
1826 set_node_initial_state(&node, ALSA_CARD_TYPE_USB);
1827 ASSERT_EQ(CRAS_NODE_TYPE_USB, node.type);
1828 ASSERT_STREQ(USB, node.name);
1829
1830 memset(&node, 0, sizeof(node));
1831 node.dev = &dev;
1832 strcpy(node.name, "Something HDMI Jack");
1833 // 0xfe can not appear in a valid UTF-8 string.
1834 node.name[0] = 0xfe;
1835 is_utf8_string_ret_value = 0;
1836 dev.direction = CRAS_STREAM_OUTPUT;
1837 set_node_initial_state(&node, ALSA_CARD_TYPE_INTERNAL);
1838 ASSERT_EQ(CRAS_NODE_TYPE_HDMI, node.type);
1839 ASSERT_STREQ(HDMI, node.name);
1840 }
1841
TEST(AlsaIoInit,HDMIJackUpdateInvalidUTF8MonitorName)1842 TEST(AlsaIoInit, HDMIJackUpdateInvalidUTF8MonitorName) {
1843 struct alsa_io* aio;
1844 struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
1845 struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
1846 const struct cras_alsa_jack* jack = (struct cras_alsa_jack*)4;
1847
1848 ResetStubData();
1849 aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
1850 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
1851 CRAS_STREAM_OUTPUT);
1852 ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
1853
1854 // Prepare the stub data such that the jack will be identified as an
1855 // HDMI jack, and thus the callback creates an HDMI node.
1856 cras_alsa_jack_get_name_ret_value = "HDMI Jack";
1857 // Set the jack name updated from monitor to be an invalid UTF8 string.
1858 cras_alsa_jack_update_monitor_fake_name = "\xfeomething";
1859 is_utf8_string_ret_value = 0;
1860
1861 // Add the jack node.
1862 cras_alsa_jack_list_create_cb(jack, 1, cras_alsa_jack_list_create_cb_data);
1863
1864 EXPECT_EQ(2, cras_alsa_jack_get_name_called);
1865 ASSERT_EQ(CRAS_NODE_TYPE_HDMI, aio->base.nodes->next->type);
1866 // The node name should be "HDMI".
1867 ASSERT_STREQ(HDMI, aio->base.nodes->next->name);
1868
1869 alsa_iodev_destroy((struct cras_iodev*)aio);
1870 }
1871
1872 // Test thread add/rm stream, open_alsa, and iodev config.
1873 class AlsaVolumeMuteSuite : public testing::Test {
1874 protected:
SetUp()1875 virtual void SetUp() {
1876 ResetStubData();
1877 output_control_ = reinterpret_cast<struct mixer_control*>(10);
1878 cras_alsa_mixer_list_outputs_outputs = &output_control_;
1879 cras_alsa_mixer_list_outputs_outputs_length = 1;
1880 cras_alsa_mixer_get_control_name_values[output_control_] = INTERNAL_SPEAKER;
1881 cras_alsa_mixer_list_outputs_outputs_length = 1;
1882 aio_output_ = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
1883 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, NULL,
1884 CRAS_STREAM_OUTPUT);
1885 alsa_iodev_legacy_complete_init((struct cras_iodev*)aio_output_);
1886 EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
1887
1888 struct cras_ionode* node;
1889 int count = 0;
1890 DL_FOREACH (aio_output_->base.nodes, node) { printf("node %d \n", count); }
1891 aio_output_->base.direction = CRAS_STREAM_OUTPUT;
1892 fmt_.frame_rate = 44100;
1893 fmt_.num_channels = 2;
1894 fmt_.format = SND_PCM_FORMAT_S16_LE;
1895 aio_output_->base.format = &fmt_;
1896 cras_alsa_get_avail_frames_ret = -1;
1897 }
1898
TearDown()1899 virtual void TearDown() {
1900 alsa_iodev_destroy((struct cras_iodev*)aio_output_);
1901 cras_alsa_get_avail_frames_ret = 0;
1902 }
1903
1904 struct mixer_control* output_control_;
1905 struct alsa_io* aio_output_;
1906 struct cras_audio_format fmt_;
1907 };
1908
TEST_F(AlsaVolumeMuteSuite,GetDefaultVolumeCurve)1909 TEST_F(AlsaVolumeMuteSuite, GetDefaultVolumeCurve) {
1910 int rc;
1911 struct cras_audio_format* fmt;
1912
1913 fmt = (struct cras_audio_format*)malloc(sizeof(*fmt));
1914 memcpy(fmt, &fmt_, sizeof(fmt_));
1915 aio_output_->base.format = fmt;
1916 aio_output_->handle = (snd_pcm_t*)0x24;
1917
1918 rc = aio_output_->base.configure_dev(&aio_output_->base);
1919 ASSERT_EQ(0, rc);
1920 EXPECT_EQ(&default_curve, fake_get_dBFS_volume_curve_val);
1921
1922 aio_output_->base.set_volume(&aio_output_->base);
1923 EXPECT_EQ(&default_curve, fake_get_dBFS_volume_curve_val);
1924 free(fmt);
1925 }
1926
TEST_F(AlsaVolumeMuteSuite,GetVolumeCurveFromNode)1927 TEST_F(AlsaVolumeMuteSuite, GetVolumeCurveFromNode) {
1928 int rc;
1929 struct cras_audio_format* fmt;
1930 struct cras_alsa_jack* jack = (struct cras_alsa_jack*)4;
1931 struct cras_ionode* node;
1932 struct cras_volume_curve hp_curve = {
1933 .get_dBFS = fake_get_dBFS,
1934 };
1935
1936 // Headphone jack plugged and has its own volume curve.
1937 cras_alsa_jack_get_mixer_output_ret = NULL;
1938 cras_alsa_jack_get_name_ret_value = HEADPHONE;
1939 cras_card_config_get_volume_curve_vals[HEADPHONE] = &hp_curve;
1940 cras_alsa_jack_list_create_cb(jack, 1, cras_alsa_jack_list_create_cb_data);
1941 EXPECT_EQ(1, cras_alsa_jack_update_node_type_called);
1942 EXPECT_EQ(3, cras_card_config_get_volume_curve_for_control_called);
1943
1944 // These settings should be placed after plugging jacks to make it safer.
1945 // If is HDMI jack, plug event will trigger update_max_supported_channels()
1946 // and do open_dev() and close_dev() once. close_dev() will perform alsa_io
1947 // cleanup.
1948 // Headphone jack won't trigger, but we still place here due to coherence.
1949 fmt = (struct cras_audio_format*)malloc(sizeof(*fmt));
1950 memcpy(fmt, &fmt_, sizeof(fmt_));
1951 aio_output_->base.format = fmt;
1952 aio_output_->handle = (snd_pcm_t*)0x24;
1953
1954 // Switch to node 'Headphone'.
1955 node = aio_output_->base.nodes->next;
1956 aio_output_->base.active_node = node;
1957
1958 rc = aio_output_->base.configure_dev(&aio_output_->base);
1959 ASSERT_EQ(0, rc);
1960 EXPECT_EQ(&hp_curve, fake_get_dBFS_volume_curve_val);
1961
1962 aio_output_->base.set_volume(&aio_output_->base);
1963 EXPECT_EQ(&hp_curve, fake_get_dBFS_volume_curve_val);
1964 free(fmt);
1965 }
1966
TEST_F(AlsaVolumeMuteSuite,SetVolume)1967 TEST_F(AlsaVolumeMuteSuite, SetVolume) {
1968 int rc;
1969 struct cras_audio_format* fmt;
1970 const size_t fake_system_volume = 55;
1971 const size_t fake_system_volume_dB = (fake_system_volume - 100) * 100;
1972
1973 fmt = (struct cras_audio_format*)malloc(sizeof(*fmt));
1974 memcpy(fmt, &fmt_, sizeof(fmt_));
1975 aio_output_->base.format = fmt;
1976 aio_output_->handle = (snd_pcm_t*)0x24;
1977
1978 sys_get_volume_return_value = fake_system_volume;
1979 rc = aio_output_->base.configure_dev(&aio_output_->base);
1980 ASSERT_EQ(0, rc);
1981 EXPECT_EQ(1, alsa_mixer_set_dBFS_called);
1982 EXPECT_EQ(fake_system_volume_dB, alsa_mixer_set_dBFS_value);
1983
1984 alsa_mixer_set_dBFS_called = 0;
1985 alsa_mixer_set_dBFS_value = 0;
1986 sys_get_volume_return_value = 50;
1987 sys_get_volume_called = 0;
1988 aio_output_->base.set_volume(&aio_output_->base);
1989 EXPECT_EQ(1, sys_get_volume_called);
1990 EXPECT_EQ(1, alsa_mixer_set_dBFS_called);
1991 EXPECT_EQ(-5000, alsa_mixer_set_dBFS_value);
1992 EXPECT_EQ(output_control_, alsa_mixer_set_dBFS_output);
1993
1994 alsa_mixer_set_dBFS_called = 0;
1995 alsa_mixer_set_dBFS_value = 0;
1996 sys_get_volume_return_value = 0;
1997 sys_get_volume_called = 0;
1998 aio_output_->base.set_volume(&aio_output_->base);
1999 EXPECT_EQ(1, sys_get_volume_called);
2000 EXPECT_EQ(1, alsa_mixer_set_dBFS_called);
2001 EXPECT_EQ(-10000, alsa_mixer_set_dBFS_value);
2002
2003 sys_get_volume_return_value = 80;
2004 aio_output_->base.active_node->volume = 90;
2005 aio_output_->base.set_volume(&aio_output_->base);
2006 EXPECT_EQ(-3000, alsa_mixer_set_dBFS_value);
2007
2008 // close the dev.
2009 rc = aio_output_->base.close_dev(&aio_output_->base);
2010 EXPECT_EQ(0, rc);
2011 EXPECT_EQ((void*)NULL, aio_output_->handle);
2012
2013 free(fmt);
2014 }
2015
TEST_F(AlsaVolumeMuteSuite,SetMute)2016 TEST_F(AlsaVolumeMuteSuite, SetMute) {
2017 int muted;
2018
2019 aio_output_->handle = (snd_pcm_t*)0x24;
2020
2021 // Test mute.
2022 ResetStubData();
2023 muted = 1;
2024
2025 sys_get_mute_return_value = muted;
2026
2027 aio_output_->base.set_mute(&aio_output_->base);
2028
2029 EXPECT_EQ(1, sys_get_mute_called);
2030 EXPECT_EQ(1, alsa_mixer_set_mute_called);
2031 EXPECT_EQ(muted, alsa_mixer_set_mute_value);
2032 EXPECT_EQ(output_control_, alsa_mixer_set_mute_output);
2033
2034 // Test unmute.
2035 ResetStubData();
2036 muted = 0;
2037
2038 sys_get_mute_return_value = muted;
2039
2040 aio_output_->base.set_mute(&aio_output_->base);
2041
2042 EXPECT_EQ(1, sys_get_mute_called);
2043 EXPECT_EQ(1, alsa_mixer_set_mute_called);
2044 EXPECT_EQ(muted, alsa_mixer_set_mute_value);
2045 EXPECT_EQ(output_control_, alsa_mixer_set_mute_output);
2046 }
2047
2048 // Test free run.
2049 class AlsaFreeRunTestSuite : public testing::Test {
2050 protected:
SetUp()2051 virtual void SetUp() {
2052 ResetStubData();
2053 memset(&aio, 0, sizeof(aio));
2054 fmt_.format = SND_PCM_FORMAT_S16_LE;
2055 fmt_.frame_rate = 48000;
2056 fmt_.num_channels = 2;
2057 aio.base.frames_queued = frames_queued;
2058 aio.base.output_underrun = alsa_output_underrun;
2059 aio.base.direction = CRAS_STREAM_OUTPUT;
2060 aio.base.format = &fmt_;
2061 aio.base.buffer_size = BUFFER_SIZE;
2062 aio.base.min_cb_level = 240;
2063 aio.base.min_buffer_level = 0;
2064 aio.filled_zeros_for_draining = 0;
2065 cras_alsa_mmap_begin_buffer = (uint8_t*)calloc(
2066 BUFFER_SIZE * 2 * 2, sizeof(*cras_alsa_mmap_begin_buffer));
2067 memset(cras_alsa_mmap_begin_buffer, 0xff,
2068 sizeof(*cras_alsa_mmap_begin_buffer));
2069 }
2070
TearDown()2071 virtual void TearDown() { free(cras_alsa_mmap_begin_buffer); }
2072
2073 struct alsa_io aio;
2074 struct cras_audio_format fmt_;
2075 };
2076
TEST_F(AlsaFreeRunTestSuite,FillWholeBufferWithZeros)2077 TEST_F(AlsaFreeRunTestSuite, FillWholeBufferWithZeros) {
2078 int rc;
2079 int16_t* zeros;
2080
2081 rc = fill_whole_buffer_with_zeros(&aio.base);
2082
2083 EXPECT_EQ(0, rc);
2084 zeros = (int16_t*)calloc(BUFFER_SIZE * 2, sizeof(*zeros));
2085 EXPECT_EQ(0, memcmp(zeros, cras_alsa_mmap_begin_buffer, BUFFER_SIZE * 2 * 2));
2086
2087 free(zeros);
2088 }
2089
TEST_F(AlsaFreeRunTestSuite,EnterFreeRunAlreadyFreeRunning)2090 TEST_F(AlsaFreeRunTestSuite, EnterFreeRunAlreadyFreeRunning) {
2091 int rc;
2092
2093 // Device is in free run state, no need to fill zeros or fill whole buffer.
2094 aio.free_running = 1;
2095
2096 rc = no_stream(&aio.base, 1);
2097
2098 EXPECT_EQ(0, rc);
2099 EXPECT_EQ(0, cras_alsa_mmap_get_whole_buffer_called);
2100 EXPECT_EQ(0, cras_iodev_fill_odev_zeros_called);
2101 EXPECT_EQ(0, cras_iodev_fill_odev_zeros_frames);
2102 }
2103
TEST_F(AlsaFreeRunTestSuite,EnterFreeRunNotDrainedYetNeedToFillZeros)2104 TEST_F(AlsaFreeRunTestSuite, EnterFreeRunNotDrainedYetNeedToFillZeros) {
2105 int rc, real_hw_level;
2106 struct timespec hw_tstamp;
2107 int fill_zeros_duration = 50;
2108 // Device is not in free run state. There are still valid samples to play.
2109 // In cras_alsa_io.c, we defined there are 50ms zeros to be filled.
2110 real_hw_level = 200;
2111 cras_alsa_get_avail_frames_avail = BUFFER_SIZE - real_hw_level;
2112
2113 rc = aio.base.frames_queued(&aio.base, &hw_tstamp);
2114 EXPECT_EQ(200, rc);
2115
2116 rc = no_stream(&aio.base, 1);
2117
2118 EXPECT_EQ(0, rc);
2119 EXPECT_EQ(0, cras_alsa_mmap_get_whole_buffer_called);
2120 EXPECT_EQ(1, cras_iodev_fill_odev_zeros_called);
2121 EXPECT_EQ(fmt_.frame_rate / 1000 * fill_zeros_duration,
2122 cras_iodev_fill_odev_zeros_frames);
2123 EXPECT_EQ(fmt_.frame_rate / 1000 * fill_zeros_duration,
2124 aio.filled_zeros_for_draining);
2125 EXPECT_EQ(0, aio.free_running);
2126 }
2127
TEST_F(AlsaFreeRunTestSuite,EnterFreeRunNotDrainedYetFillZerosExceedBuffer)2128 TEST_F(AlsaFreeRunTestSuite, EnterFreeRunNotDrainedYetFillZerosExceedBuffer) {
2129 int rc, real_hw_level;
2130
2131 // Device is not in free run state. There are still valid samples to play.
2132 // If frames avail is smaller than 50ms(48 * 50 = 2400 zeros), only fill
2133 // zeros until buffer size.
2134 real_hw_level = 7000;
2135 cras_alsa_get_avail_frames_avail = BUFFER_SIZE - real_hw_level;
2136
2137 rc = no_stream(&aio.base, 1);
2138
2139 EXPECT_EQ(0, rc);
2140 EXPECT_EQ(0, cras_alsa_mmap_get_whole_buffer_called);
2141 EXPECT_EQ(1, cras_iodev_fill_odev_zeros_called);
2142 EXPECT_EQ(cras_alsa_get_avail_frames_avail,
2143 cras_iodev_fill_odev_zeros_frames);
2144 EXPECT_EQ(cras_alsa_get_avail_frames_avail, aio.filled_zeros_for_draining);
2145 EXPECT_EQ(0, aio.free_running);
2146 }
2147
TEST_F(AlsaFreeRunTestSuite,EnterFreeRunDrained)2148 TEST_F(AlsaFreeRunTestSuite, EnterFreeRunDrained) {
2149 int rc, real_hw_level;
2150
2151 // Device is not in free run state. There are still valid samples to play.
2152 // The number of valid samples is less than filled zeros.
2153 // Should enter free run state and fill whole buffer with zeros.
2154 real_hw_level = 40;
2155 cras_alsa_get_avail_frames_avail = BUFFER_SIZE - real_hw_level;
2156 aio.filled_zeros_for_draining = 100;
2157
2158 rc = no_stream(&aio.base, 1);
2159
2160 EXPECT_EQ(0, rc);
2161 EXPECT_EQ(1, cras_alsa_mmap_get_whole_buffer_called);
2162 EXPECT_EQ(0, cras_iodev_fill_odev_zeros_called);
2163 EXPECT_EQ(1, aio.free_running);
2164 }
2165
TEST_F(AlsaFreeRunTestSuite,EnterFreeRunNoSamples)2166 TEST_F(AlsaFreeRunTestSuite, EnterFreeRunNoSamples) {
2167 int rc, real_hw_level;
2168
2169 // Device is not in free run state. There is no sample to play.
2170 // Should enter free run state and fill whole buffer with zeros.
2171 real_hw_level = 0;
2172 cras_alsa_get_avail_frames_avail = BUFFER_SIZE - real_hw_level;
2173
2174 rc = no_stream(&aio.base, 1);
2175
2176 EXPECT_EQ(0, rc);
2177 EXPECT_EQ(1, cras_alsa_mmap_get_whole_buffer_called);
2178 EXPECT_EQ(0, cras_iodev_fill_odev_zeros_called);
2179 EXPECT_EQ(1, aio.free_running);
2180 }
2181
TEST_F(AlsaFreeRunTestSuite,IsFreeRunning)2182 TEST_F(AlsaFreeRunTestSuite, IsFreeRunning) {
2183 aio.free_running = 1;
2184 EXPECT_EQ(1, is_free_running(&aio.base));
2185
2186 aio.free_running = 0;
2187 EXPECT_EQ(0, is_free_running(&aio.base));
2188 }
2189
TEST_F(AlsaFreeRunTestSuite,LeaveFreeRunNotInFreeRunMoreRemain)2190 TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunNotInFreeRunMoreRemain) {
2191 int rc, real_hw_level;
2192
2193 // Compare min_buffer_level + min_cb_level with valid samples left.
2194 // 240 + 512 < 900 - 100, so we will get 900 - 100 in appl_ptr_ahead.
2195
2196 aio.free_running = 0;
2197 aio.filled_zeros_for_draining = 100;
2198 aio.base.min_buffer_level = 512;
2199 real_hw_level = 900;
2200 cras_alsa_get_avail_frames_avail = BUFFER_SIZE - real_hw_level;
2201
2202 rc = no_stream(&aio.base, 0);
2203
2204 EXPECT_EQ(0, rc);
2205 EXPECT_EQ(1, cras_alsa_resume_appl_ptr_called);
2206 EXPECT_EQ(800, cras_alsa_resume_appl_ptr_ahead);
2207 EXPECT_EQ(0, cras_iodev_fill_odev_zeros_frames);
2208 EXPECT_EQ(0, aio.free_running);
2209 EXPECT_EQ(0, aio.filled_zeros_for_draining);
2210 EXPECT_EQ(1, cras_iodev_reset_rate_estimator_called);
2211 }
2212
TEST_F(AlsaFreeRunTestSuite,LeaveFreeRunNotInFreeRunLessRemain)2213 TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunNotInFreeRunLessRemain) {
2214 int rc, real_hw_level;
2215
2216 // Compare min_buffer_level + min_cb_level with valid samples left.
2217 // 240 + 256 > 400 - 500, so we will get 240 + 256 in appl_ptr_ahead.
2218 // And it will fill 240 + 256 - 400 = 96 zeros frames into device.
2219
2220 aio.free_running = 0;
2221 aio.filled_zeros_for_draining = 500;
2222 aio.base.min_buffer_level = 256;
2223 real_hw_level = 400;
2224 cras_alsa_get_avail_frames_avail = BUFFER_SIZE - real_hw_level;
2225
2226 rc = no_stream(&aio.base, 0);
2227
2228 EXPECT_EQ(0, rc);
2229 EXPECT_EQ(1, cras_alsa_resume_appl_ptr_called);
2230 EXPECT_EQ(aio.base.min_buffer_level + aio.base.min_cb_level,
2231 cras_alsa_resume_appl_ptr_ahead);
2232 EXPECT_EQ(96, cras_iodev_fill_odev_zeros_frames);
2233 EXPECT_EQ(0, aio.free_running);
2234 EXPECT_EQ(0, aio.filled_zeros_for_draining);
2235 EXPECT_EQ(1, cras_iodev_reset_rate_estimator_called);
2236 }
2237
TEST_F(AlsaFreeRunTestSuite,LeaveFreeRunInFreeRun)2238 TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunInFreeRun) {
2239 int rc;
2240
2241 aio.free_running = 1;
2242 aio.filled_zeros_for_draining = 100;
2243 aio.base.min_buffer_level = 512;
2244
2245 rc = no_stream(&aio.base, 0);
2246
2247 EXPECT_EQ(0, rc);
2248 EXPECT_EQ(1, cras_alsa_resume_appl_ptr_called);
2249 EXPECT_EQ(aio.base.min_buffer_level + aio.base.min_cb_level,
2250 cras_alsa_resume_appl_ptr_ahead);
2251 EXPECT_EQ(0, aio.free_running);
2252 EXPECT_EQ(0, aio.filled_zeros_for_draining);
2253 EXPECT_EQ(1, cras_iodev_reset_rate_estimator_called);
2254 }
2255
2256 // Reuse AlsaFreeRunTestSuite for output underrun handling because they are
2257 // similar.
TEST_F(AlsaFreeRunTestSuite,OutputUnderrun)2258 TEST_F(AlsaFreeRunTestSuite, OutputUnderrun) {
2259 int rc;
2260 int16_t* zeros;
2261 snd_pcm_uframes_t offset;
2262
2263 // Ask alsa_io to handle output underrun.
2264 rc = alsa_output_underrun(&aio.base);
2265 EXPECT_EQ(0, rc);
2266
2267 // mmap buffer should be filled with zeros.
2268 zeros = (int16_t*)calloc(BUFFER_SIZE * 2, sizeof(*zeros));
2269 EXPECT_EQ(0, memcmp(zeros, cras_alsa_mmap_begin_buffer, BUFFER_SIZE * 2 * 2));
2270
2271 // appl_ptr should be moved to min_buffer_level + 1.5 * min_cb_level ahead of
2272 // hw_ptr.
2273 offset = aio.base.min_buffer_level + aio.base.min_cb_level +
2274 aio.base.min_cb_level / 2;
2275 EXPECT_EQ(1, cras_alsa_resume_appl_ptr_called);
2276 EXPECT_EQ(offset, cras_alsa_resume_appl_ptr_ahead);
2277
2278 free(zeros);
2279 }
2280
TEST(AlsaHotwordNode,HotwordTriggeredSendMessage)2281 TEST(AlsaHotwordNode, HotwordTriggeredSendMessage) {
2282 struct cras_iodev* iodev;
2283 struct cras_audio_format format;
2284 struct alsa_input_node alsa_node;
2285 struct cras_ionode* node = &alsa_node.base;
2286 int rc;
2287
2288 ResetStubData();
2289 iodev = alsa_iodev_create_with_default_parameters(
2290 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
2291 CRAS_STREAM_INPUT);
2292 format.frame_rate = 16000;
2293 format.num_channels = 1;
2294 cras_iodev_set_format(iodev, &format);
2295
2296 memset(&alsa_node, 0, sizeof(alsa_node));
2297 node->dev = iodev;
2298 strcpy(node->name, HOTWORD_DEV);
2299 set_node_initial_state(node, ALSA_CARD_TYPE_INTERNAL);
2300 EXPECT_EQ(CRAS_NODE_TYPE_HOTWORD, node->type);
2301
2302 iodev->active_node = node;
2303 iodev->open_dev(iodev);
2304 rc = iodev->configure_dev(iodev);
2305 free(fake_format);
2306 ASSERT_EQ(0, rc);
2307
2308 ASSERT_NE(reinterpret_cast<thread_callback>(NULL), audio_thread_cb);
2309 audio_thread_cb(audio_thread_cb_data, POLLIN);
2310 EXPECT_EQ(1, hotword_send_triggered_msg_called);
2311 alsa_iodev_destroy(iodev);
2312 }
2313
TEST(AlsaGetValidFrames,GetValidFramesNormalState)2314 TEST(AlsaGetValidFrames, GetValidFramesNormalState) {
2315 struct cras_iodev* iodev;
2316 struct alsa_io* aio;
2317 struct timespec tstamp;
2318 int rc;
2319
2320 ResetStubData();
2321 iodev = alsa_iodev_create_with_default_parameters(
2322 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
2323 CRAS_STREAM_OUTPUT);
2324 aio = (struct alsa_io*)iodev;
2325
2326 aio->free_running = 0;
2327 aio->filled_zeros_for_draining = 200;
2328 cras_alsa_get_avail_frames_avail = iodev->buffer_size - 500;
2329 cras_alsa_get_avail_frames_ret = 0;
2330 clock_gettime_retspec.tv_sec = 123;
2331 clock_gettime_retspec.tv_nsec = 321;
2332 rc = iodev->get_valid_frames(iodev, &tstamp);
2333 EXPECT_EQ(rc, 300);
2334 EXPECT_EQ(tstamp.tv_sec, clock_gettime_retspec.tv_sec);
2335 EXPECT_EQ(tstamp.tv_nsec, clock_gettime_retspec.tv_nsec);
2336
2337 alsa_iodev_destroy(iodev);
2338 }
2339
TEST(AlsaGetValidFrames,GetValidFramesFreeRunning)2340 TEST(AlsaGetValidFrames, GetValidFramesFreeRunning) {
2341 struct cras_iodev* iodev;
2342 struct alsa_io* aio;
2343 struct timespec tstamp;
2344 int rc;
2345
2346 ResetStubData();
2347 iodev = alsa_iodev_create_with_default_parameters(
2348 0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
2349 CRAS_STREAM_OUTPUT);
2350 aio = (struct alsa_io*)iodev;
2351
2352 aio->free_running = 1;
2353 clock_gettime_retspec.tv_sec = 123;
2354 clock_gettime_retspec.tv_nsec = 321;
2355 rc = iodev->get_valid_frames(iodev, &tstamp);
2356 EXPECT_EQ(rc, 0);
2357 EXPECT_EQ(tstamp.tv_sec, clock_gettime_retspec.tv_sec);
2358 EXPECT_EQ(tstamp.tv_nsec, clock_gettime_retspec.tv_nsec);
2359
2360 alsa_iodev_destroy(iodev);
2361 }
2362
2363 } // namespace
2364
main(int argc,char ** argv)2365 int main(int argc, char** argv) {
2366 ::testing::InitGoogleTest(&argc, argv);
2367 openlog(NULL, LOG_PERROR, LOG_USER);
2368 return RUN_ALL_TESTS();
2369 }
2370
2371 // Stubs
2372
2373 extern "C" {
2374
2375 // From iodev.
cras_iodev_list_add_output(struct cras_iodev * output)2376 int cras_iodev_list_add_output(struct cras_iodev* output) {
2377 return 0;
2378 }
cras_iodev_list_rm_output(struct cras_iodev * dev)2379 int cras_iodev_list_rm_output(struct cras_iodev* dev) {
2380 return 0;
2381 }
2382
cras_iodev_list_add_input(struct cras_iodev * input)2383 int cras_iodev_list_add_input(struct cras_iodev* input) {
2384 return 0;
2385 }
cras_iodev_list_rm_input(struct cras_iodev * dev)2386 int cras_iodev_list_rm_input(struct cras_iodev* dev) {
2387 return 0;
2388 }
2389
cras_iodev_list_get_hotword_models(cras_node_id_t node_id)2390 char* cras_iodev_list_get_hotword_models(cras_node_id_t node_id) {
2391 return NULL;
2392 }
2393
cras_iodev_list_set_hotword_model(cras_node_id_t node_id,const char * model_name)2394 int cras_iodev_list_set_hotword_model(cras_node_id_t node_id,
2395 const char* model_name) {
2396 return 0;
2397 }
2398
cras_iodev_list_suspend_hotword_streams()2399 int cras_iodev_list_suspend_hotword_streams() {
2400 return 0;
2401 }
2402
cras_iodev_list_resume_hotword_stream()2403 int cras_iodev_list_resume_hotword_stream() {
2404 return 0;
2405 }
2406
cras_iodev_list_get_audio_thread()2407 struct audio_thread* cras_iodev_list_get_audio_thread() {
2408 return NULL;
2409 }
2410
2411 // From alsa helper.
cras_alsa_set_channel_map(snd_pcm_t * handle,struct cras_audio_format * fmt)2412 int cras_alsa_set_channel_map(snd_pcm_t* handle,
2413 struct cras_audio_format* fmt) {
2414 return 0;
2415 }
cras_alsa_get_channel_map(snd_pcm_t * handle,struct cras_audio_format * fmt)2416 int cras_alsa_get_channel_map(snd_pcm_t* handle,
2417 struct cras_audio_format* fmt) {
2418 return 0;
2419 }
cras_alsa_pcm_open(snd_pcm_t ** handle,const char * dev,snd_pcm_stream_t stream)2420 int cras_alsa_pcm_open(snd_pcm_t** handle,
2421 const char* dev,
2422 snd_pcm_stream_t stream) {
2423 *handle = (snd_pcm_t*)0x24;
2424 cras_alsa_open_called++;
2425 return 0;
2426 }
cras_alsa_pcm_close(snd_pcm_t * handle)2427 int cras_alsa_pcm_close(snd_pcm_t* handle) {
2428 return 0;
2429 }
cras_alsa_pcm_start(snd_pcm_t * handle)2430 int cras_alsa_pcm_start(snd_pcm_t* handle) {
2431 cras_alsa_start_called++;
2432 return 0;
2433 }
cras_alsa_pcm_drain(snd_pcm_t * handle)2434 int cras_alsa_pcm_drain(snd_pcm_t* handle) {
2435 return 0;
2436 }
cras_alsa_fill_properties(snd_pcm_t * handle,size_t ** rates,size_t ** channel_counts,snd_pcm_format_t ** formats)2437 int cras_alsa_fill_properties(snd_pcm_t* handle,
2438 size_t** rates,
2439 size_t** channel_counts,
2440 snd_pcm_format_t** formats) {
2441 *rates = (size_t*)malloc(sizeof(**rates) * 3);
2442 (*rates)[0] = 44100;
2443 (*rates)[1] = 48000;
2444 (*rates)[2] = 0;
2445
2446 if (cras_alsa_support_8_channels) { // Support up to 8 channels.
2447 *channel_counts = (size_t*)malloc(sizeof(**channel_counts) * 6);
2448 (*channel_counts)[0] = 6;
2449 (*channel_counts)[1] = 4;
2450 (*channel_counts)[2] = 2;
2451 (*channel_counts)[3] = 1;
2452 (*channel_counts)[4] = 8;
2453 (*channel_counts)[5] = 0;
2454 } else { // Support 2 channels only.
2455 *channel_counts = (size_t*)malloc(sizeof(**channel_counts) * 2);
2456 (*channel_counts)[0] = 2;
2457 (*channel_counts)[1] = 0;
2458 }
2459
2460 *formats = (snd_pcm_format_t*)malloc(sizeof(**formats) * 2);
2461 (*formats)[0] = SND_PCM_FORMAT_S16_LE;
2462 (*formats)[1] = (snd_pcm_format_t)0;
2463
2464 cras_alsa_fill_properties_called++;
2465 return 0;
2466 }
cras_alsa_set_hwparams(snd_pcm_t * handle,struct cras_audio_format * format,snd_pcm_uframes_t * buffer_size,int period_wakeup,unsigned int dma_period_time)2467 int cras_alsa_set_hwparams(snd_pcm_t* handle,
2468 struct cras_audio_format* format,
2469 snd_pcm_uframes_t* buffer_size,
2470 int period_wakeup,
2471 unsigned int dma_period_time) {
2472 return 0;
2473 }
cras_alsa_set_swparams(snd_pcm_t * handle)2474 int cras_alsa_set_swparams(snd_pcm_t* handle) {
2475 return 0;
2476 }
cras_alsa_get_avail_frames(snd_pcm_t * handle,snd_pcm_uframes_t buf_size,snd_pcm_uframes_t severe_underrun_frames,const char * dev_name,snd_pcm_uframes_t * used,struct timespec * tstamp)2477 int cras_alsa_get_avail_frames(snd_pcm_t* handle,
2478 snd_pcm_uframes_t buf_size,
2479 snd_pcm_uframes_t severe_underrun_frames,
2480 const char* dev_name,
2481 snd_pcm_uframes_t* used,
2482 struct timespec* tstamp) {
2483 *used = cras_alsa_get_avail_frames_avail;
2484 clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
2485 return cras_alsa_get_avail_frames_ret;
2486 }
cras_alsa_get_delay_frames(snd_pcm_t * handle,snd_pcm_uframes_t buf_size,snd_pcm_sframes_t * delay)2487 int cras_alsa_get_delay_frames(snd_pcm_t* handle,
2488 snd_pcm_uframes_t buf_size,
2489 snd_pcm_sframes_t* delay) {
2490 *delay = 0;
2491 return 0;
2492 }
cras_alsa_mmap_begin(snd_pcm_t * handle,unsigned int format_bytes,uint8_t ** dst,snd_pcm_uframes_t * offset,snd_pcm_uframes_t * frames)2493 int cras_alsa_mmap_begin(snd_pcm_t* handle,
2494 unsigned int format_bytes,
2495 uint8_t** dst,
2496 snd_pcm_uframes_t* offset,
2497 snd_pcm_uframes_t* frames) {
2498 *dst = cras_alsa_mmap_begin_buffer;
2499 *frames = cras_alsa_mmap_begin_frames;
2500 return 0;
2501 }
cras_alsa_mmap_commit(snd_pcm_t * handle,snd_pcm_uframes_t offset,snd_pcm_uframes_t frames)2502 int cras_alsa_mmap_commit(snd_pcm_t* handle,
2503 snd_pcm_uframes_t offset,
2504 snd_pcm_uframes_t frames) {
2505 return 0;
2506 }
cras_alsa_attempt_resume(snd_pcm_t * handle)2507 int cras_alsa_attempt_resume(snd_pcm_t* handle) {
2508 cras_alsa_attempt_resume_called++;
2509 return 0;
2510 }
2511
2512 // ALSA stubs.
snd_pcm_format_physical_width(snd_pcm_format_t format)2513 int snd_pcm_format_physical_width(snd_pcm_format_t format) {
2514 return 16;
2515 }
2516
snd_pcm_state(snd_pcm_t * handle)2517 snd_pcm_state_t snd_pcm_state(snd_pcm_t* handle) {
2518 return snd_pcm_state_ret;
2519 }
2520
snd_strerror(int errnum)2521 const char* snd_strerror(int errnum) {
2522 return "Alsa Error in UT";
2523 }
2524
cras_alsa_mixer_get_control_for_section(struct cras_alsa_mixer * cras_mixer,const struct ucm_section * section)2525 struct mixer_control* cras_alsa_mixer_get_control_for_section(
2526 struct cras_alsa_mixer* cras_mixer,
2527 const struct ucm_section* section) {
2528 cras_alsa_mixer_get_control_for_section_called++;
2529 return cras_alsa_mixer_get_control_for_section_return_value;
2530 }
2531
cras_alsa_mixer_get_control_name(const struct mixer_control * control)2532 const char* cras_alsa_mixer_get_control_name(
2533 const struct mixer_control* control) {
2534 ControlNameMap::iterator it;
2535 cras_alsa_mixer_get_control_name_called++;
2536 it = cras_alsa_mixer_get_control_name_values.find(control);
2537 if (it == cras_alsa_mixer_get_control_name_values.end())
2538 return "";
2539 return it->second.c_str();
2540 }
2541
2542 // From system_state.
cras_system_get_volume()2543 size_t cras_system_get_volume() {
2544 sys_get_volume_called++;
2545 return sys_get_volume_return_value;
2546 }
2547
cras_system_get_mute()2548 int cras_system_get_mute() {
2549 sys_get_mute_called++;
2550 return sys_get_mute_return_value;
2551 }
2552
cras_system_get_capture_mute()2553 int cras_system_get_capture_mute() {
2554 sys_get_capture_mute_called++;
2555 return sys_get_capture_mute_return_value;
2556 }
2557
cras_system_set_volume_limits(long min,long max)2558 void cras_system_set_volume_limits(long min, long max) {
2559 sys_set_volume_limits_called++;
2560 }
2561
cras_system_get_noise_cancellation_enabled()2562 bool cras_system_get_noise_cancellation_enabled() {
2563 return false;
2564 }
2565
2566 // From cras_alsa_mixer.
cras_alsa_mixer_set_dBFS(struct cras_alsa_mixer * m,long dB_level,struct mixer_control * output)2567 void cras_alsa_mixer_set_dBFS(struct cras_alsa_mixer* m,
2568 long dB_level,
2569 struct mixer_control* output) {
2570 alsa_mixer_set_dBFS_called++;
2571 alsa_mixer_set_dBFS_value = dB_level;
2572 alsa_mixer_set_dBFS_output = output;
2573 }
2574
cras_alsa_mixer_set_mute(struct cras_alsa_mixer * cras_mixer,int muted,struct mixer_control * mixer_output)2575 void cras_alsa_mixer_set_mute(struct cras_alsa_mixer* cras_mixer,
2576 int muted,
2577 struct mixer_control* mixer_output) {
2578 alsa_mixer_set_mute_called++;
2579 alsa_mixer_set_mute_value = muted;
2580 alsa_mixer_set_mute_output = mixer_output;
2581 }
2582
cras_alsa_mixer_get_dB_range(struct cras_alsa_mixer * cras_mixer)2583 long cras_alsa_mixer_get_dB_range(struct cras_alsa_mixer* cras_mixer) {
2584 alsa_mixer_get_dB_range_called++;
2585 return alsa_mixer_get_dB_range_value;
2586 }
2587
cras_alsa_mixer_get_output_dB_range(struct mixer_control * mixer_output)2588 long cras_alsa_mixer_get_output_dB_range(struct mixer_control* mixer_output) {
2589 alsa_mixer_get_output_dB_range_called++;
2590 return alsa_mixer_get_output_dB_range_value;
2591 }
2592
cras_alsa_mixer_set_capture_dBFS(struct cras_alsa_mixer * m,long dB_level,struct mixer_control * mixer_input)2593 void cras_alsa_mixer_set_capture_dBFS(struct cras_alsa_mixer* m,
2594 long dB_level,
2595 struct mixer_control* mixer_input) {
2596 alsa_mixer_set_capture_dBFS_called++;
2597 alsa_mixer_set_capture_dBFS_value = dB_level;
2598 alsa_mixer_set_capture_dBFS_input = mixer_input;
2599 }
2600
cras_alsa_mixer_set_capture_mute(struct cras_alsa_mixer * m,int mute,struct mixer_control * mixer_input)2601 void cras_alsa_mixer_set_capture_mute(struct cras_alsa_mixer* m,
2602 int mute,
2603 struct mixer_control* mixer_input) {
2604 alsa_mixer_set_capture_mute_called++;
2605 alsa_mixer_set_capture_mute_value = mute;
2606 alsa_mixer_set_capture_mute_input = mixer_input;
2607 }
2608
cras_alsa_mixer_list_outputs(struct cras_alsa_mixer * cras_mixer,cras_alsa_mixer_control_callback cb,void * callback_arg)2609 void cras_alsa_mixer_list_outputs(struct cras_alsa_mixer* cras_mixer,
2610 cras_alsa_mixer_control_callback cb,
2611 void* callback_arg) {
2612 cras_alsa_mixer_list_outputs_called++;
2613 for (size_t i = 0; i < cras_alsa_mixer_list_outputs_outputs_length; i++) {
2614 cb(cras_alsa_mixer_list_outputs_outputs[i], callback_arg);
2615 }
2616 }
2617
cras_alsa_mixer_list_inputs(struct cras_alsa_mixer * cras_mixer,cras_alsa_mixer_control_callback cb,void * callback_arg)2618 void cras_alsa_mixer_list_inputs(struct cras_alsa_mixer* cras_mixer,
2619 cras_alsa_mixer_control_callback cb,
2620 void* callback_arg) {
2621 cras_alsa_mixer_list_inputs_called++;
2622 for (size_t i = 0; i < cras_alsa_mixer_list_inputs_outputs_length; i++) {
2623 cb(cras_alsa_mixer_list_inputs_outputs[i], callback_arg);
2624 }
2625 }
2626
cras_alsa_mixer_set_output_active_state(struct mixer_control * output,int active)2627 int cras_alsa_mixer_set_output_active_state(struct mixer_control* output,
2628 int active) {
2629 cras_alsa_mixer_set_output_active_state_called++;
2630 cras_alsa_mixer_set_output_active_state_outputs.push_back(output);
2631 cras_alsa_mixer_set_output_active_state_values.push_back(active);
2632 return 0;
2633 }
2634
cras_volume_curve_destroy(struct cras_volume_curve * curve)2635 void cras_volume_curve_destroy(struct cras_volume_curve* curve) {}
2636
cras_alsa_mixer_get_minimum_capture_gain(struct cras_alsa_mixer * cmix,struct mixer_control * mixer_input)2637 long cras_alsa_mixer_get_minimum_capture_gain(
2638 struct cras_alsa_mixer* cmix,
2639 struct mixer_control* mixer_input) {
2640 cras_alsa_mixer_get_minimum_capture_gain_called++;
2641 cras_alsa_mixer_get_minimum_capture_gain_mixer_input = mixer_input;
2642 return cras_alsa_mixer_get_minimum_capture_gain_ret_value;
2643 }
2644
cras_alsa_mixer_get_maximum_capture_gain(struct cras_alsa_mixer * cmix,struct mixer_control * mixer_input)2645 long cras_alsa_mixer_get_maximum_capture_gain(
2646 struct cras_alsa_mixer* cmix,
2647 struct mixer_control* mixer_input) {
2648 cras_alsa_mixer_get_maximum_capture_gain_called++;
2649 cras_alsa_mixer_get_maximum_capture_gain_mixer_input = mixer_input;
2650 return cras_alsa_mixer_get_maximum_capture_gain_ret_value;
2651 }
2652
cras_alsa_mixer_has_main_volume(const struct cras_alsa_mixer * cras_mixer)2653 int cras_alsa_mixer_has_main_volume(const struct cras_alsa_mixer* cras_mixer) {
2654 return 1;
2655 }
2656
cras_alsa_mixer_has_volume(const struct mixer_control * mixer_control)2657 int cras_alsa_mixer_has_volume(const struct mixer_control* mixer_control) {
2658 return 1;
2659 }
2660
2661 // From cras_alsa_jack
cras_alsa_jack_list_create(unsigned int card_index,const char * card_name,unsigned int device_index,int check_gpio_jack,struct cras_alsa_mixer * mixer,struct cras_use_case_mgr * ucm,snd_hctl_t * hctl,enum CRAS_STREAM_DIRECTION direction,jack_state_change_callback * cb,void * cb_data)2662 struct cras_alsa_jack_list* cras_alsa_jack_list_create(
2663 unsigned int card_index,
2664 const char* card_name,
2665 unsigned int device_index,
2666 int check_gpio_jack,
2667 struct cras_alsa_mixer* mixer,
2668 struct cras_use_case_mgr* ucm,
2669 snd_hctl_t* hctl,
2670 enum CRAS_STREAM_DIRECTION direction,
2671 jack_state_change_callback* cb,
2672 void* cb_data) {
2673 cras_alsa_jack_list_create_called++;
2674 cras_alsa_jack_list_create_cb = cb;
2675 cras_alsa_jack_list_create_cb_data = cb_data;
2676 return (struct cras_alsa_jack_list*)0xfee;
2677 }
2678
cras_alsa_jack_list_find_jacks_by_name_matching(struct cras_alsa_jack_list * jack_list)2679 int cras_alsa_jack_list_find_jacks_by_name_matching(
2680 struct cras_alsa_jack_list* jack_list) {
2681 cras_alsa_jack_list_find_jacks_by_name_matching_called++;
2682 return 0;
2683 }
2684
cras_alsa_jack_list_add_jack_for_section(struct cras_alsa_jack_list * jack_list,struct ucm_section * ucm_section,struct cras_alsa_jack ** result_jack)2685 int cras_alsa_jack_list_add_jack_for_section(
2686 struct cras_alsa_jack_list* jack_list,
2687 struct ucm_section* ucm_section,
2688 struct cras_alsa_jack** result_jack) {
2689 cras_alsa_jack_list_add_jack_for_section_called++;
2690 if (result_jack)
2691 *result_jack = cras_alsa_jack_list_add_jack_for_section_result_jack;
2692 return 0;
2693 }
2694
cras_alsa_jack_list_destroy(struct cras_alsa_jack_list * jack_list)2695 void cras_alsa_jack_list_destroy(struct cras_alsa_jack_list* jack_list) {
2696 cras_alsa_jack_list_destroy_called++;
2697 }
2698
cras_alsa_jack_list_has_hctl_jacks(struct cras_alsa_jack_list * jack_list)2699 int cras_alsa_jack_list_has_hctl_jacks(struct cras_alsa_jack_list* jack_list) {
2700 return cras_alsa_jack_list_has_hctl_jacks_return_val;
2701 }
2702
cras_alsa_jack_list_report(const struct cras_alsa_jack_list * jack_list)2703 void cras_alsa_jack_list_report(const struct cras_alsa_jack_list* jack_list) {}
2704
cras_alsa_jack_enable_ucm(const struct cras_alsa_jack * jack,int enable)2705 void cras_alsa_jack_enable_ucm(const struct cras_alsa_jack* jack, int enable) {
2706 cras_alsa_jack_enable_ucm_called++;
2707 }
2708
cras_alsa_jack_get_name(const struct cras_alsa_jack * jack)2709 const char* cras_alsa_jack_get_name(const struct cras_alsa_jack* jack) {
2710 cras_alsa_jack_get_name_called++;
2711 return cras_alsa_jack_get_name_ret_value;
2712 }
2713
ucm_get_dsp_name_for_dev(struct cras_use_case_mgr * mgr,const char * dev)2714 const char* ucm_get_dsp_name_for_dev(struct cras_use_case_mgr* mgr,
2715 const char* dev) {
2716 DspNameMap::iterator it;
2717 ucm_get_dsp_name_for_dev_called++;
2718 if (!dev)
2719 return NULL;
2720 it = ucm_get_dsp_name_for_dev_values.find(dev);
2721 if (it == ucm_get_dsp_name_for_dev_values.end())
2722 return NULL;
2723 return strdup(it->second.c_str());
2724 }
2725
cras_alsa_jack_get_mixer_output(const struct cras_alsa_jack * jack)2726 struct mixer_control* cras_alsa_jack_get_mixer_output(
2727 const struct cras_alsa_jack* jack) {
2728 return cras_alsa_jack_get_mixer_output_ret;
2729 }
2730
cras_alsa_jack_get_mixer_input(const struct cras_alsa_jack * jack)2731 struct mixer_control* cras_alsa_jack_get_mixer_input(
2732 const struct cras_alsa_jack* jack) {
2733 return cras_alsa_jack_get_mixer_input_ret;
2734 }
2735
ucm_set_enabled(struct cras_use_case_mgr * mgr,const char * dev,int enabled)2736 int ucm_set_enabled(struct cras_use_case_mgr* mgr,
2737 const char* dev,
2738 int enabled) {
2739 ucm_set_enabled_called++;
2740 return 0;
2741 }
2742
ucm_get_flag(struct cras_use_case_mgr * mgr,const char * flag_name)2743 char* ucm_get_flag(struct cras_use_case_mgr* mgr, const char* flag_name) {
2744 if ((!strcmp(flag_name, "AutoUnplugInputNode") &&
2745 auto_unplug_input_node_ret) ||
2746 (!strcmp(flag_name, "AutoUnplugOutputNode") &&
2747 auto_unplug_output_node_ret)) {
2748 char* ret = (char*)malloc(8);
2749 snprintf(ret, 8, "%s", "1");
2750 return ret;
2751 }
2752
2753 return NULL;
2754 }
2755
ucm_swap_mode_exists(struct cras_use_case_mgr * mgr)2756 int ucm_swap_mode_exists(struct cras_use_case_mgr* mgr) {
2757 return ucm_swap_mode_exists_ret_value;
2758 }
2759
ucm_enable_swap_mode(struct cras_use_case_mgr * mgr,const char * node_name,int enable)2760 int ucm_enable_swap_mode(struct cras_use_case_mgr* mgr,
2761 const char* node_name,
2762 int enable) {
2763 ucm_enable_swap_mode_called++;
2764 return ucm_enable_swap_mode_ret_value;
2765 }
2766
ucm_get_min_buffer_level(struct cras_use_case_mgr * mgr,unsigned int * level)2767 int ucm_get_min_buffer_level(struct cras_use_case_mgr* mgr,
2768 unsigned int* level) {
2769 *level = 0;
2770 return 0;
2771 }
2772
ucm_get_disable_software_volume(struct cras_use_case_mgr * mgr)2773 unsigned int ucm_get_disable_software_volume(struct cras_use_case_mgr* mgr) {
2774 return 0;
2775 }
2776
ucm_get_hotword_models(struct cras_use_case_mgr * mgr)2777 char* ucm_get_hotword_models(struct cras_use_case_mgr* mgr) {
2778 return NULL;
2779 }
2780
ucm_set_hotword_model(struct cras_use_case_mgr * mgr,const char * model)2781 int ucm_set_hotword_model(struct cras_use_case_mgr* mgr, const char* model) {
2782 return 0;
2783 }
2784
ucm_get_dma_period_for_dev(struct cras_use_case_mgr * mgr,const char * dev)2785 unsigned int ucm_get_dma_period_for_dev(struct cras_use_case_mgr* mgr,
2786 const char* dev) {
2787 ucm_get_dma_period_for_dev_called++;
2788 return ucm_get_dma_period_for_dev_ret;
2789 }
2790
ucm_get_sample_rate_for_dev(struct cras_use_case_mgr * mgr,const char * dev,enum CRAS_STREAM_DIRECTION direction)2791 int ucm_get_sample_rate_for_dev(struct cras_use_case_mgr* mgr,
2792 const char* dev,
2793 enum CRAS_STREAM_DIRECTION direction) {
2794 return -EINVAL;
2795 }
2796
ucm_get_capture_chmap_for_dev(struct cras_use_case_mgr * mgr,const char * dev,int8_t * channel_layout)2797 int ucm_get_capture_chmap_for_dev(struct cras_use_case_mgr* mgr,
2798 const char* dev,
2799 int8_t* channel_layout) {
2800 return -EINVAL;
2801 }
2802
ucm_get_preempt_hotword(struct cras_use_case_mgr * mgr,const char * dev)2803 int ucm_get_preempt_hotword(struct cras_use_case_mgr* mgr, const char* dev) {
2804 return 0;
2805 }
2806
ucm_get_channels_for_dev(struct cras_use_case_mgr * mgr,const char * dev,enum CRAS_STREAM_DIRECTION direction,size_t * channels)2807 int ucm_get_channels_for_dev(struct cras_use_case_mgr* mgr,
2808 const char* dev,
2809 enum CRAS_STREAM_DIRECTION direction,
2810 size_t* channels) {
2811 return -EINVAL;
2812 }
2813
ucm_node_noise_cancellation_exists(struct cras_use_case_mgr * mgr,const char * node_name)2814 int ucm_node_noise_cancellation_exists(struct cras_use_case_mgr* mgr,
2815 const char* node_name) {
2816 return 0;
2817 }
2818
ucm_enable_node_noise_cancellation(struct cras_use_case_mgr * mgr,const char * node_name,int enable)2819 int ucm_enable_node_noise_cancellation(struct cras_use_case_mgr* mgr,
2820 const char* node_name,
2821 int enable) {
2822 return 0;
2823 }
2824
cras_volume_curve_create_default()2825 struct cras_volume_curve* cras_volume_curve_create_default() {
2826 return &default_curve;
2827 }
2828
cras_card_config_get_volume_curve_for_control(const struct cras_card_config * card_config,const char * control_name)2829 struct cras_volume_curve* cras_card_config_get_volume_curve_for_control(
2830 const struct cras_card_config* card_config,
2831 const char* control_name) {
2832 VolCurveMap::iterator it;
2833 cras_card_config_get_volume_curve_for_control_called++;
2834 if (!control_name)
2835 return NULL;
2836 it = cras_card_config_get_volume_curve_vals.find(control_name);
2837 if (it == cras_card_config_get_volume_curve_vals.end())
2838 return NULL;
2839 return it->second;
2840 }
2841
cras_iodev_free_format(struct cras_iodev * iodev)2842 void cras_iodev_free_format(struct cras_iodev* iodev) {}
2843
cras_iodev_set_format(struct cras_iodev * iodev,const struct cras_audio_format * fmt)2844 int cras_iodev_set_format(struct cras_iodev* iodev,
2845 const struct cras_audio_format* fmt) {
2846 fake_format = (struct cras_audio_format*)calloc(1, sizeof(cras_audio_format));
2847 // Copy the content of format from fmt into format of iodev.
2848 memcpy(fake_format, fmt, sizeof(cras_audio_format));
2849 iodev->format = fake_format;
2850 return 0;
2851 }
2852
audio_thread_create()2853 struct audio_thread* audio_thread_create() {
2854 return reinterpret_cast<audio_thread*>(0x323);
2855 }
2856
audio_thread_destroy(audio_thread * thread)2857 void audio_thread_destroy(audio_thread* thread) {}
2858
cras_iodev_update_dsp(struct cras_iodev * iodev)2859 void cras_iodev_update_dsp(struct cras_iodev* iodev) {
2860 cras_iodev_update_dsp_called++;
2861 cras_iodev_update_dsp_name = iodev->dsp_name ?: "";
2862 }
2863
cras_iodev_set_node_plugged(struct cras_ionode * ionode,int plugged)2864 void cras_iodev_set_node_plugged(struct cras_ionode* ionode, int plugged) {
2865 cras_iodev_set_node_plugged_called++;
2866 cras_iodev_set_node_plugged_ionode = ionode;
2867 cras_iodev_set_node_plugged_value = plugged;
2868 if (ionode)
2869 ionode->plugged = plugged;
2870 }
2871
cras_iodev_add_node(struct cras_iodev * iodev,struct cras_ionode * node)2872 void cras_iodev_add_node(struct cras_iodev* iodev, struct cras_ionode* node) {
2873 cras_iodev_add_node_called++;
2874 DL_APPEND(iodev->nodes, node);
2875 }
2876
cras_iodev_rm_node(struct cras_iodev * iodev,struct cras_ionode * node)2877 void cras_iodev_rm_node(struct cras_iodev* iodev, struct cras_ionode* node) {
2878 DL_DELETE(iodev->nodes, node);
2879 }
2880
cras_iodev_set_active_node(struct cras_iodev * iodev,struct cras_ionode * node)2881 void cras_iodev_set_active_node(struct cras_iodev* iodev,
2882 struct cras_ionode* node) {
2883 iodev->active_node = node;
2884 }
2885
cras_iodev_free_resources(struct cras_iodev * iodev)2886 void cras_iodev_free_resources(struct cras_iodev* iodev) {
2887 cras_iodev_free_resources_called++;
2888 }
2889
cras_alsa_jack_update_monitor_name(const struct cras_alsa_jack * jack,char * name_buf,unsigned int buf_size)2890 void cras_alsa_jack_update_monitor_name(const struct cras_alsa_jack* jack,
2891 char* name_buf,
2892 unsigned int buf_size) {
2893 if (cras_alsa_jack_update_monitor_fake_name)
2894 strcpy(name_buf, cras_alsa_jack_update_monitor_fake_name);
2895 }
2896
cras_alsa_jack_update_node_type(const struct cras_alsa_jack * jack,enum CRAS_NODE_TYPE * type)2897 void cras_alsa_jack_update_node_type(const struct cras_alsa_jack* jack,
2898 enum CRAS_NODE_TYPE* type) {
2899 cras_alsa_jack_update_node_type_called++;
2900 }
2901
cras_alsa_jack_get_ucm_device(const struct cras_alsa_jack * jack)2902 const char* cras_alsa_jack_get_ucm_device(const struct cras_alsa_jack* jack) {
2903 return NULL;
2904 }
2905
ucm_disable_all_hotword_models(struct cras_use_case_mgr * mgr)2906 void ucm_disable_all_hotword_models(struct cras_use_case_mgr* mgr) {}
2907
ucm_enable_hotword_model(struct cras_use_case_mgr * mgr)2908 int ucm_enable_hotword_model(struct cras_use_case_mgr* mgr) {
2909 return 0;
2910 }
2911
ucm_get_default_node_gain(struct cras_use_case_mgr * mgr,const char * dev,long * gain)2912 int ucm_get_default_node_gain(struct cras_use_case_mgr* mgr,
2913 const char* dev,
2914 long* gain) {
2915 if (ucm_get_default_node_gain_values.find(dev) ==
2916 ucm_get_default_node_gain_values.end())
2917 return 1;
2918
2919 *gain = ucm_get_default_node_gain_values[dev];
2920 return 0;
2921 }
2922
ucm_get_intrinsic_sensitivity(struct cras_use_case_mgr * mgr,const char * dev,long * vol)2923 int ucm_get_intrinsic_sensitivity(struct cras_use_case_mgr* mgr,
2924 const char* dev,
2925 long* vol) {
2926 if (ucm_get_intrinsic_sensitivity_values.find(dev) ==
2927 ucm_get_intrinsic_sensitivity_values.end())
2928 return 1;
2929
2930 *vol = ucm_get_intrinsic_sensitivity_values[dev];
2931 return 0;
2932 }
2933
cras_iodev_init_audio_area(struct cras_iodev * iodev,int num_channels)2934 void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {}
2935
cras_iodev_free_audio_area(struct cras_iodev * iodev)2936 void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
2937
cras_iodev_reset_rate_estimator(const struct cras_iodev * iodev)2938 int cras_iodev_reset_rate_estimator(const struct cras_iodev* iodev) {
2939 cras_iodev_reset_rate_estimator_called++;
2940 return 0;
2941 }
2942
cras_iodev_frames_queued(struct cras_iodev * iodev,struct timespec * tstamp)2943 int cras_iodev_frames_queued(struct cras_iodev* iodev,
2944 struct timespec* tstamp) {
2945 clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
2946 return cras_iodev_frames_queued_ret;
2947 }
2948
cras_iodev_buffer_avail(struct cras_iodev * iodev,unsigned hw_level)2949 int cras_iodev_buffer_avail(struct cras_iodev* iodev, unsigned hw_level) {
2950 return cras_iodev_buffer_avail_ret;
2951 }
2952
cras_iodev_fill_odev_zeros(struct cras_iodev * odev,unsigned int frames)2953 int cras_iodev_fill_odev_zeros(struct cras_iodev* odev, unsigned int frames) {
2954 cras_iodev_fill_odev_zeros_called++;
2955 cras_iodev_fill_odev_zeros_frames = frames;
2956 return 0;
2957 }
2958
cras_audio_area_config_buf_pointers(struct cras_audio_area * area,const struct cras_audio_format * fmt,uint8_t * base_buffer)2959 void cras_audio_area_config_buf_pointers(struct cras_audio_area* area,
2960 const struct cras_audio_format* fmt,
2961 uint8_t* base_buffer) {}
2962
audio_thread_add_events_callback(int fd,thread_callback cb,void * data,int events)2963 void audio_thread_add_events_callback(int fd,
2964 thread_callback cb,
2965 void* data,
2966 int events) {
2967 audio_thread_cb = cb;
2968 audio_thread_cb_data = data;
2969 }
2970
audio_thread_rm_callback(int fd)2971 void audio_thread_rm_callback(int fd) {}
2972
audio_thread_rm_callback_sync(struct audio_thread * thread,int fd)2973 int audio_thread_rm_callback_sync(struct audio_thread* thread, int fd) {
2974 return 0;
2975 }
2976
cras_hotword_send_triggered_msg()2977 int cras_hotword_send_triggered_msg() {
2978 hotword_send_triggered_msg_called++;
2979 return 0;
2980 }
2981
snd_pcm_poll_descriptors_count(snd_pcm_t * pcm)2982 int snd_pcm_poll_descriptors_count(snd_pcm_t* pcm) {
2983 return 1;
2984 }
2985
snd_pcm_poll_descriptors(snd_pcm_t * pcm,struct pollfd * pfds,unsigned int space)2986 int snd_pcm_poll_descriptors(snd_pcm_t* pcm,
2987 struct pollfd* pfds,
2988 unsigned int space) {
2989 if (space >= 1) {
2990 pfds[0].events = POLLIN;
2991 pfds[0].fd = 99;
2992 }
2993 return 0;
2994 }
2995
is_utf8_string(const char * string)2996 int is_utf8_string(const char* string) {
2997 return is_utf8_string_ret_value;
2998 }
2999
cras_alsa_mmap_get_whole_buffer(snd_pcm_t * handle,uint8_t ** dst)3000 int cras_alsa_mmap_get_whole_buffer(snd_pcm_t* handle, uint8_t** dst) {
3001 snd_pcm_uframes_t offset, frames;
3002
3003 cras_alsa_mmap_get_whole_buffer_called++;
3004 return cras_alsa_mmap_begin(handle, 0, dst, &offset, &frames);
3005 }
3006
cras_alsa_resume_appl_ptr(snd_pcm_t * handle,snd_pcm_uframes_t ahead)3007 int cras_alsa_resume_appl_ptr(snd_pcm_t* handle, snd_pcm_uframes_t ahead) {
3008 cras_alsa_resume_appl_ptr_called++;
3009 cras_alsa_resume_appl_ptr_ahead = ahead;
3010 return 0;
3011 }
3012
cras_iodev_default_no_stream_playback(struct cras_iodev * odev,int enable)3013 int cras_iodev_default_no_stream_playback(struct cras_iodev* odev, int enable) {
3014 return 0;
3015 }
3016
cras_iodev_output_underrun(struct cras_iodev * odev,unsigned int hw_level,unsigned int frames_written)3017 int cras_iodev_output_underrun(struct cras_iodev* odev,
3018 unsigned int hw_level,
3019 unsigned int frames_written) {
3020 return odev->output_underrun(odev);
3021 }
3022
cras_iodev_state(const struct cras_iodev * iodev)3023 enum CRAS_IODEV_STATE cras_iodev_state(const struct cras_iodev* iodev) {
3024 return iodev->state;
3025 }
3026
cras_iodev_dsp_set_swap_mode_for_node(struct cras_iodev * iodev,struct cras_ionode * node,int enable)3027 int cras_iodev_dsp_set_swap_mode_for_node(struct cras_iodev* iodev,
3028 struct cras_ionode* node,
3029 int enable) {
3030 cras_iodev_dsp_set_swap_mode_for_node_called++;
3031 return 0;
3032 }
3033
cras_ramp_create()3034 struct cras_ramp* cras_ramp_create() {
3035 return (struct cras_ramp*)0x1;
3036 }
3037
3038 // From librt.
clock_gettime(clockid_t clk_id,struct timespec * tp)3039 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
3040 tp->tv_sec = clock_gettime_retspec.tv_sec;
3041 tp->tv_nsec = clock_gettime_retspec.tv_nsec;
3042 return 0;
3043 }
3044
3045 } // extern "C"
3046