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 <sys/param.h>
8 #include <syslog.h>
9
10 #include <map>
11
12 extern "C" {
13 #include "cras_alsa_card.h"
14 #include "cras_alsa_io.h"
15 #include "cras_alsa_mixer.h"
16 #include "cras_alsa_ucm.h"
17 #include "cras_iodev.h"
18 #include "cras_types.h"
19 #include "cras_util.h"
20 #include "utlist.h"
21 }
22
23 namespace {
24
25 static size_t cras_alsa_mixer_create_called;
26 static struct cras_alsa_mixer* cras_alsa_mixer_create_return;
27 static size_t cras_alsa_mixer_destroy_called;
28 static size_t cras_alsa_iodev_create_called;
29 static struct cras_iodev** cras_alsa_iodev_create_return;
30 static struct cras_iodev fake_dev1, fake_dev2, fake_dev3, fake_dev4;
31 static struct cras_iodev* cras_alsa_iodev_create_default_return[] = {
32 &fake_dev1,
33 &fake_dev2,
34 &fake_dev3,
35 &fake_dev4,
36 };
37 static size_t cras_alsa_iodev_create_return_size;
38 static size_t cras_alsa_iodev_legacy_complete_init_called;
39 static size_t cras_alsa_iodev_ucm_add_nodes_and_jacks_called;
40 static size_t cras_alsa_iodev_ucm_complete_init_called;
41 static size_t cras_alsa_iodev_destroy_called;
42 static struct cras_iodev* cras_alsa_iodev_destroy_arg;
43 static size_t cras_alsa_iodev_index_called;
44 static std::map<struct cras_iodev*, unsigned int> cras_alsa_iodev_index_return;
45 static int alsa_iodev_has_hctl_jacks_return;
46 static size_t snd_ctl_open_called;
47 static size_t snd_ctl_open_return;
48 static size_t snd_ctl_close_called;
49 static size_t snd_ctl_close_return;
50 static size_t snd_ctl_pcm_next_device_called;
51 static bool snd_ctl_pcm_next_device_return_error;
52 static int* snd_ctl_pcm_next_device_set_devs;
53 static size_t snd_ctl_pcm_next_device_set_devs_size;
54 static size_t snd_ctl_pcm_next_device_set_devs_index;
55 static size_t snd_ctl_pcm_info_called;
56 static int* snd_ctl_pcm_info_rets;
57 static size_t snd_ctl_pcm_info_rets_size;
58 static size_t snd_ctl_pcm_info_rets_index;
59 static size_t snd_ctl_card_info_called;
60 static int snd_ctl_card_info_ret;
61 static size_t snd_hctl_open_called;
62 static int snd_hctl_open_return_value;
63 static int snd_hctl_close_called;
64 static size_t snd_hctl_nonblock_called;
65 static snd_hctl_t* snd_hctl_open_pointer_val;
66 static size_t snd_hctl_load_called;
67 static int snd_hctl_load_return_value;
68 static struct pollfd* snd_hctl_poll_descriptors_fds;
69 static size_t snd_hctl_poll_descriptors_num_fds;
70 static size_t snd_hctl_poll_descriptors_called;
71 static size_t cras_system_add_select_fd_called;
72 static std::vector<int> cras_system_add_select_fd_values;
73 static size_t cras_system_rm_select_fd_called;
74 static std::vector<int> cras_system_rm_select_fd_values;
75 static size_t snd_hctl_handle_events_called;
76 static size_t iniparser_freedict_called;
77 static size_t iniparser_load_called;
78 static struct cras_device_blocklist* fake_blocklist;
79 static int cras_device_blocklist_check_retval;
80 static unsigned ucm_create_called;
81 static char ucm_create_name[100];
82 static unsigned ucm_destroy_called;
83 static size_t ucm_get_dev_for_mixer_called;
84 static size_t ucm_get_flag_called;
85 static char ucm_get_flag_name[65];
86 static char* device_config_dir;
87 static const char* cras_card_config_dir;
88 static struct mixer_name* ucm_get_coupled_mixer_names_return_value;
89 static struct mixer_name* coupled_output_names_value;
90 static int ucm_has_fully_specified_ucm_flag_return_value;
91 static int ucm_get_sections_called;
92 static struct mixer_name* ucm_get_main_volume_names_return_value;
93 static struct ucm_section* ucm_get_sections_return_value;
94 static size_t cras_alsa_mixer_add_controls_in_section_called;
95 static int cras_alsa_mixer_add_controls_in_section_return_value;
96 static int cras_alsa_mixer_add_main_volume_control_by_name_called;
97 static int cras_alsa_mixer_add_main_volume_control_by_name_return_value;
98 static int ucm_get_echo_reference_dev_name_for_dev_called;
99 static size_t cras_system_check_ignore_ucm_suffix_called;
100 static bool cras_system_check_ignore_ucm_suffix_value;
101 static const char* ucm_get_echo_reference_dev_name_for_dev_return_value[4];
102
ResetStubData()103 static void ResetStubData() {
104 cras_alsa_mixer_create_called = 0;
105 cras_alsa_mixer_create_return = reinterpret_cast<struct cras_alsa_mixer*>(1);
106 cras_alsa_mixer_destroy_called = 0;
107 cras_alsa_iodev_destroy_arg = NULL;
108 cras_alsa_iodev_create_called = 0;
109 cras_alsa_iodev_create_return = cras_alsa_iodev_create_default_return;
110 cras_alsa_iodev_create_return_size =
111 ARRAY_SIZE(cras_alsa_iodev_create_default_return);
112 cras_alsa_iodev_legacy_complete_init_called = 0;
113 cras_alsa_iodev_ucm_add_nodes_and_jacks_called = 0;
114 cras_alsa_iodev_ucm_complete_init_called = 0;
115 cras_alsa_iodev_destroy_called = 0;
116 cras_alsa_iodev_index_called = 0;
117 cras_alsa_iodev_index_return.clear();
118 alsa_iodev_has_hctl_jacks_return = 1;
119 snd_ctl_open_called = 0;
120 snd_ctl_open_return = 0;
121 snd_ctl_close_called = 0;
122 snd_ctl_close_return = 0;
123 snd_ctl_pcm_next_device_called = 0;
124 snd_ctl_pcm_next_device_return_error = false;
125 snd_ctl_pcm_next_device_set_devs_size = 0;
126 snd_ctl_pcm_next_device_set_devs_index = 0;
127 snd_ctl_pcm_info_called = 0;
128 snd_ctl_pcm_info_rets_size = 0;
129 snd_ctl_pcm_info_rets_index = 0;
130 snd_ctl_card_info_called = 0;
131 snd_ctl_card_info_ret = 0;
132 snd_hctl_open_called = 0;
133 snd_hctl_open_return_value = 0;
134 snd_hctl_open_pointer_val = reinterpret_cast<snd_hctl_t*>(0x4323);
135 snd_hctl_load_called = 0;
136 snd_hctl_load_return_value = 0;
137 snd_hctl_close_called = 0;
138 snd_hctl_nonblock_called = 0;
139 snd_hctl_poll_descriptors_num_fds = 0;
140 snd_hctl_poll_descriptors_called = 0;
141 snd_hctl_handle_events_called = 0;
142 snd_hctl_poll_descriptors_num_fds = 0;
143 snd_hctl_poll_descriptors_called = 0;
144 cras_system_add_select_fd_called = 0;
145 cras_system_add_select_fd_values.clear();
146 cras_system_rm_select_fd_called = 0;
147 cras_system_rm_select_fd_values.clear();
148 iniparser_freedict_called = 0;
149 iniparser_load_called = 0;
150 fake_blocklist = reinterpret_cast<struct cras_device_blocklist*>(3);
151 cras_device_blocklist_check_retval = 0;
152 ucm_create_called = 0;
153 memset(ucm_create_name, 0, sizeof(ucm_get_flag_name));
154 ucm_destroy_called = 0;
155 ucm_get_dev_for_mixer_called = 0;
156 ucm_get_flag_called = 0;
157 memset(ucm_get_flag_name, 0, sizeof(ucm_get_flag_name));
158 device_config_dir = reinterpret_cast<char*>(3);
159 cras_card_config_dir = NULL;
160 ucm_get_coupled_mixer_names_return_value = NULL;
161 ucm_get_main_volume_names_return_value = NULL;
162 mixer_name_free(coupled_output_names_value);
163 coupled_output_names_value = NULL;
164 ucm_has_fully_specified_ucm_flag_return_value = 0;
165 ucm_get_sections_called = 0;
166 ucm_get_sections_return_value = NULL;
167 cras_alsa_mixer_add_controls_in_section_called = 0;
168 cras_alsa_mixer_add_controls_in_section_return_value = 0;
169 cras_alsa_mixer_add_main_volume_control_by_name_called = 0;
170 cras_alsa_mixer_add_main_volume_control_by_name_return_value = 0;
171 ucm_get_echo_reference_dev_name_for_dev_called = 0;
172 cras_system_check_ignore_ucm_suffix_called = 0;
173 cras_system_check_ignore_ucm_suffix_value = 0;
174 fake_dev1.nodes = NULL;
175 fake_dev2.nodes = NULL;
176 fake_dev3.nodes = NULL;
177 fake_dev4.nodes = NULL;
178 }
179
TEST(AlsaCard,CreateFailInvalidCard)180 TEST(AlsaCard, CreateFailInvalidCard) {
181 struct cras_alsa_card* c;
182 cras_alsa_card_info card_info;
183
184 ResetStubData();
185 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
186 card_info.card_index = 55;
187 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
188 NULL);
189 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
190 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
191 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
192 }
193
TEST(AlsaCard,CreateFailMixerInit)194 TEST(AlsaCard, CreateFailMixerInit) {
195 struct cras_alsa_card* c;
196 cras_alsa_card_info card_info;
197
198 ResetStubData();
199 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
200 card_info.card_index = 0;
201 cras_alsa_mixer_create_return = static_cast<struct cras_alsa_mixer*>(NULL);
202 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
203 NULL);
204 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
205 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
206 EXPECT_EQ(1, cras_alsa_mixer_create_called);
207 EXPECT_EQ(0, cras_alsa_mixer_destroy_called);
208 }
209
TEST(AlsaCard,CreateFailCtlOpen)210 TEST(AlsaCard, CreateFailCtlOpen) {
211 struct cras_alsa_card* c;
212 cras_alsa_card_info card_info;
213
214 ResetStubData();
215 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
216 card_info.card_index = 0;
217 snd_ctl_open_return = -1;
218 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
219 NULL);
220 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
221 EXPECT_EQ(1, snd_ctl_open_called);
222 EXPECT_EQ(0, snd_ctl_close_called);
223 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
224 EXPECT_EQ(0, cras_alsa_mixer_create_called);
225 }
226
TEST(AlsaCard,CreateFailHctlOpen)227 TEST(AlsaCard, CreateFailHctlOpen) {
228 struct cras_alsa_card* c;
229 cras_alsa_card_info card_info;
230
231 ResetStubData();
232 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
233 card_info.card_index = 0;
234 snd_hctl_open_pointer_val = NULL;
235 snd_hctl_open_return_value = -1;
236
237 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
238 NULL);
239 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
240 EXPECT_EQ(1, snd_ctl_open_called);
241 EXPECT_EQ(1, snd_ctl_close_called);
242 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
243 EXPECT_EQ(1, snd_hctl_open_called);
244 EXPECT_EQ(0, snd_hctl_nonblock_called);
245 EXPECT_EQ(0, snd_hctl_load_called);
246 EXPECT_EQ(1, cras_alsa_mixer_create_called);
247 cras_alsa_card_destroy(c);
248 }
249
TEST(AlsaCard,CreateFailHctlLoad)250 TEST(AlsaCard, CreateFailHctlLoad) {
251 struct cras_alsa_card* c;
252 cras_alsa_card_info card_info;
253
254 ResetStubData();
255 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
256 card_info.card_index = 0;
257 snd_hctl_load_return_value = -1;
258
259 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
260 NULL);
261 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
262 EXPECT_EQ(1, snd_ctl_open_called);
263 EXPECT_EQ(1, snd_ctl_close_called);
264 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
265 EXPECT_EQ(1, snd_hctl_open_called);
266 EXPECT_EQ(1, snd_hctl_nonblock_called);
267 EXPECT_EQ(1, snd_hctl_load_called);
268 EXPECT_EQ(0, cras_alsa_mixer_create_called);
269 }
270
TEST(AlsaCard,AddSelectForHctlNoDevices)271 TEST(AlsaCard, AddSelectForHctlNoDevices) {
272 struct pollfd poll_fds[] = {
273 {3, 0, 0},
274 };
275
276 struct cras_alsa_card* c;
277 cras_alsa_card_info card_info;
278
279 ResetStubData();
280 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
281 card_info.card_index = 0;
282 snd_hctl_poll_descriptors_fds = poll_fds;
283 snd_hctl_poll_descriptors_num_fds = ARRAY_SIZE(poll_fds);
284
285 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
286 NULL);
287 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
288 EXPECT_EQ(1, snd_ctl_open_called);
289 EXPECT_EQ(1, snd_ctl_close_called);
290 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
291 EXPECT_EQ(1, snd_hctl_open_called);
292 EXPECT_EQ(1, snd_hctl_nonblock_called);
293 EXPECT_EQ(1, snd_hctl_load_called);
294 EXPECT_EQ(1, cras_alsa_mixer_create_called);
295 EXPECT_EQ(0, cras_system_add_select_fd_called);
296 cras_alsa_card_destroy(c);
297 EXPECT_EQ(0, cras_system_rm_select_fd_called);
298 }
299
TEST(AlsaCard,AddSelectForHctlWithDevices)300 TEST(AlsaCard, AddSelectForHctlWithDevices) {
301 struct pollfd poll_fds[] = {
302 {3, 0, 0},
303 };
304 int dev_nums[] = {0};
305 int info_rets[] = {0, -1};
306
307 struct cras_alsa_card* c;
308 cras_alsa_card_info card_info;
309
310 ResetStubData();
311 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
312 snd_ctl_pcm_next_device_set_devs = dev_nums;
313 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
314 snd_ctl_pcm_info_rets = info_rets;
315 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
316 card_info.card_index = 0;
317 snd_hctl_poll_descriptors_fds = poll_fds;
318 snd_hctl_poll_descriptors_num_fds = ARRAY_SIZE(poll_fds);
319
320 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
321 NULL);
322 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
323 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
324 EXPECT_EQ(2, snd_ctl_pcm_next_device_called);
325 EXPECT_EQ(1, cras_alsa_iodev_create_called);
326 EXPECT_EQ(0, cras_alsa_iodev_index_called);
327 EXPECT_EQ(1, snd_ctl_card_info_called);
328 EXPECT_EQ(1, ucm_create_called);
329 EXPECT_EQ(1, ucm_get_dev_for_mixer_called);
330 EXPECT_EQ(1, ucm_get_flag_called);
331 EXPECT_EQ(0, strcmp(ucm_get_flag_name, "ExtraMainVolume"));
332 EXPECT_EQ(cras_card_config_dir, device_config_dir);
333 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
334 EXPECT_EQ(1, snd_hctl_open_called);
335 EXPECT_EQ(1, snd_hctl_nonblock_called);
336 EXPECT_EQ(1, snd_hctl_load_called);
337 EXPECT_EQ(1, cras_alsa_mixer_create_called);
338 ASSERT_EQ(1, cras_system_add_select_fd_called);
339 EXPECT_EQ(3, cras_system_add_select_fd_values[0]);
340 cras_alsa_card_destroy(c);
341 EXPECT_EQ(ARRAY_SIZE(poll_fds), cras_system_rm_select_fd_called);
342 }
343
TEST(AlsaCard,CreateFailCtlCardInfo)344 TEST(AlsaCard, CreateFailCtlCardInfo) {
345 struct cras_alsa_card* c;
346 cras_alsa_card_info card_info;
347
348 ResetStubData();
349 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
350 card_info.card_index = 0;
351 snd_ctl_card_info_ret = -1;
352 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
353 NULL);
354 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
355 EXPECT_EQ(1, snd_ctl_open_called);
356 EXPECT_EQ(1, snd_ctl_close_called);
357 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
358 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
359 }
360
TEST(AlsaCard,CreateNoDevices)361 TEST(AlsaCard, CreateNoDevices) {
362 struct cras_alsa_card* c;
363 cras_alsa_card_info card_info;
364
365 ResetStubData();
366 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
367 card_info.card_index = 1;
368 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
369 NULL);
370 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
371 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
372 EXPECT_EQ(1, snd_ctl_pcm_next_device_called);
373 EXPECT_EQ(0, cras_alsa_iodev_create_called);
374 EXPECT_EQ(0, cras_alsa_iodev_legacy_complete_init_called);
375 EXPECT_EQ(1, cras_alsa_card_get_index(c));
376 EXPECT_EQ(0, ucm_get_sections_called);
377 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
378
379 cras_alsa_card_destroy(c);
380 EXPECT_EQ(0, cras_alsa_iodev_destroy_called);
381 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
382 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
383 }
384
TEST(AlsaCard,CreateOneOutputNextDevError)385 TEST(AlsaCard, CreateOneOutputNextDevError) {
386 struct cras_alsa_card* c;
387 cras_alsa_card_info card_info;
388
389 ResetStubData();
390 snd_ctl_pcm_next_device_return_error = true;
391 card_info.card_type = ALSA_CARD_TYPE_USB;
392 card_info.card_index = 0;
393 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
394 NULL);
395 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
396 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
397 EXPECT_EQ(snd_ctl_open_called, snd_ctl_close_called);
398 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
399 }
400
TEST(AlsaCard,CreateOneOutput)401 TEST(AlsaCard, CreateOneOutput) {
402 struct cras_alsa_card* c;
403 int dev_nums[] = {0};
404 int info_rets[] = {0, -1};
405 cras_alsa_card_info card_info;
406
407 ResetStubData();
408 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
409 snd_ctl_pcm_next_device_set_devs = dev_nums;
410 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
411 snd_ctl_pcm_info_rets = info_rets;
412 card_info.card_type = ALSA_CARD_TYPE_USB;
413 card_info.card_index = 0;
414 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
415 NULL);
416 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
417 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
418 EXPECT_EQ(2, snd_ctl_pcm_next_device_called);
419 EXPECT_EQ(1, cras_alsa_iodev_create_called);
420 EXPECT_EQ(1, cras_alsa_iodev_legacy_complete_init_called);
421 EXPECT_EQ(0, cras_alsa_iodev_index_called);
422 EXPECT_EQ(1, snd_ctl_card_info_called);
423 EXPECT_EQ(1, ucm_create_called);
424 EXPECT_EQ(1, ucm_get_dev_for_mixer_called);
425 EXPECT_EQ(1, ucm_get_flag_called);
426 EXPECT_EQ(0, strcmp(ucm_get_flag_name, "ExtraMainVolume"));
427 EXPECT_EQ(cras_card_config_dir, device_config_dir);
428 EXPECT_EQ(0, ucm_get_sections_called);
429 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
430
431 cras_alsa_card_destroy(c);
432 EXPECT_EQ(1, ucm_destroy_called);
433 EXPECT_EQ(1, cras_alsa_iodev_destroy_called);
434 EXPECT_EQ(cras_alsa_iodev_create_return[0], cras_alsa_iodev_destroy_arg);
435 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
436 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
437 }
438
TEST(AlsaCard,CreateOneOutputBlocklisted)439 TEST(AlsaCard, CreateOneOutputBlocklisted) {
440 struct cras_alsa_card* c;
441 int dev_nums[] = {0};
442 int info_rets[] = {0, -1};
443 cras_alsa_card_info card_info;
444
445 ResetStubData();
446 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
447 snd_ctl_pcm_next_device_set_devs = dev_nums;
448 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
449 snd_ctl_pcm_info_rets = info_rets;
450 alsa_iodev_has_hctl_jacks_return = 0;
451 cras_device_blocklist_check_retval = 1;
452 card_info.card_type = ALSA_CARD_TYPE_USB;
453 card_info.card_index = 0;
454 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
455 NULL);
456 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
457 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
458 EXPECT_EQ(2, snd_ctl_pcm_next_device_called);
459 EXPECT_EQ(1, snd_ctl_card_info_called);
460 EXPECT_EQ(0, cras_alsa_iodev_create_called);
461 EXPECT_EQ(0, cras_alsa_iodev_legacy_complete_init_called);
462 EXPECT_EQ(cras_card_config_dir, device_config_dir);
463
464 cras_alsa_card_destroy(c);
465 EXPECT_EQ(0, cras_alsa_iodev_destroy_called);
466 EXPECT_EQ(NULL, cras_alsa_iodev_destroy_arg);
467 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
468 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
469 }
470
TEST(AlsaCard,CreateTwoOutputs)471 TEST(AlsaCard, CreateTwoOutputs) {
472 struct cras_alsa_card* c;
473 int dev_nums[] = {0, 3};
474 int info_rets[] = {0, -1, 0};
475 cras_alsa_card_info card_info;
476
477 ResetStubData();
478 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
479 snd_ctl_pcm_next_device_set_devs = dev_nums;
480 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
481 snd_ctl_pcm_info_rets = info_rets;
482 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
483 card_info.card_index = 0;
484 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
485 NULL);
486 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
487 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
488 EXPECT_EQ(3, snd_ctl_pcm_next_device_called);
489 EXPECT_EQ(2, cras_alsa_iodev_create_called);
490 EXPECT_EQ(2, cras_alsa_iodev_legacy_complete_init_called);
491 EXPECT_EQ(1, cras_alsa_iodev_index_called);
492 EXPECT_EQ(1, snd_ctl_card_info_called);
493 EXPECT_EQ(cras_card_config_dir, device_config_dir);
494 EXPECT_EQ(0, ucm_get_sections_called);
495 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
496
497 cras_alsa_card_destroy(c);
498 EXPECT_EQ(2, cras_alsa_iodev_destroy_called);
499 EXPECT_EQ(cras_alsa_iodev_create_return[1], cras_alsa_iodev_destroy_arg);
500 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
501 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
502 }
503
TEST(AlsaCard,CreateTwoDuplicateDeviceIndex)504 TEST(AlsaCard, CreateTwoDuplicateDeviceIndex) {
505 struct cras_alsa_card* c;
506 int dev_nums[] = {0, 0};
507 int info_rets[] = {0, -1, 0};
508 cras_alsa_card_info card_info;
509
510 ResetStubData();
511 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
512 snd_ctl_pcm_next_device_set_devs = dev_nums;
513 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
514 snd_ctl_pcm_info_rets = info_rets;
515 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
516 card_info.card_index = 0;
517 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
518 NULL);
519 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
520 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
521 EXPECT_EQ(3, snd_ctl_pcm_next_device_called);
522 EXPECT_EQ(1, cras_alsa_iodev_create_called);
523 EXPECT_EQ(2, cras_alsa_iodev_legacy_complete_init_called);
524 EXPECT_EQ(1, cras_alsa_iodev_index_called);
525 EXPECT_EQ(1, snd_ctl_card_info_called);
526 EXPECT_EQ(cras_card_config_dir, device_config_dir);
527 EXPECT_EQ(0, ucm_get_sections_called);
528 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
529
530 cras_alsa_card_destroy(c);
531 EXPECT_EQ(1, cras_alsa_iodev_destroy_called);
532 EXPECT_EQ(cras_alsa_iodev_create_return[0], cras_alsa_iodev_destroy_arg);
533 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
534 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
535 }
536
TEST(AlsaCard,CreateOneInput)537 TEST(AlsaCard, CreateOneInput) {
538 struct cras_alsa_card* c;
539 int dev_nums[] = {0};
540 int info_rets[] = {-1, 0};
541 cras_alsa_card_info card_info;
542
543 ResetStubData();
544 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
545 snd_ctl_pcm_next_device_set_devs = dev_nums;
546 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
547 snd_ctl_pcm_info_rets = info_rets;
548 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
549 card_info.card_index = 0;
550 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
551 NULL);
552 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
553 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
554 EXPECT_EQ(2, snd_ctl_pcm_next_device_called);
555 EXPECT_EQ(1, cras_alsa_iodev_create_called);
556 EXPECT_EQ(1, cras_alsa_iodev_legacy_complete_init_called);
557 EXPECT_EQ(0, cras_alsa_iodev_index_called);
558 EXPECT_EQ(cras_card_config_dir, device_config_dir);
559 EXPECT_EQ(0, ucm_get_sections_called);
560 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
561
562 cras_alsa_card_destroy(c);
563 EXPECT_EQ(1, cras_alsa_iodev_destroy_called);
564 EXPECT_EQ(cras_alsa_iodev_create_return[0], cras_alsa_iodev_destroy_arg);
565 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
566 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
567 }
568
TEST(AlsaCard,CreateOneInputAndOneOutput)569 TEST(AlsaCard, CreateOneInputAndOneOutput) {
570 struct cras_alsa_card* c;
571 int dev_nums[] = {0};
572 int info_rets[] = {0, 0};
573 cras_alsa_card_info card_info;
574
575 ResetStubData();
576 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
577 snd_ctl_pcm_next_device_set_devs = dev_nums;
578 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
579 snd_ctl_pcm_info_rets = info_rets;
580 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
581 card_info.card_index = 0;
582 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
583 NULL);
584 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
585 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
586 EXPECT_EQ(2, snd_ctl_pcm_next_device_called);
587 EXPECT_EQ(2, cras_alsa_iodev_create_called);
588 EXPECT_EQ(2, cras_alsa_iodev_legacy_complete_init_called);
589 EXPECT_EQ(0, cras_alsa_iodev_index_called);
590 EXPECT_EQ(cras_card_config_dir, device_config_dir);
591 EXPECT_EQ(0, ucm_get_sections_called);
592 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
593
594 cras_alsa_card_destroy(c);
595 EXPECT_EQ(2, cras_alsa_iodev_destroy_called);
596 EXPECT_EQ(cras_alsa_iodev_create_return[1], cras_alsa_iodev_destroy_arg);
597 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
598 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
599 }
600
TEST(AlsaCard,CreateOneInputAndOneOutputTwoDevices)601 TEST(AlsaCard, CreateOneInputAndOneOutputTwoDevices) {
602 struct cras_alsa_card* c;
603 int dev_nums[] = {0, 3};
604 int info_rets[] = {0, -1, -1, 0};
605 cras_alsa_card_info card_info;
606
607 ResetStubData();
608 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
609 snd_ctl_pcm_next_device_set_devs = dev_nums;
610 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
611 snd_ctl_pcm_info_rets = info_rets;
612 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
613 card_info.card_index = 0;
614 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
615 NULL);
616 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
617 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
618 EXPECT_EQ(3, snd_ctl_pcm_next_device_called);
619 EXPECT_EQ(2, cras_alsa_iodev_create_called);
620 EXPECT_EQ(2, cras_alsa_iodev_legacy_complete_init_called);
621 EXPECT_EQ(0, cras_alsa_iodev_index_called);
622 EXPECT_EQ(cras_card_config_dir, device_config_dir);
623 EXPECT_EQ(0, ucm_get_sections_called);
624 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
625
626 cras_alsa_card_destroy(c);
627 EXPECT_EQ(2, cras_alsa_iodev_destroy_called);
628 EXPECT_EQ(cras_alsa_iodev_create_return[1], cras_alsa_iodev_destroy_arg);
629 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
630 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
631 }
632
TEST(AlsaCard,CreateOneOutputWithCoupledMixers)633 TEST(AlsaCard, CreateOneOutputWithCoupledMixers) {
634 struct cras_alsa_card* c;
635 int dev_nums[] = {0};
636 int info_rets[] = {0, -1};
637 struct mixer_name *mixer_name_1, *mixer_name_2;
638 /* Use strdup because cras_alsa_card_create will delete it. */
639 const char *name1 = strdup("MixerName1"), *name2 = strdup("MixerName2");
640
641 cras_alsa_card_info card_info;
642
643 ResetStubData();
644 snd_ctl_pcm_next_device_set_devs_size = ARRAY_SIZE(dev_nums);
645 snd_ctl_pcm_next_device_set_devs = dev_nums;
646 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
647 snd_ctl_pcm_info_rets = info_rets;
648 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
649 card_info.card_index = 0;
650
651 /* Creates a list of mixer names as return value of
652 * ucm_get_coupled_mixer_names. */
653 mixer_name_1 = (struct mixer_name*)malloc(sizeof(*mixer_name_1));
654 mixer_name_2 = (struct mixer_name*)malloc(sizeof(*mixer_name_2));
655 mixer_name_1->name = name1;
656 mixer_name_2->name = name2;
657 mixer_name_1->dir = CRAS_STREAM_OUTPUT;
658 mixer_name_2->dir = CRAS_STREAM_OUTPUT;
659 mixer_name_1->type = MIXER_NAME_VOLUME;
660 mixer_name_2->type = MIXER_NAME_VOLUME;
661
662 DL_APPEND(ucm_get_coupled_mixer_names_return_value, mixer_name_1);
663 DL_APPEND(ucm_get_coupled_mixer_names_return_value, mixer_name_2);
664
665 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
666 NULL);
667
668 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
669 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
670 EXPECT_EQ(2, snd_ctl_pcm_next_device_called);
671 EXPECT_EQ(1, cras_alsa_iodev_create_called);
672 EXPECT_EQ(1, cras_alsa_iodev_legacy_complete_init_called);
673 EXPECT_EQ(0, cras_alsa_iodev_index_called);
674 EXPECT_EQ(1, snd_ctl_card_info_called);
675 EXPECT_EQ(1, ucm_create_called);
676 EXPECT_EQ(1, ucm_get_dev_for_mixer_called);
677 EXPECT_EQ(1, ucm_get_flag_called);
678 EXPECT_EQ(0, strcmp(ucm_get_flag_name, "ExtraMainVolume"));
679 EXPECT_EQ(cras_card_config_dir, device_config_dir);
680 EXPECT_EQ(0, ucm_get_sections_called);
681 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
682
683 /* Checks cras_alsa_card_create can handle the list and pass the names to
684 * cras_alsa_mixer_create. */
685 struct mixer_name* m_name = coupled_output_names_value;
686 EXPECT_EQ(0, m_name ? strcmp(m_name->name, "MixerName1") : 1);
687 if (m_name)
688 m_name = m_name->next;
689 EXPECT_EQ(0, m_name ? strcmp(m_name->name, "MixerName2") : 1);
690
691 cras_alsa_card_destroy(c);
692 EXPECT_EQ(1, ucm_destroy_called);
693 EXPECT_EQ(1, cras_alsa_iodev_destroy_called);
694 EXPECT_EQ(cras_alsa_iodev_create_return[0], cras_alsa_iodev_destroy_arg);
695 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
696 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
697
698 mixer_name_free(coupled_output_names_value);
699 coupled_output_names_value = NULL;
700 }
701
TEST(AlsaCard,CreateFullyUCMNoSections)702 TEST(AlsaCard, CreateFullyUCMNoSections) {
703 struct cras_alsa_card* c;
704 cras_alsa_card_info card_info;
705
706 ResetStubData();
707 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
708 card_info.card_index = 0;
709 ucm_has_fully_specified_ucm_flag_return_value = 1;
710 ucm_get_sections_return_value = NULL;
711 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
712 NULL);
713 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
714 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
715 EXPECT_EQ(0, cras_alsa_iodev_create_called);
716 EXPECT_EQ(0, cras_alsa_iodev_ucm_complete_init_called);
717 EXPECT_EQ(1, snd_ctl_card_info_called);
718 EXPECT_EQ(1, ucm_get_sections_called);
719 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
720
721 cras_alsa_card_destroy(c);
722 EXPECT_EQ(1, ucm_destroy_called);
723 EXPECT_EQ(0, cras_alsa_iodev_destroy_called);
724 EXPECT_EQ(NULL, cras_alsa_iodev_destroy_arg);
725 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
726 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
727 }
728
TEST(AlsaCard,CreateFullyUCMTwoMainVolume)729 TEST(AlsaCard, CreateFullyUCMTwoMainVolume) {
730 struct cras_alsa_card* c;
731 struct mixer_name *mixer_name_1, *mixer_name_2;
732 const char *name1 = strdup("MixerName1"), *name2 = strdup("MixerName2");
733 cras_alsa_card_info card_info;
734
735 ResetStubData();
736 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
737 card_info.card_index = 0;
738 ucm_has_fully_specified_ucm_flag_return_value = 1;
739
740 /* Creates a list of mixer names as return value of
741 * ucm_get_main_volume_names_return_value. */
742 mixer_name_1 = (struct mixer_name*)malloc(sizeof(*mixer_name_1));
743 mixer_name_2 = (struct mixer_name*)malloc(sizeof(*mixer_name_2));
744 mixer_name_1->name = name1;
745 mixer_name_2->name = name2;
746 mixer_name_1->dir = CRAS_STREAM_OUTPUT;
747 mixer_name_2->dir = CRAS_STREAM_OUTPUT;
748 mixer_name_1->type = MIXER_NAME_MAIN_VOLUME;
749 mixer_name_2->type = MIXER_NAME_MAIN_VOLUME;
750
751 DL_APPEND(ucm_get_main_volume_names_return_value, mixer_name_1);
752 DL_APPEND(ucm_get_main_volume_names_return_value, mixer_name_2);
753
754 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
755 NULL);
756
757 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
758 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
759 EXPECT_EQ(0, cras_alsa_iodev_create_called);
760 EXPECT_EQ(0, cras_alsa_iodev_ucm_complete_init_called);
761 EXPECT_EQ(1, snd_ctl_card_info_called);
762 EXPECT_EQ(1, cras_alsa_mixer_add_main_volume_control_by_name_called);
763 EXPECT_EQ(1, ucm_get_sections_called);
764 EXPECT_EQ(0, cras_alsa_mixer_add_controls_in_section_called);
765
766 cras_alsa_card_destroy(c);
767 EXPECT_EQ(1, ucm_destroy_called);
768 EXPECT_EQ(0, cras_alsa_iodev_destroy_called);
769 EXPECT_EQ(NULL, cras_alsa_iodev_destroy_arg);
770 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
771 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
772 }
773
TEST(AlsaCard,TwoUCMSecionsDependentPCM)774 TEST(AlsaCard, TwoUCMSecionsDependentPCM) {
775 struct cras_alsa_card* c;
776 cras_alsa_card_info card_info;
777 struct ucm_section* sections = NULL;
778 struct ucm_section* section;
779
780 /* Create UCM so that MIC1 and MIC2 will be two nodes on the same iodev. */
781 section = ucm_section_create("MIC1", "hw:0,3", 0, -1, CRAS_STREAM_INPUT,
782 "my-sound-card Headset Jack", "gpio");
783 DL_APPEND(sections, section);
784 section = ucm_section_create("MIC2", "hw:0,5", 0, 3, CRAS_STREAM_INPUT,
785 "my-sound-card Headset Jack", "gpio");
786 DL_APPEND(sections, section);
787
788 ResetStubData();
789 int info_rets[] = {0, 0};
790 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
791 card_info.card_index = 0;
792 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
793 snd_ctl_pcm_info_rets = info_rets;
794 ucm_has_fully_specified_ucm_flag_return_value = 1;
795 ucm_get_sections_return_value = sections;
796 ASSERT_NE(ucm_get_sections_return_value, (struct ucm_section*)NULL);
797
798 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
799 NULL);
800
801 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
802 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
803 EXPECT_EQ(1, snd_ctl_card_info_called);
804 EXPECT_EQ(1, ucm_get_sections_called);
805 EXPECT_EQ(1, snd_ctl_pcm_info_called);
806 EXPECT_EQ(2, cras_alsa_mixer_add_controls_in_section_called);
807 EXPECT_EQ(1, cras_alsa_iodev_create_called);
808 EXPECT_EQ(2, cras_alsa_iodev_ucm_add_nodes_and_jacks_called);
809 EXPECT_EQ(1, cras_alsa_iodev_ucm_complete_init_called);
810
811 cras_alsa_card_destroy(c);
812 EXPECT_EQ(1, ucm_destroy_called);
813 EXPECT_EQ(1, cras_alsa_iodev_destroy_called);
814 EXPECT_EQ(cras_alsa_iodev_create_return[0], cras_alsa_iodev_destroy_arg);
815 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
816 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
817 }
818
GenerateUcmSections(void)819 struct ucm_section* GenerateUcmSections(void) {
820 struct ucm_section* sections = NULL;
821 struct ucm_section* section;
822
823 section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
824 "my-sound-card Headset Jack", "gpio");
825 ucm_section_add_coupled(section, "HP-L", MIXER_NAME_VOLUME);
826 ucm_section_add_coupled(section, "HP-R", MIXER_NAME_VOLUME);
827 DL_APPEND(sections, section);
828
829 section = ucm_section_create("Speaker", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
830 NULL, NULL);
831 ucm_section_add_coupled(section, "SPK-L", MIXER_NAME_VOLUME);
832 ucm_section_add_coupled(section, "SPK-R", MIXER_NAME_VOLUME);
833 DL_APPEND(sections, section);
834
835 section = ucm_section_create("Internal Mic", "hw:0,1", 0, -1,
836 CRAS_STREAM_INPUT, NULL, NULL);
837 ucm_section_add_coupled(section, "INT-MIC-L", MIXER_NAME_VOLUME);
838 ucm_section_add_coupled(section, "INT-MIC-R", MIXER_NAME_VOLUME);
839 DL_APPEND(sections, section);
840
841 section = ucm_section_create("Mic", "hw:0,1", 1, -1, CRAS_STREAM_INPUT,
842 "my-sound-card Headset Jack", "gpio");
843 ucm_section_add_coupled(section, "MIC-L", MIXER_NAME_VOLUME);
844 ucm_section_add_coupled(section, "MIC-R", MIXER_NAME_VOLUME);
845 DL_APPEND(sections, section);
846
847 section = ucm_section_create("HDMI", "hw:0,1", 2, -1, CRAS_STREAM_OUTPUT,
848 NULL, NULL);
849 ucm_section_set_mixer_name(section, "HDMI");
850 DL_APPEND(sections, section);
851
852 return sections;
853 }
854
TEST(AlsaCard,CreateFullyUCMFailureOnControls)855 TEST(AlsaCard, CreateFullyUCMFailureOnControls) {
856 struct cras_alsa_card* c;
857 cras_alsa_card_info card_info;
858
859 ResetStubData();
860 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
861 card_info.card_index = 0;
862 ucm_has_fully_specified_ucm_flag_return_value = 1;
863 ucm_get_sections_return_value = GenerateUcmSections();
864 ASSERT_NE(ucm_get_sections_return_value, (struct ucm_section*)NULL);
865
866 cras_alsa_mixer_add_controls_in_section_return_value = -EINVAL;
867
868 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
869 NULL);
870
871 EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
872 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
873 EXPECT_EQ(1, snd_ctl_card_info_called);
874 EXPECT_EQ(1, ucm_get_sections_called);
875 EXPECT_EQ(1, cras_alsa_mixer_add_controls_in_section_called);
876 EXPECT_EQ(0, cras_alsa_iodev_create_called);
877 EXPECT_EQ(0, cras_alsa_iodev_ucm_complete_init_called);
878
879 cras_alsa_card_destroy(c);
880 EXPECT_EQ(1, ucm_destroy_called);
881 EXPECT_EQ(0, cras_alsa_iodev_destroy_called);
882 EXPECT_EQ(NULL, cras_alsa_iodev_destroy_arg);
883 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
884 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
885 }
886
TEST(AlsaCard,CreateFullyUCMFourDevicesFiveSections)887 TEST(AlsaCard, CreateFullyUCMFourDevicesFiveSections) {
888 struct cras_alsa_card* c;
889 cras_alsa_card_info card_info;
890 int info_rets[] = {0, 0, 0, 0, 0, -1};
891
892 ResetStubData();
893 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
894 card_info.card_index = 0;
895 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
896 snd_ctl_pcm_info_rets = info_rets;
897 ucm_has_fully_specified_ucm_flag_return_value = 1;
898 ucm_get_sections_return_value = GenerateUcmSections();
899 cras_alsa_iodev_index_return[cras_alsa_iodev_create_return[0]] = 0;
900 cras_alsa_iodev_index_return[cras_alsa_iodev_create_return[1]] = 0;
901 cras_alsa_iodev_index_return[cras_alsa_iodev_create_return[2]] = 1;
902 cras_alsa_iodev_index_return[cras_alsa_iodev_create_return[3]] = 2;
903 ASSERT_NE(ucm_get_sections_return_value, (struct ucm_section*)NULL);
904
905 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
906 NULL);
907
908 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
909 EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
910 EXPECT_EQ(1, snd_ctl_card_info_called);
911 EXPECT_EQ(1, ucm_get_sections_called);
912 EXPECT_EQ(5, snd_ctl_pcm_info_called);
913 EXPECT_EQ(5, cras_alsa_mixer_add_controls_in_section_called);
914 EXPECT_EQ(4, cras_alsa_iodev_create_called);
915 EXPECT_EQ(5, cras_alsa_iodev_ucm_add_nodes_and_jacks_called);
916 EXPECT_EQ(4, cras_alsa_iodev_ucm_complete_init_called);
917
918 cras_alsa_card_destroy(c);
919 EXPECT_EQ(1, ucm_destroy_called);
920 EXPECT_EQ(4, cras_alsa_iodev_destroy_called);
921 EXPECT_EQ(cras_alsa_iodev_create_return[3], cras_alsa_iodev_destroy_arg);
922 EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
923 EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
924 }
925
TEST(AlsaCard,GG)926 TEST(AlsaCard, GG) {
927 struct cras_alsa_card* c;
928 cras_alsa_card_info card_info;
929 int info_rets[] = {0, 0, 0, 0, 0, -1};
930 struct cras_ionode nodes[4];
931 const char* echo_ref = "echo ref";
932
933 ResetStubData();
934 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
935 card_info.card_index = 0;
936 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
937 snd_ctl_pcm_info_rets = info_rets;
938 ucm_has_fully_specified_ucm_flag_return_value = 1;
939 ucm_get_sections_return_value = GenerateUcmSections();
940
941 fake_dev1.nodes = nodes;
942 fake_dev2.nodes = nodes + 1;
943 fake_dev3.nodes = nodes + 2;
944 fake_dev4.nodes = nodes + 3;
945 snprintf(nodes[0].name, CRAS_NODE_NAME_BUFFER_SIZE, "dev1");
946 snprintf(nodes[1].name, CRAS_NODE_NAME_BUFFER_SIZE, "dev2");
947 snprintf(nodes[2].name, CRAS_NODE_NAME_BUFFER_SIZE, "dev3");
948 snprintf(nodes[3].name, CRAS_NODE_NAME_BUFFER_SIZE, "echo ref");
949
950 ucm_get_echo_reference_dev_name_for_dev_return_value[0] = strdup(echo_ref);
951
952 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
953 NULL);
954
955 EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
956 EXPECT_EQ(fake_dev1.echo_reference_dev, &fake_dev4);
957 cras_alsa_card_destroy(c);
958 }
959
TEST(AlsaCard,UCMSuffix)960 TEST(AlsaCard, UCMSuffix) {
961 struct cras_alsa_card* c;
962 cras_alsa_card_info card_info;
963 int info_rets[] = {0, 0, 0, 0, 0, -1};
964
965 ResetStubData();
966 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
967 card_info.card_index = 0;
968 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
969 snd_ctl_pcm_info_rets = info_rets;
970 ucm_has_fully_specified_ucm_flag_return_value = 1;
971 ucm_get_sections_return_value = GenerateUcmSections();
972 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
973 "1mic");
974 EXPECT_EQ(0, strcmp(ucm_create_name, "TestName.1mic"));
975 EXPECT_EQ(1, cras_system_check_ignore_ucm_suffix_called);
976 cras_alsa_card_destroy(c);
977 }
978
TEST(AlsaCard,UCMIgnoreSuffix)979 TEST(AlsaCard, UCMIgnoreSuffix) {
980 struct cras_alsa_card* c;
981 cras_alsa_card_info card_info;
982 int info_rets[] = {0, 0, 0, 0, 0, -1};
983
984 ResetStubData();
985 card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
986 card_info.card_index = 0;
987 snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
988 snd_ctl_pcm_info_rets = info_rets;
989 ucm_has_fully_specified_ucm_flag_return_value = 1;
990 ucm_get_sections_return_value = GenerateUcmSections();
991 cras_system_check_ignore_ucm_suffix_value = true;
992 c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
993 "1mic");
994 EXPECT_EQ(0, strcmp(ucm_create_name, "TestName"));
995 EXPECT_EQ(1, cras_system_check_ignore_ucm_suffix_called);
996 cras_alsa_card_destroy(c);
997 }
998
999 /* Stubs */
1000
1001 extern "C" {
cras_alsa_mixer_create(const char * card_name)1002 struct cras_alsa_mixer* cras_alsa_mixer_create(const char* card_name) {
1003 cras_alsa_mixer_create_called++;
1004 return cras_alsa_mixer_create_return;
1005 }
1006
cras_alsa_mixer_add_controls_by_name_matching(struct cras_alsa_mixer * cmix,struct mixer_name * extra_controls,struct mixer_name * coupled_controls)1007 int cras_alsa_mixer_add_controls_by_name_matching(
1008 struct cras_alsa_mixer* cmix,
1009 struct mixer_name* extra_controls,
1010 struct mixer_name* coupled_controls) {
1011 /* Duplicate coupled_output_names to verify in the end of unittest
1012 * because names will get freed later in cras_alsa_card_create. */
1013 struct mixer_name* control;
1014 DL_FOREACH (coupled_controls, control) {
1015 coupled_output_names_value =
1016 mixer_name_add(coupled_output_names_value, control->name,
1017 CRAS_STREAM_OUTPUT, control->type);
1018 }
1019 return 0;
1020 }
1021
cras_alsa_mixer_destroy(struct cras_alsa_mixer * cras_mixer)1022 void cras_alsa_mixer_destroy(struct cras_alsa_mixer* cras_mixer) {
1023 cras_alsa_mixer_destroy_called++;
1024 }
1025
alsa_iodev_create(size_t card_index,const char * card_name,size_t device_index,const char * pcm_name,const char * dev_name,const char * dev_id,enum CRAS_ALSA_CARD_TYPE card_type,int is_first,struct cras_alsa_mixer * mixer,const struct cras_card_config * config,struct cras_use_case_mgr * ucm,snd_hctl_t * hctl,enum CRAS_STREAM_DIRECTION direction,size_t usb_vid,size_t usb_pid,char * usb_serial_number)1026 struct cras_iodev* alsa_iodev_create(size_t card_index,
1027 const char* card_name,
1028 size_t device_index,
1029 const char* pcm_name,
1030 const char* dev_name,
1031 const char* dev_id,
1032 enum CRAS_ALSA_CARD_TYPE card_type,
1033 int is_first,
1034 struct cras_alsa_mixer* mixer,
1035 const struct cras_card_config* config,
1036 struct cras_use_case_mgr* ucm,
1037 snd_hctl_t* hctl,
1038 enum CRAS_STREAM_DIRECTION direction,
1039 size_t usb_vid,
1040 size_t usb_pid,
1041 char* usb_serial_number) {
1042 struct cras_iodev* result = NULL;
1043 if (cras_alsa_iodev_create_called < cras_alsa_iodev_create_return_size)
1044 result = cras_alsa_iodev_create_return[cras_alsa_iodev_create_called];
1045 cras_alsa_iodev_create_called++;
1046 return result;
1047 }
alsa_iodev_destroy(struct cras_iodev * iodev)1048 void alsa_iodev_destroy(struct cras_iodev* iodev) {
1049 cras_alsa_iodev_destroy_called++;
1050 cras_alsa_iodev_destroy_arg = iodev;
1051 }
alsa_iodev_legacy_complete_init(struct cras_iodev * iodev)1052 int alsa_iodev_legacy_complete_init(struct cras_iodev* iodev) {
1053 cras_alsa_iodev_legacy_complete_init_called++;
1054 return 0;
1055 }
alsa_iodev_ucm_add_nodes_and_jacks(struct cras_iodev * iodev,struct ucm_section * section)1056 int alsa_iodev_ucm_add_nodes_and_jacks(struct cras_iodev* iodev,
1057 struct ucm_section* section) {
1058 cras_alsa_iodev_ucm_add_nodes_and_jacks_called++;
1059 return 0;
1060 }
alsa_iodev_ucm_complete_init(struct cras_iodev * iodev)1061 void alsa_iodev_ucm_complete_init(struct cras_iodev* iodev) {
1062 cras_alsa_iodev_ucm_complete_init_called++;
1063 }
alsa_iodev_index(struct cras_iodev * iodev)1064 unsigned alsa_iodev_index(struct cras_iodev* iodev) {
1065 std::map<struct cras_iodev*, unsigned int>::iterator i;
1066 cras_alsa_iodev_index_called++;
1067 i = cras_alsa_iodev_index_return.find(iodev);
1068 if (i != cras_alsa_iodev_index_return.end())
1069 return i->second;
1070 return 0;
1071 }
alsa_iodev_has_hctl_jacks(struct cras_iodev * iodev)1072 int alsa_iodev_has_hctl_jacks(struct cras_iodev* iodev) {
1073 return alsa_iodev_has_hctl_jacks_return;
1074 }
1075
snd_pcm_info_sizeof()1076 size_t snd_pcm_info_sizeof() {
1077 return 10;
1078 }
snd_ctl_card_info_sizeof()1079 size_t snd_ctl_card_info_sizeof() {
1080 return 10;
1081 }
snd_ctl_open(snd_ctl_t ** handle,const char * name,int card)1082 int snd_ctl_open(snd_ctl_t** handle, const char* name, int card) {
1083 snd_ctl_open_called++;
1084 if (snd_ctl_open_return == 0)
1085 *handle = reinterpret_cast<snd_ctl_t*>(0xff);
1086 else
1087 *handle = NULL;
1088 return snd_ctl_open_return;
1089 }
snd_ctl_close(snd_ctl_t * handle)1090 int snd_ctl_close(snd_ctl_t* handle) {
1091 snd_ctl_close_called++;
1092 return snd_ctl_close_return;
1093 }
snd_ctl_pcm_next_device(snd_ctl_t * ctl,int * device)1094 int snd_ctl_pcm_next_device(snd_ctl_t* ctl, int* device) {
1095 if (snd_ctl_pcm_next_device_return_error) {
1096 *device = 10;
1097 return -1;
1098 }
1099 snd_ctl_pcm_next_device_called++;
1100 if (snd_ctl_pcm_next_device_set_devs_index >=
1101 snd_ctl_pcm_next_device_set_devs_size) {
1102 *device = -1;
1103 return 0;
1104 }
1105 *device =
1106 snd_ctl_pcm_next_device_set_devs[snd_ctl_pcm_next_device_set_devs_index];
1107 snd_ctl_pcm_next_device_set_devs_index++;
1108 return 0;
1109 }
snd_pcm_info_set_device(snd_pcm_info_t * obj,unsigned int val)1110 void snd_pcm_info_set_device(snd_pcm_info_t* obj, unsigned int val) {}
snd_pcm_info_set_subdevice(snd_pcm_info_t * obj,unsigned int val)1111 void snd_pcm_info_set_subdevice(snd_pcm_info_t* obj, unsigned int val) {}
snd_pcm_info_set_stream(snd_pcm_info_t * obj,snd_pcm_stream_t val)1112 void snd_pcm_info_set_stream(snd_pcm_info_t* obj, snd_pcm_stream_t val) {}
snd_pcm_info_get_name(const snd_pcm_info_t * obj)1113 const char* snd_pcm_info_get_name(const snd_pcm_info_t* obj) {
1114 return "Fake device name";
1115 }
snd_pcm_info_get_id(const snd_pcm_info_t * obj)1116 const char* snd_pcm_info_get_id(const snd_pcm_info_t* obj) {
1117 return "Fake device id";
1118 }
snd_ctl_pcm_info(snd_ctl_t * ctl,snd_pcm_info_t * info)1119 int snd_ctl_pcm_info(snd_ctl_t* ctl, snd_pcm_info_t* info) {
1120 int ret;
1121 snd_ctl_pcm_info_called++;
1122 if (snd_ctl_pcm_info_rets_index >= snd_ctl_pcm_info_rets_size) {
1123 return -1;
1124 }
1125 ret = snd_ctl_pcm_info_rets[snd_ctl_pcm_info_rets_index];
1126 snd_ctl_pcm_info_rets_index++;
1127 return ret;
1128 }
snd_ctl_card_info(snd_ctl_t * ctl,snd_ctl_card_info_t * info)1129 int snd_ctl_card_info(snd_ctl_t* ctl, snd_ctl_card_info_t* info) {
1130 snd_ctl_card_info_called++;
1131 return snd_ctl_card_info_ret;
1132 }
snd_ctl_card_info_get_name(const snd_ctl_card_info_t * obj)1133 const char* snd_ctl_card_info_get_name(const snd_ctl_card_info_t* obj) {
1134 return "TestName";
1135 }
snd_ctl_card_info_get_id(const snd_ctl_card_info_t * obj)1136 const char* snd_ctl_card_info_get_id(const snd_ctl_card_info_t* obj) {
1137 return "TestId";
1138 }
snd_hctl_open(snd_hctl_t ** hctlp,const char * name,int mode)1139 int snd_hctl_open(snd_hctl_t** hctlp, const char* name, int mode) {
1140 *hctlp = snd_hctl_open_pointer_val;
1141 snd_hctl_open_called++;
1142 return snd_hctl_open_return_value;
1143 }
snd_hctl_nonblock(snd_hctl_t * hctl,int nonblock)1144 int snd_hctl_nonblock(snd_hctl_t* hctl, int nonblock) {
1145 snd_hctl_nonblock_called++;
1146 return 0;
1147 }
snd_hctl_load(snd_hctl_t * hctl)1148 int snd_hctl_load(snd_hctl_t* hctl) {
1149 snd_hctl_load_called++;
1150 return snd_hctl_load_return_value;
1151 }
snd_hctl_close(snd_hctl_t * hctl)1152 int snd_hctl_close(snd_hctl_t* hctl) {
1153 snd_hctl_close_called++;
1154 return 0;
1155 }
snd_hctl_poll_descriptors_count(snd_hctl_t * hctl)1156 int snd_hctl_poll_descriptors_count(snd_hctl_t* hctl) {
1157 return snd_hctl_poll_descriptors_num_fds;
1158 }
snd_hctl_poll_descriptors(snd_hctl_t * hctl,struct pollfd * pfds,unsigned int space)1159 int snd_hctl_poll_descriptors(snd_hctl_t* hctl,
1160 struct pollfd* pfds,
1161 unsigned int space) {
1162 unsigned int num = MIN(space, snd_hctl_poll_descriptors_num_fds);
1163 memcpy(pfds, snd_hctl_poll_descriptors_fds, num * sizeof(*pfds));
1164 snd_hctl_poll_descriptors_called++;
1165 return num;
1166 }
snd_hctl_handle_events(snd_hctl_t * hctl)1167 int snd_hctl_handle_events(snd_hctl_t* hctl) {
1168 snd_hctl_handle_events_called++;
1169 return 0;
1170 }
1171
cras_system_add_select_fd(int fd,void (* callback)(void * data),void * callback_data)1172 int cras_system_add_select_fd(int fd,
1173 void (*callback)(void* data),
1174 void* callback_data) {
1175 cras_system_add_select_fd_called++;
1176 cras_system_add_select_fd_values.push_back(fd);
1177 return 0;
1178 }
cras_system_rm_select_fd(int fd)1179 void cras_system_rm_select_fd(int fd) {
1180 cras_system_rm_select_fd_called++;
1181 cras_system_rm_select_fd_values.push_back(fd);
1182 }
1183
cras_card_config_create(const char * config_path,const char * card_name)1184 struct cras_card_config* cras_card_config_create(const char* config_path,
1185 const char* card_name) {
1186 cras_card_config_dir = config_path;
1187 return NULL;
1188 }
1189
cras_card_config_destroy(struct cras_card_config * card_config)1190 void cras_card_config_destroy(struct cras_card_config* card_config) {}
1191
cras_card_config_get_volume_curve_for_control(const struct cras_card_config * card_config,const char * control_name)1192 struct cras_volume_curve* cras_card_config_get_volume_curve_for_control(
1193 const struct cras_card_config* card_config,
1194 const char* control_name) {
1195 return NULL;
1196 }
1197
cras_device_blocklist_check(struct cras_device_blocklist * blocklist,unsigned vendor_id,unsigned product_id,unsigned device_index)1198 int cras_device_blocklist_check(struct cras_device_blocklist* blocklist,
1199 unsigned vendor_id,
1200 unsigned product_id,
1201 unsigned device_index) {
1202 EXPECT_EQ(fake_blocklist, blocklist);
1203
1204 return cras_device_blocklist_check_retval;
1205 }
1206
ucm_create(const char * name)1207 struct cras_use_case_mgr* ucm_create(const char* name) {
1208 ucm_create_called++;
1209 strncpy(ucm_create_name, name, sizeof(ucm_create_name) - 1);
1210 return reinterpret_cast<struct cras_use_case_mgr*>(0x44);
1211 }
1212
ucm_destroy(struct cras_use_case_mgr * mgr)1213 void ucm_destroy(struct cras_use_case_mgr* mgr) {
1214 ucm_destroy_called++;
1215 }
1216
ucm_get_dev_for_mixer(struct cras_use_case_mgr * mgr,const char * mixer,enum CRAS_STREAM_DIRECTION dir)1217 char* ucm_get_dev_for_mixer(struct cras_use_case_mgr* mgr,
1218 const char* mixer,
1219 enum CRAS_STREAM_DIRECTION dir) {
1220 ucm_get_dev_for_mixer_called++;
1221 return strdup("device");
1222 }
1223
ucm_get_flag(struct cras_use_case_mgr * mgr,const char * flag_name)1224 char* ucm_get_flag(struct cras_use_case_mgr* mgr, const char* flag_name) {
1225 ucm_get_flag_called++;
1226 strncpy(ucm_get_flag_name, flag_name, sizeof(ucm_get_flag_name) - 1);
1227 return NULL;
1228 }
1229
ucm_get_coupled_mixer_names(struct cras_use_case_mgr * mgr,const char * dev)1230 struct mixer_name* ucm_get_coupled_mixer_names(struct cras_use_case_mgr* mgr,
1231 const char* dev) {
1232 return ucm_get_coupled_mixer_names_return_value;
1233 }
1234
ucm_has_fully_specified_ucm_flag(struct cras_use_case_mgr * mgr)1235 int ucm_has_fully_specified_ucm_flag(struct cras_use_case_mgr* mgr) {
1236 return ucm_has_fully_specified_ucm_flag_return_value;
1237 }
1238
ucm_get_main_volume_names(struct cras_use_case_mgr * mgr)1239 struct mixer_name* ucm_get_main_volume_names(struct cras_use_case_mgr* mgr) {
1240 return ucm_get_main_volume_names_return_value;
1241 }
1242
ucm_get_sections(struct cras_use_case_mgr * mgr)1243 struct ucm_section* ucm_get_sections(struct cras_use_case_mgr* mgr) {
1244 ucm_get_sections_called++;
1245 return ucm_get_sections_return_value;
1246 }
ucm_get_echo_reference_dev_name_for_dev(struct cras_use_case_mgr * mgr,const char * dev)1247 const char* ucm_get_echo_reference_dev_name_for_dev(
1248 struct cras_use_case_mgr* mgr,
1249 const char* dev) {
1250 int idx = ucm_get_echo_reference_dev_name_for_dev_called++;
1251 return ucm_get_echo_reference_dev_name_for_dev_return_value[idx];
1252 }
1253
cras_alsa_mixer_add_main_volume_control_by_name(struct cras_alsa_mixer * cmix,struct mixer_name * mixer_names)1254 int cras_alsa_mixer_add_main_volume_control_by_name(
1255 struct cras_alsa_mixer* cmix,
1256 struct mixer_name* mixer_names) {
1257 cras_alsa_mixer_add_main_volume_control_by_name_called++;
1258 return cras_alsa_mixer_add_main_volume_control_by_name_return_value;
1259 }
1260
cras_alsa_mixer_add_controls_in_section(struct cras_alsa_mixer * cmix,struct ucm_section * section)1261 int cras_alsa_mixer_add_controls_in_section(struct cras_alsa_mixer* cmix,
1262 struct ucm_section* section) {
1263 cras_alsa_mixer_add_controls_in_section_called++;
1264 return cras_alsa_mixer_add_controls_in_section_return_value;
1265 }
1266
cras_system_check_ignore_ucm_suffix(const char * card_name)1267 bool cras_system_check_ignore_ucm_suffix(const char* card_name) {
1268 cras_system_check_ignore_ucm_suffix_called++;
1269 return cras_system_check_ignore_ucm_suffix_value;
1270 }
1271
ucm_free_mixer_names(struct mixer_name * names)1272 void ucm_free_mixer_names(struct mixer_name* names) {
1273 struct mixer_name* m;
1274 DL_FOREACH (names, m) {
1275 DL_DELETE(names, m);
1276 free((void*)m->name);
1277 free(m);
1278 }
1279 }
1280
1281 } /* extern "C" */
1282
1283 } // namespace
1284
main(int argc,char ** argv)1285 int main(int argc, char** argv) {
1286 ::testing::InitGoogleTest(&argc, argv);
1287 openlog(NULL, LOG_PERROR, LOG_USER);
1288 return RUN_ALL_TESTS();
1289 }
1290