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 <iniparser.h>
7 #include <stdio.h>
8 #include <syslog.h>
9 #include <map>
10
11 extern "C" {
12 #include "cras_alsa_ucm.h"
13 #include "cras_types.h"
14 #include "cras_util.h"
15 #include "utlist.h"
16 #include "cras_util.h"
17
18 // Include C file to test static functions.
19 #include "cras_alsa_ucm.c"
20 }
21
22 namespace {
23
24 static int snd_use_case_mgr_open_return;
25 static snd_use_case_mgr_t *snd_use_case_mgr_open_mgr_ptr;
26 static unsigned snd_use_case_mgr_open_called;
27 static unsigned snd_use_case_mgr_close_called;
28 static unsigned snd_use_case_get_called;
29 static std::vector<std::string> snd_use_case_get_id;
30 static int snd_use_case_set_return;
31 static std::map<std::string, std::string> snd_use_case_get_value;
32 static unsigned snd_use_case_set_called;
33 static std::vector<std::pair<std::string, std::string> > snd_use_case_set_param;
34 static std::map<std::string, const char **> fake_list;
35 static std::map<std::string, unsigned> fake_list_size;
36 static unsigned snd_use_case_free_list_called;
37 static std::vector<std::string> list_devices_callback_names;
38 static std::vector<void*> list_devices_callback_args;
39 static struct cras_use_case_mgr cras_ucm_mgr;
40 static const char *avail_verbs[] = { "HiFi", "Comment for Verb1" };
41
ResetStubData()42 static void ResetStubData() {
43 snd_use_case_mgr_open_called = 0;
44 snd_use_case_mgr_open_return = 0;
45 snd_use_case_mgr_close_called = 0;
46 snd_use_case_set_return = 0;
47 snd_use_case_get_called = 0;
48 snd_use_case_set_called = 0;
49 snd_use_case_set_param.clear();
50 snd_use_case_free_list_called = 0;
51 snd_use_case_get_id.clear();
52 snd_use_case_get_value.clear();
53 fake_list.clear();
54 fake_list_size.clear();
55 fake_list["_verbs"] = avail_verbs;
56 fake_list_size["_verbs"] = 2;
57 list_devices_callback_names.clear();
58 list_devices_callback_args.clear();
59 snd_use_case_mgr_open_mgr_ptr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
60 cras_ucm_mgr.use_case = CRAS_STREAM_TYPE_DEFAULT;
61 }
62
list_devices_callback(const char * section_name,void * arg)63 static void list_devices_callback(const char* section_name, void *arg) {
64 list_devices_callback_names.push_back(std::string(section_name));
65 list_devices_callback_args.push_back(arg);
66 }
67
SetSectionDeviceData()68 static void SetSectionDeviceData() {
69 static const char *sections[] = { "Speaker", "Comment for Dev1",
70 "IntMic", "Comment for Dev2",
71 "Headphone", "Comment for Dev3",
72 "ExtMic", "Comment for Dev4",
73 "HDMI", "Comment for Dev5"};
74 fake_list["_devices/HiFi"] = sections;
75 fake_list_size["_devices/HiFi"] = 10;
76 std::string id_1 = "=PlaybackPCM/Speaker/HiFi";
77 std::string id_2 = "=CapturePCM/IntMic/HiFi";
78 std::string id_3 = "=PlaybackPCM/Headphone/HiFi";
79 std::string id_4 = "=CapturePCM/ExtMic/HiFi";
80 std::string id_5 = "=PlaybackPCM/HDMI/HiFi";
81 std::string value_1 = "test_card:0";
82 std::string value_2 = "test_card:0";
83 std::string value_3 = "test_card:0";
84 std::string value_4 = "test_card:0";
85 std::string value_5 = "test_card:1";
86
87 snd_use_case_get_value[id_1] = value_1;
88 snd_use_case_get_value[id_2] = value_2;
89 snd_use_case_get_value[id_3] = value_3;
90 snd_use_case_get_value[id_4] = value_4;
91 snd_use_case_get_value[id_5] = value_5;
92 }
93
TEST(AlsaUcm,CreateFailInvalidCard)94 TEST(AlsaUcm, CreateFailInvalidCard) {
95 ResetStubData();
96 EXPECT_EQ(NULL, ucm_create(NULL));
97 EXPECT_EQ(0, snd_use_case_mgr_open_called);
98 }
99
TEST(AlsaUcm,CreateFailCardNotFound)100 TEST(AlsaUcm, CreateFailCardNotFound) {
101 ResetStubData();
102 snd_use_case_mgr_open_return = -1;
103 EXPECT_EQ(NULL, ucm_create("foo"));
104 EXPECT_EQ(1, snd_use_case_mgr_open_called);
105 }
106
TEST(AlsaUcm,CreateFailNoHiFi)107 TEST(AlsaUcm, CreateFailNoHiFi) {
108 ResetStubData();
109 snd_use_case_set_return = -1;
110 EXPECT_EQ(NULL, ucm_create("foo"));
111 EXPECT_EQ(1, snd_use_case_mgr_open_called);
112 EXPECT_EQ(1, snd_use_case_set_called);
113 EXPECT_EQ(1, snd_use_case_mgr_close_called);
114 }
115
TEST(AlsaUcm,CreateSuccess)116 TEST(AlsaUcm, CreateSuccess) {
117 struct cras_use_case_mgr *mgr;
118
119 ResetStubData();
120
121 mgr = ucm_create("foo");
122 EXPECT_NE(static_cast<snd_use_case_mgr_t*>(NULL), mgr->mgr);
123 EXPECT_EQ(1, snd_use_case_mgr_open_called);
124 EXPECT_EQ(1, snd_use_case_set_called);
125 EXPECT_EQ(0, snd_use_case_mgr_close_called);
126
127 ucm_destroy(mgr);
128 EXPECT_EQ(1, snd_use_case_mgr_close_called);
129 }
130
TEST(AlsaUcm,CheckEnabledEmptyList)131 TEST(AlsaUcm, CheckEnabledEmptyList) {
132 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
133
134 ResetStubData();
135 fake_list["_enadevs"] = NULL;
136 fake_list_size["_enadevs"] = 0;
137
138 EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 0));
139 EXPECT_EQ(0, snd_use_case_set_called);
140
141 EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 1));
142 EXPECT_EQ(1, snd_use_case_set_called);
143
144 EXPECT_EQ(0, snd_use_case_free_list_called);
145 }
146
TEST(AlsaUcm,CheckEnabledAlready)147 TEST(AlsaUcm, CheckEnabledAlready) {
148 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
149 const char *enabled[] = { "Dev2", "Dev1" };
150
151 ResetStubData();
152
153 fake_list["_enadevs"] = enabled;
154 fake_list_size["_enadevs"] = 2;
155
156 EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 1));
157 EXPECT_EQ(0, snd_use_case_set_called);
158
159 EXPECT_EQ(0, ucm_set_enabled(mgr, "Dev1", 0));
160 EXPECT_EQ(1, snd_use_case_set_called);
161
162 EXPECT_EQ(2, snd_use_case_free_list_called);
163 }
164
TEST(AlsaUcm,GetEdidForDev)165 TEST(AlsaUcm, GetEdidForDev) {
166 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
167 std::string id = "=EDIDFile/Dev1/HiFi";
168 std::string value = "EdidFileName";
169 const char *file_name;
170
171 ResetStubData();
172
173 snd_use_case_get_value[id] = value;
174
175 file_name = ucm_get_edid_file_for_dev(mgr, "Dev1");
176 ASSERT_TRUE(file_name);
177 EXPECT_EQ(0, strcmp(file_name, value.c_str()));
178 free((void*)file_name);
179
180 ASSERT_EQ(1, snd_use_case_get_called);
181 EXPECT_EQ(snd_use_case_get_id[0], id);
182 }
183
TEST(AlsaUcm,GetCapControlForDev)184 TEST(AlsaUcm, GetCapControlForDev) {
185 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
186 char *cap_control;
187 std::string id = "=CaptureControl/Dev1/HiFi";
188 std::string value = "MIC";
189
190 ResetStubData();
191
192 snd_use_case_get_value[id] = value;
193
194 cap_control = ucm_get_cap_control(mgr, "Dev1");
195 ASSERT_TRUE(cap_control);
196 EXPECT_EQ(0, strcmp(cap_control, value.c_str()));
197 free(cap_control);
198
199 ASSERT_EQ(1, snd_use_case_get_called);
200 EXPECT_EQ(snd_use_case_get_id[0], id);
201 }
202
TEST(AlsaUcm,GetOverrideType)203 TEST(AlsaUcm, GetOverrideType) {
204 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
205 const char *override_type_name;
206 std::string id = "=OverrideNodeType/Dev1/HiFi";
207 std::string value = "HDMI";
208
209 ResetStubData();
210
211 snd_use_case_get_value[id] = value;
212
213 override_type_name = ucm_get_override_type_name(mgr, "Dev1");
214 ASSERT_TRUE(override_type_name);
215 EXPECT_EQ(0, strcmp(override_type_name, value.c_str()));
216 free((void*)override_type_name);
217
218 ASSERT_EQ(1, snd_use_case_get_called);
219 EXPECT_EQ(snd_use_case_get_id[0], id);
220 }
221
TEST(AlsaUcm,GetSectionsForVar)222 TEST(AlsaUcm, GetSectionsForVar) {
223 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
224 struct section_name *section_names, *c;
225
226 ResetStubData();
227
228 const char *sections[] = { "Sec1", "Comment for Sec1",
229 "Sec2", "Comment for Sec2",
230 "Sec3", "Comment for Sec3"};
231 fake_list["Identifier"] = sections;
232 fake_list_size["Identifier"] = 6;
233 std::string id_1 = "=Var/Sec1/HiFi";
234 std::string id_2 = "=Var/Sec2/HiFi";
235 std::string id_3 = "=Var/Sec3/HiFi";
236 std::string value_1 = "Value1";
237 std::string value_2 = "Value2";
238 std::string value_3 = "Value2";
239
240 snd_use_case_get_value[id_1] = value_1;
241 snd_use_case_get_value[id_2] = value_2;
242 snd_use_case_get_value[id_3] = value_3;
243
244 section_names = ucm_get_sections_for_var(mgr, "Var", "Value2", "Identifier",
245 CRAS_STREAM_OUTPUT);
246
247 ASSERT_TRUE(section_names);
248 EXPECT_EQ(0, strcmp(section_names->name, "Sec2"));
249 EXPECT_EQ(0, strcmp(section_names->next->name, "Sec3"));
250
251 ASSERT_EQ(3, snd_use_case_get_called);
252 EXPECT_EQ(snd_use_case_get_id[0], id_1);
253 EXPECT_EQ(snd_use_case_get_id[1], id_2);
254 EXPECT_EQ(snd_use_case_get_id[2], id_3);
255
256 DL_FOREACH(section_names, c) {
257 DL_DELETE(section_names, c);
258 free((void*)c->name);
259 free(c);
260 }
261 }
262
TEST(AlsaUcm,GetDevForJack)263 TEST(AlsaUcm, GetDevForJack) {
264 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
265 const char *dev_name;
266 const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
267 "Comment for Dev2" };
268
269 ResetStubData();
270
271 fake_list["_devices/HiFi"] = devices;
272 fake_list_size["_devices/HiFi"] = 4;
273 std::string id_1 = "=JackName/Dev1/HiFi";
274 std::string id_2 = "=JackName/Dev2/HiFi";
275 std::string value_1 = "Value1";
276 std::string value_2 = "Value2";
277
278 snd_use_case_get_value[id_1] = value_1;
279 snd_use_case_get_value[id_2] = value_2;
280 dev_name = ucm_get_dev_for_jack(mgr, value_2.c_str(), CRAS_STREAM_OUTPUT);
281 ASSERT_TRUE(dev_name);
282 EXPECT_EQ(0, strcmp(dev_name, "Dev2"));
283 free((void*)dev_name);
284
285 ASSERT_EQ(2, snd_use_case_get_called);
286 EXPECT_EQ(snd_use_case_get_id[0], id_1);
287 EXPECT_EQ(snd_use_case_get_id[1], id_2);
288 }
289
TEST(AlsaUcm,GetDevForHeadphoneJack)290 TEST(AlsaUcm, GetDevForHeadphoneJack) {
291 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
292 const char *dev_name;
293 const char *devices[] = { "Mic", "Comment for Dev1", "Headphone",
294 "Comment for Dev2" };
295
296 ResetStubData();
297
298 fake_list["_devices/HiFi"] = devices;
299 fake_list_size["_devices/HiFi"] = 4;
300 std::string id_1 = "=JackName/Mic/HiFi";
301 std::string id_2 = "=JackName/Headphone/HiFi";
302 std::string value = "JackValue";
303
304 snd_use_case_get_value[id_1] = value;
305 snd_use_case_get_value[id_2] = value;
306
307 /* Looking for jack with matched value with output direction, Headphone will
308 * be found even though Mic section has the matched value too. */
309 dev_name = ucm_get_dev_for_jack(mgr, value.c_str(), CRAS_STREAM_OUTPUT);
310
311 ASSERT_TRUE(dev_name);
312 EXPECT_EQ(0, strcmp(dev_name, "Headphone"));
313 free((void*)dev_name);
314 }
315
TEST(AlsaUcm,GetDevForMicJack)316 TEST(AlsaUcm, GetDevForMicJack) {
317 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
318 const char *dev_name;
319 const char *devices[] = { "Headphone", "Comment for Dev1", "Mic",
320 "Comment for Dev2" };
321
322 ResetStubData();
323
324 fake_list["_devices/HiFi"] = devices;
325 fake_list_size["_devices/HiFi"] = 4;
326 std::string id_1 = "=JackName/Headphone/HiFi";
327 std::string id_2 = "=JackName/Mic/HiFi";
328 std::string value = "JackValue";
329
330 snd_use_case_get_value[id_1] = value;
331 snd_use_case_get_value[id_2] = value;
332
333 /* Looking for jack with matched value with input direction, Mic will be found
334 * even though Headphone section has the matched value too. */
335 dev_name = ucm_get_dev_for_jack(mgr, value.c_str(), CRAS_STREAM_INPUT);
336
337 ASSERT_TRUE(dev_name);
338 EXPECT_EQ(0, strcmp(dev_name, "Mic"));
339 free((void*)dev_name);
340 }
341
TEST(AlsaUcm,GetDevForMixer)342 TEST(AlsaUcm, GetDevForMixer) {
343 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
344 const char *dev_name_out, *dev_name_in;
345 const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
346 "Comment for Dev2" };
347
348 ResetStubData();
349
350 fake_list["_devices/HiFi"] = devices;
351 fake_list_size["_devices/HiFi"] = 4;
352 std::string id_1 = "=MixerName/Dev1/HiFi";
353 std::string id_2 = "=MixerName/Dev2/HiFi";
354 std::string value_1 = "Value1";
355 std::string value_2 = "Value2";
356
357 snd_use_case_get_value[id_1] = value_1;
358 snd_use_case_get_value[id_2] = value_2;
359 dev_name_out = ucm_get_dev_for_mixer(
360 mgr, value_1.c_str(), CRAS_STREAM_OUTPUT);
361 dev_name_in = ucm_get_dev_for_mixer(mgr, value_2.c_str(), CRAS_STREAM_INPUT);
362
363 ASSERT_TRUE(dev_name_out);
364 EXPECT_EQ(0, strcmp(dev_name_out, "Dev1"));
365 free((void*)dev_name_out);
366
367 ASSERT_TRUE(dev_name_in);
368 EXPECT_EQ(0, strcmp(dev_name_in, "Dev2"));
369 free((void*)dev_name_in);
370 }
371
TEST(AlsaUcm,GetDeviceNameForDevice)372 TEST(AlsaUcm, GetDeviceNameForDevice) {
373 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
374 const char *input_dev_name, *output_dev_name;
375 const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
376 "Comment for Dev2" };
377
378 ResetStubData();
379
380 fake_list["_devices/HiFi"] = devices;
381 fake_list_size["_devices/HiFi"] = 4;
382 std::string id_1 = "=CapturePCM/Dev1/HiFi";
383 std::string id_2 = "=PlaybackPCM/Dev2/HiFi";
384 std::string value_1 = "DeviceName1";
385 std::string value_2 = "DeviceName2";
386
387 snd_use_case_get_value[id_1] = value_1;
388 snd_use_case_get_value[id_2] = value_2;
389 input_dev_name = ucm_get_device_name_for_dev(mgr, "Dev1", CRAS_STREAM_INPUT);
390 output_dev_name = ucm_get_device_name_for_dev(mgr, "Dev2", CRAS_STREAM_OUTPUT);
391 ASSERT_TRUE(input_dev_name);
392 ASSERT_TRUE(output_dev_name);
393 EXPECT_EQ(0, strcmp(input_dev_name, value_1.c_str()));
394 EXPECT_EQ(0, strcmp(output_dev_name, value_2.c_str()));
395
396 ASSERT_EQ(2, snd_use_case_get_called);
397 EXPECT_EQ(snd_use_case_get_id[0], id_1);
398 EXPECT_EQ(snd_use_case_get_id[1], id_2);
399 free((void *)input_dev_name);
400 free((void *)output_dev_name);
401 }
402
TEST(AlsaUcm,GetDeviceRateForDevice)403 TEST(AlsaUcm, GetDeviceRateForDevice) {
404 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
405 int input_dev_rate, output_dev_rate;
406 const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
407 "Comment for Dev2" };
408
409 ResetStubData();
410
411 fake_list["_devices/HiFi"] = devices;
412 fake_list_size["_devices/HiFi"] = 4;
413 std::string id_1 = "=CaptureRate/Dev1/HiFi";
414 std::string id_2 = "=PlaybackRate/Dev2/HiFi";
415 std::string value_1 = "44100";
416 std::string value_2 = "48000";
417
418 snd_use_case_get_value[id_1] = value_1;
419 snd_use_case_get_value[id_2] = value_2;
420 input_dev_rate = ucm_get_sample_rate_for_dev(mgr, "Dev1", CRAS_STREAM_INPUT);
421 output_dev_rate = ucm_get_sample_rate_for_dev(mgr, "Dev2",
422 CRAS_STREAM_OUTPUT);
423 EXPECT_EQ(44100, input_dev_rate);
424 EXPECT_EQ(48000, output_dev_rate);
425
426 ASSERT_EQ(2, snd_use_case_get_called);
427 EXPECT_EQ(snd_use_case_get_id[0], id_1);
428 EXPECT_EQ(snd_use_case_get_id[1], id_2);
429 }
430
TEST(AlsaUcm,GetCaptureChannelMapForDevice)431 TEST(AlsaUcm, GetCaptureChannelMapForDevice) {
432 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
433 int8_t channel_layout[CRAS_CH_MAX];
434 int rc;
435
436 ResetStubData();
437
438 std::string id_1 = "=CaptureChannelMap/Dev1/HiFi";
439 std::string value_1 = "-1 -1 0 1 -1 -1 -1 -1 -1 -1 -1";
440
441 snd_use_case_get_value[id_1] = value_1;
442 rc = ucm_get_capture_chmap_for_dev(mgr, "Dev1", channel_layout);
443
444 EXPECT_EQ(0, rc);
445
446 ASSERT_EQ(1, snd_use_case_get_called);
447 EXPECT_EQ(snd_use_case_get_id[0], id_1);
448 EXPECT_EQ(channel_layout[0], -1);
449 EXPECT_EQ(channel_layout[1], -1);
450 EXPECT_EQ(channel_layout[2], 0);
451 EXPECT_EQ(channel_layout[3], 1);
452 EXPECT_EQ(channel_layout[4], -1);
453 EXPECT_EQ(channel_layout[5], -1);
454 EXPECT_EQ(channel_layout[6], -1);
455 EXPECT_EQ(channel_layout[7], -1);
456 EXPECT_EQ(channel_layout[8], -1);
457 EXPECT_EQ(channel_layout[9], -1);
458 EXPECT_EQ(channel_layout[10], -1);
459 }
460
TEST(AlsaUcm,GetEchoReferenceDev)461 TEST(AlsaUcm, GetEchoReferenceDev) {
462 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
463 const char *echo_ref_dev;
464
465 ResetStubData();
466
467 std::string id_1 = "=EchoReferenceDev/Dev1/HiFi";
468 std::string value_1 = "Echo Ref";
469
470 snd_use_case_get_value[id_1] = value_1;
471 echo_ref_dev = ucm_get_echo_reference_dev_name_for_dev(mgr, "Dev1");
472
473 ASSERT_EQ(1, snd_use_case_get_called);
474 EXPECT_EQ(snd_use_case_get_id[0], id_1);
475 EXPECT_EQ(0, strcmp(echo_ref_dev, value_1.c_str()));
476 free((void *)echo_ref_dev);
477 }
478
TEST(AlsaUcm,GetHotwordModels)479 TEST(AlsaUcm, GetHotwordModels) {
480 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
481 const char *models;
482 const char *modifiers[] = { "Mod1",
483 "Comment1",
484 "Hotword Model en",
485 "Comment2",
486 "Hotword Model jp",
487 "Comment3",
488 "Mod2",
489 "Comment4",
490 "Hotword Model de",
491 "Comment5" };
492 ResetStubData();
493
494 fake_list["_modifiers/HiFi"] = modifiers;
495 fake_list_size["_modifiers/HiFi"] = 10;
496
497 models = ucm_get_hotword_models(mgr);
498 ASSERT_TRUE(models);
499 EXPECT_EQ(0, strcmp(models, "en,jp,de"));
500 free((void *)models);
501 }
502
TEST(AlsaUcm,SetHotwordModel)503 TEST(AlsaUcm, SetHotwordModel) {
504 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
505 const char *modifiers[] = { "Hotword Model en",
506 "Comment1",
507 "Hotword Model jp",
508 "Comment2",
509 "Hotword Model de",
510 "Comment3" };
511 const char *enabled_mods[] = { "Hotword Model en" };
512 ResetStubData();
513
514 fake_list["_modifiers/HiFi"] = modifiers;
515 fake_list_size["_modifiers/HiFi"] = 6;
516
517 EXPECT_EQ(-EINVAL, ucm_set_hotword_model(mgr, "zh"));
518 EXPECT_EQ(0, snd_use_case_set_called);
519
520 fake_list["_enamods"] = enabled_mods;
521 fake_list_size["_enamods"] = 1;
522 ucm_set_hotword_model(mgr, "jp");
523
524 EXPECT_EQ(2, snd_use_case_set_called);
525 EXPECT_EQ(snd_use_case_set_param[0],
526 std::make_pair(std::string("_dismod"), std::string("Hotword Model en")));
527 EXPECT_EQ(snd_use_case_set_param[1],
528 std::make_pair(std::string("_enamod"), std::string("Hotword Model jp")));
529 }
530
TEST(AlsaUcm,SwapModeExists)531 TEST(AlsaUcm, SwapModeExists) {
532 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
533 int rc;
534 const char *modifiers_1[] = { "Speaker Swap Mode",
535 "Comment for Speaker Swap Mode",
536 "Microphone Swap Mode",
537 "Comment for Microphone Swap Mode" };
538 const char *modifiers_2[] = { "Speaker Some Mode",
539 "Comment for Speaker Some Mode",
540 "Microphone Some Mode",
541 "Comment for Microphone Some Mode" };
542
543 ResetStubData();
544
545 fake_list["_modifiers/HiFi"] = modifiers_1;
546 fake_list_size["_modifiers/HiFi"] = 4;
547 rc = ucm_swap_mode_exists(mgr);
548 EXPECT_EQ(1, rc);
549
550 fake_list["_modifiers/HiFi"] = modifiers_2;
551 fake_list_size["_modifiers/HiFi"] = 4;
552 rc = ucm_swap_mode_exists(mgr);
553 EXPECT_EQ(0, rc);
554 }
555
TEST(AlsaUcm,EnableSwapMode)556 TEST(AlsaUcm, EnableSwapMode) {
557 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
558 int rc;
559 const char *modifiers[] = { "Speaker Swap Mode",
560 "Comment for Speaker Swap Mode",
561 "Microphone Swap Mode",
562 "Comment for Microphone Swap Mode" };
563 const char *modifiers_enabled[] = {"Speaker Swap Mode"};
564
565 ResetStubData();
566
567 fake_list["_modifiers/HiFi"] = modifiers;
568 fake_list_size["_modifiers/HiFi"] = 4;
569
570 fake_list["_enamods"] = modifiers_enabled;
571 fake_list_size["_enamods"] = 1;
572
573 snd_use_case_set_return = 0;
574
575 rc = ucm_enable_swap_mode(mgr, "Headphone", 1);
576 EXPECT_EQ(-EPERM, rc);
577 EXPECT_EQ(0, snd_use_case_set_called);
578
579 rc = ucm_enable_swap_mode(mgr, "Speaker", 1);
580 EXPECT_EQ(0, rc);
581 EXPECT_EQ(0, snd_use_case_set_called);
582
583 rc = ucm_enable_swap_mode(mgr, "Microphone", 1);
584 EXPECT_EQ(0, rc);
585 EXPECT_EQ(1, snd_use_case_set_called);
586 }
587
TEST(AlsaUcm,DisableSwapMode)588 TEST(AlsaUcm, DisableSwapMode) {
589 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
590 int rc;
591 const char *modifiers[] = { "Speaker Swap Mode",
592 "Comment for Speaker Swap Mode",
593 "Microphone Swap Mode",
594 "Comment for Microphone Swap Mode" };
595 const char *modifiers_enabled[] = {"Speaker Swap Mode"};
596
597 ResetStubData();
598
599 fake_list["_modifiers/HiFi"] = modifiers;
600 fake_list_size["_modifiers/HiFi"] = 4;
601
602 fake_list["_enamods"] = modifiers_enabled;
603 fake_list_size["_enamods"] = 1;
604
605 snd_use_case_set_return = 0;
606
607 rc = ucm_enable_swap_mode(mgr, "Headphone", 0);
608 EXPECT_EQ(-EPERM, rc);
609 EXPECT_EQ(0, snd_use_case_set_called);
610
611 rc = ucm_enable_swap_mode(mgr, "Microphone", 0);
612 EXPECT_EQ(0, rc);
613 EXPECT_EQ(0, snd_use_case_set_called);
614
615 rc = ucm_enable_swap_mode(mgr, "Speaker", 0);
616 EXPECT_EQ(0, rc);
617 EXPECT_EQ(1, snd_use_case_set_called);
618
619 }
620
TEST(AlsaFlag,GetFlag)621 TEST(AlsaFlag, GetFlag) {
622 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
623 char *flag_value;
624
625 std::string id = "=FlagName//HiFi";
626 std::string value = "1";
627 ResetStubData();
628
629 snd_use_case_get_value[id] = value;
630
631 flag_value = ucm_get_flag(mgr, "FlagName");
632 ASSERT_TRUE(flag_value);
633 EXPECT_EQ(0, strcmp(flag_value, value.c_str()));
634 free(flag_value);
635
636 ASSERT_EQ(1, snd_use_case_get_called);
637 EXPECT_EQ(snd_use_case_get_id[0], id);
638 }
639
TEST(AlsaUcm,ModifierEnabled)640 TEST(AlsaUcm, ModifierEnabled) {
641 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
642 int enabled;
643
644 ResetStubData();
645
646 const char *mods[] = { "Mod1", "Mod2" };
647 fake_list["_enamods"] = mods;
648 fake_list_size["_enamods"] = 2;
649
650 enabled = modifier_enabled(mgr, "Mod1");
651 EXPECT_EQ(1, enabled);
652 enabled = modifier_enabled(mgr, "Mod2");
653 EXPECT_EQ(1, enabled);
654 enabled = modifier_enabled(mgr, "Mod3");
655 EXPECT_EQ(0, enabled);
656 }
657
TEST(AlsaUcm,SetModifierEnabled)658 TEST(AlsaUcm, SetModifierEnabled) {
659 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
660
661 ResetStubData();
662
663 ucm_set_modifier_enabled(mgr, "Mod1", 1);
664 EXPECT_EQ(snd_use_case_set_param[0],
665 std::make_pair(std::string("_enamod"), std::string("Mod1")));
666 EXPECT_EQ(1, snd_use_case_set_called);
667 ucm_set_modifier_enabled(mgr, "Mod1", 0);
668 EXPECT_EQ(snd_use_case_set_param[1],
669 std::make_pair(std::string("_dismod"), std::string("Mod1")));
670 EXPECT_EQ(2, snd_use_case_set_called);
671 }
672
TEST(AlsaUcm,EndWithSuffix)673 TEST(AlsaUcm, EndWithSuffix) {
674 EXPECT_EQ(1, ucm_str_ends_with_suffix("Foo bar", "bar"));
675 EXPECT_EQ(1, ucm_str_ends_with_suffix("bar", "bar"));
676 EXPECT_EQ(0, ucm_str_ends_with_suffix("Foo car", "bar"));
677 }
678
TEST(AlsaUcm,SectionExistsWithName)679 TEST(AlsaUcm, SectionExistsWithName) {
680 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
681 const char *sections[] = { "Sec1", "Comment for Sec1", "Sec2",
682 "Comment for Sec2" };
683
684 ResetStubData();
685
686 fake_list["Identifier"] = sections;
687 fake_list_size["Identifier"] = 4;
688 EXPECT_EQ(1, ucm_section_exists_with_name(mgr, "Sec1", "Identifier"));
689 EXPECT_EQ(1, ucm_section_exists_with_name(mgr, "Sec2", "Identifier"));
690 EXPECT_EQ(0, ucm_section_exists_with_name(mgr, "Sec3", "Identifier"));
691 }
692
TEST(AlsaUcm,SectionExistsWithSuffix)693 TEST(AlsaUcm, SectionExistsWithSuffix) {
694 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
695
696 ResetStubData();
697
698 const char *sections[] = { "Sec1 Suffix1", "Comment for Sec1",
699 "Sec2 Suffix2", "Comment for Sec2" };
700 fake_list["Identifier"] = sections;
701 fake_list_size["Identifier"] = 4;
702 EXPECT_EQ(1, ucm_section_exists_with_suffix(mgr, "Suffix1", "Identifier"));
703 EXPECT_EQ(1, ucm_section_exists_with_suffix(mgr, "Suffix2", "Identifier"));
704 EXPECT_EQ(0, ucm_section_exists_with_suffix(mgr, "Suffix3", "Identifier"));
705 }
706
TEST(AlsaUcm,DisableSoftwareVolume)707 TEST(AlsaUcm, DisableSoftwareVolume) {
708 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
709 unsigned int disable_software_volume;
710 std::string id = "=DisableSoftwareVolume//HiFi";
711 std::string value = "1";
712
713 ResetStubData();
714
715 snd_use_case_get_value[id] = value;
716
717 disable_software_volume = ucm_get_disable_software_volume(mgr);
718 ASSERT_TRUE(disable_software_volume);
719
720 ASSERT_EQ(1, snd_use_case_get_called);
721 EXPECT_EQ(snd_use_case_get_id[0], id);
722 }
723
TEST(AlsaUcm,GetCoupledMixersForDevice)724 TEST(AlsaUcm, GetCoupledMixersForDevice) {
725 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
726 struct mixer_name *mixer_names_1, *mixer_names_2, *c;
727 const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
728 "Comment for Dev2" };
729
730 ResetStubData();
731
732 fake_list["_devices/HiFi"] = devices;
733 fake_list_size["_devices/HiFi"] = 4;
734 std::string id_1 = "=CoupledMixers/Dev1/HiFi";
735 std::string value_1 = "Mixer Name1,Mixer Name2,Mixer Name3";
736 std::string id_2 = "=CoupledMixers/Dev2/HiFi";
737 std::string value_2 = "";
738 snd_use_case_get_value[id_1] = value_1;
739 snd_use_case_get_value[id_2] = value_2;
740 mixer_names_1 = ucm_get_coupled_mixer_names(mgr, "Dev1");
741 mixer_names_2 = ucm_get_coupled_mixer_names(mgr, "Dev2");
742
743 ASSERT_TRUE(mixer_names_1);
744 EXPECT_EQ(0, strcmp(mixer_names_1->name, "Mixer Name1"));
745 EXPECT_EQ(0, strcmp(mixer_names_1->next->name, "Mixer Name2"));
746 EXPECT_EQ(0, strcmp(mixer_names_1->next->next->name, "Mixer Name3"));
747 EXPECT_EQ(NULL, mixer_names_1->next->next->next);
748
749 EXPECT_EQ(NULL, mixer_names_2);
750
751 DL_FOREACH(mixer_names_1, c) {
752 DL_DELETE(mixer_names_1, c);
753 free((void*)c->name);
754 free(c);
755 }
756 }
757
TEST(AlsaUcm,FreeMixerNames)758 TEST(AlsaUcm, FreeMixerNames) {
759 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
760 struct mixer_name *mixer_names_1;
761 const char *devices[] = { "Dev1", "Comment for Dev1"};
762
763 ResetStubData();
764
765 fake_list["_devices/HiFi"] = devices;
766 fake_list_size["_devices/HiFi"] = 2;
767 std::string id_1 = "=CoupledMixers/Dev1/HiFi";
768 std::string value_1 = "Mixer Name1,Mixer Name2,Mixer Name3";
769 snd_use_case_get_value[id_1] = value_1;
770 mixer_names_1 = ucm_get_coupled_mixer_names(mgr, "Dev1");
771
772
773 ASSERT_TRUE(mixer_names_1);
774 EXPECT_EQ(0, strcmp(mixer_names_1->name, "Mixer Name1"));
775 EXPECT_EQ(0, strcmp(mixer_names_1->next->name, "Mixer Name2"));
776 EXPECT_EQ(0, strcmp(mixer_names_1->next->next->name, "Mixer Name3"));
777 EXPECT_EQ(NULL, mixer_names_1->next->next->next);
778
779 /* No way to actually check if memory is freed. */
780 mixer_name_free(mixer_names_1);
781 }
782
TEST(AlsaUcm,MaxSoftwareGain)783 TEST(AlsaUcm, MaxSoftwareGain) {
784 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
785 long max_software_gain;
786 int ret;
787 std::string id = "=MaxSoftwareGain/Internal Mic/HiFi";
788 std::string value = "2000";
789
790 ResetStubData();
791
792 /* Value can be found in UCM. */
793 snd_use_case_get_value[id] = value;
794
795 ret = ucm_get_max_software_gain(mgr, "Internal Mic", &max_software_gain);
796
797 EXPECT_EQ(0, ret);
798 EXPECT_EQ(2000, max_software_gain);
799
800 ResetStubData();
801
802 /* Value can not be found in UCM. */
803 ret = ucm_get_max_software_gain(mgr, "Internal Mic", &max_software_gain);
804
805 ASSERT_TRUE(ret);
806 }
807
TEST(AlsaUcm,MinSoftwareGain)808 TEST(AlsaUcm, MinSoftwareGain) {
809 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
810 long min_software_gain;
811 int ret;
812 std::string id = "=MinSoftwareGain/Internal Mic/HiFi";
813 std::string value = "2000";
814
815 ResetStubData();
816
817 /* Value can be found in UCM. */
818 snd_use_case_get_value[id] = value;
819
820 ret = ucm_get_min_software_gain(mgr, "Internal Mic", &min_software_gain);
821
822 EXPECT_EQ(0, ret);
823 EXPECT_EQ(2000, min_software_gain);
824
825 ResetStubData();
826
827 /* Value can not be found in UCM. */
828 ret = ucm_get_min_software_gain(mgr, "Internal Mic", &min_software_gain);
829
830 ASSERT_TRUE(ret);
831 }
832
TEST(AlsaUcm,DefaultNodeGain)833 TEST(AlsaUcm, DefaultNodeGain) {
834 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
835 long default_node_gain;
836 int ret;
837 std::string id = "=DefaultNodeGain/Internal Mic/HiFi";
838 std::string value = "-2000";
839
840 ResetStubData();
841
842 /* Value can be found in UCM. */
843 snd_use_case_get_value[id] = value;
844
845 ret = ucm_get_default_node_gain(mgr, "Internal Mic", &default_node_gain);
846
847 EXPECT_EQ(0, ret);
848 EXPECT_EQ(-2000, default_node_gain);
849
850 ResetStubData();
851
852 /* Value can not be found in UCM. */
853 ret = ucm_get_default_node_gain(mgr, "Internal Mic", &default_node_gain);
854
855 ASSERT_TRUE(ret);
856 }
857
TEST(AlsaUcm,UseFullySpecifiedUCMConfig)858 TEST(AlsaUcm, UseFullySpecifiedUCMConfig) {
859 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
860 int fully_specified_flag;
861
862 std::string id = "=FullySpecifiedUCM//HiFi";
863 ResetStubData();
864
865 /* Flag is not set */
866 fully_specified_flag = ucm_has_fully_specified_ucm_flag(mgr);
867 ASSERT_FALSE(fully_specified_flag);
868
869 /* Flag is set to "1". */
870 snd_use_case_get_value[id] = std::string("1");
871 fully_specified_flag = ucm_has_fully_specified_ucm_flag(mgr);
872 ASSERT_TRUE(fully_specified_flag);
873
874 /* Flag is set to "0". */
875 snd_use_case_get_value[id] = std::string("0");
876 fully_specified_flag = ucm_has_fully_specified_ucm_flag(mgr);
877 ASSERT_FALSE(fully_specified_flag);
878 }
879
TEST(AlsaUcm,EnableHtimestampFlag)880 TEST(AlsaUcm, EnableHtimestampFlag) {
881 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
882 unsigned int enable_htimestamp_flag;
883
884 std::string id = "=EnableHtimestamp//HiFi";
885 ResetStubData();
886
887 /* Flag is not set */
888 enable_htimestamp_flag = ucm_get_enable_htimestamp_flag(mgr);
889 ASSERT_FALSE(enable_htimestamp_flag);
890
891 /* Flag is set to "1". */
892 snd_use_case_get_value[id] = std::string("1");
893 enable_htimestamp_flag = ucm_get_enable_htimestamp_flag(mgr);
894 ASSERT_TRUE(enable_htimestamp_flag);
895
896 /* Flag is set to "0". */
897 snd_use_case_get_value[id] = std::string("0");
898 enable_htimestamp_flag = ucm_get_enable_htimestamp_flag(mgr);
899 ASSERT_FALSE(enable_htimestamp_flag);
900 }
901
TEST(AlsaUcm,GetMixerNameForDevice)902 TEST(AlsaUcm, GetMixerNameForDevice) {
903 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
904 const char *mixer_name_1, *mixer_name_2;
905 const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
906 "Comment for Dev2" };
907
908 ResetStubData();
909
910 fake_list["_devices/HiFi"] = devices;
911 fake_list_size["_devices/HiFi"] = 4;
912 std::string id_1 = "=MixerName/Dev1/HiFi";
913 std::string id_2 = "=MixerName/Dev2/HiFi";
914 std::string value_1 = "MixerName1";
915 std::string value_2 = "MixerName2";
916
917 snd_use_case_get_value[id_1] = value_1;
918 snd_use_case_get_value[id_2] = value_2;
919 mixer_name_1 = ucm_get_mixer_name_for_dev(mgr, "Dev1");
920 mixer_name_2 = ucm_get_mixer_name_for_dev(mgr, "Dev2");
921
922 EXPECT_EQ(0, strcmp(mixer_name_1, value_1.c_str()));
923 EXPECT_EQ(0, strcmp(mixer_name_2, value_2.c_str()));
924 free((void *)mixer_name_1);
925 free((void *)mixer_name_2);
926 }
927
TEST(AlsaUcm,GetMainVolumeMixerName)928 TEST(AlsaUcm, GetMainVolumeMixerName) {
929 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
930 struct mixer_name *mixer_names_1, *mixer_names_2, *c;
931
932 ResetStubData();
933
934 std::string id = "=MainVolumeNames//HiFi";
935 std::string value_1 = "Mixer Name1,Mixer Name2,Mixer Name3";
936
937 snd_use_case_get_value[id] = value_1;
938 mixer_names_1 = ucm_get_main_volume_names(mgr);
939
940 ResetStubData();
941
942 /* Can not find MainVolumeNames */
943 mixer_names_2 = ucm_get_main_volume_names(mgr);
944
945 ASSERT_TRUE(mixer_names_1);
946 EXPECT_EQ(0, strcmp(mixer_names_1->name, "Mixer Name1"));
947 EXPECT_EQ(0, strcmp(mixer_names_1->next->name, "Mixer Name2"));
948 EXPECT_EQ(0, strcmp(mixer_names_1->next->next->name, "Mixer Name3"));
949 EXPECT_EQ(NULL, mixer_names_1->next->next->next);
950
951 DL_FOREACH(mixer_names_1, c) {
952 DL_DELETE(mixer_names_1, c);
953 free((void*)c->name);
954 free(c);
955 }
956
957 EXPECT_EQ(NULL, mixer_names_2);
958 }
959
TEST(AlsaUcm,ListSectionsByDeviceNameOutput)960 TEST(AlsaUcm, ListSectionsByDeviceNameOutput) {
961 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
962 void* callback_arg = reinterpret_cast<void*>(0x56);
963 int listed = 0;
964
965 ResetStubData();
966 SetSectionDeviceData();
967
968 listed = ucm_list_section_devices_by_device_name(
969 mgr, CRAS_STREAM_OUTPUT, "test_card:0", list_devices_callback,
970 callback_arg);
971
972 EXPECT_EQ(2, listed);
973 EXPECT_EQ(2, list_devices_callback_names.size());
974 EXPECT_EQ(2, list_devices_callback_args.size());
975
976 EXPECT_EQ(
977 0, strcmp(list_devices_callback_names[0].c_str(), "Speaker"));
978 EXPECT_EQ(callback_arg, list_devices_callback_args[0]);
979
980 EXPECT_EQ(
981 0, strcmp(list_devices_callback_names[1].c_str(), "Headphone"));
982 EXPECT_EQ(callback_arg, list_devices_callback_args[1]);
983 }
984
TEST(AlsaUcm,ListSectionsByDeviceNameInput)985 TEST(AlsaUcm, ListSectionsByDeviceNameInput) {
986 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
987 void* callback_arg = reinterpret_cast<void*>(0x56);
988 int listed = 0;
989
990 ResetStubData();
991 SetSectionDeviceData();
992
993 listed = ucm_list_section_devices_by_device_name(
994 mgr, CRAS_STREAM_INPUT, "test_card:0", list_devices_callback,
995 callback_arg);
996
997 EXPECT_EQ(2, listed);
998 EXPECT_EQ(2, list_devices_callback_names.size());
999 EXPECT_EQ(2, list_devices_callback_args.size());
1000
1001 EXPECT_EQ(
1002 0, strcmp(list_devices_callback_names[0].c_str(), "IntMic"));
1003 EXPECT_EQ(callback_arg, list_devices_callback_args[0]);
1004
1005 EXPECT_EQ(
1006 0, strcmp(list_devices_callback_names[1].c_str(), "ExtMic"));
1007 EXPECT_EQ(callback_arg, list_devices_callback_args[1]);
1008 }
1009
TEST(AlsaUcm,GetJackNameForDevice)1010 TEST(AlsaUcm, GetJackNameForDevice) {
1011 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
1012 const char *jack_name_1, *jack_name_2;
1013 const char *devices[] = { "Dev1", "Comment for Dev1", "Dev2",
1014 "Comment for Dev2" };
1015
1016 ResetStubData();
1017
1018 fake_list["_devices/HiFi"] = devices;
1019 fake_list_size["_devices/HiFi"] = 4;
1020 std::string id_1 = "=JackName/Dev1/HiFi";
1021 std::string value_1 = "JackName1";
1022
1023 snd_use_case_get_value[id_1] = value_1;
1024 jack_name_1 = ucm_get_jack_name_for_dev(mgr, "Dev1");
1025 jack_name_2 = ucm_get_jack_name_for_dev(mgr, "Dev2");
1026
1027 EXPECT_EQ(0, strcmp(jack_name_1, value_1.c_str()));
1028 EXPECT_EQ(NULL, jack_name_2);
1029
1030 free((void *)jack_name_1);
1031 free((void *)jack_name_2);
1032 }
1033
TEST(AlsaUcm,GetJackTypeForDevice)1034 TEST(AlsaUcm, GetJackTypeForDevice) {
1035 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
1036 const char *jack_type_1, *jack_type_2, *jack_type_3, *jack_type_4;
1037 const char *devices[] = { "Dev1", "Comment for Dev1",
1038 "Dev2", "Comment for Dev2",
1039 "Dev3", "Comment for Dev3",
1040 "Dev4", "Comment for Dev4"};
1041
1042 ResetStubData();
1043
1044 fake_list["_devices/HiFi"] = devices;
1045 fake_list_size["_devices/HiFi"] = 8;
1046 std::string id_1 = "=JackType/Dev1/HiFi";
1047 std::string value_1 = "hctl";
1048 std::string id_2 = "=JackType/Dev2/HiFi";
1049 std::string value_2 = "gpio";
1050 std::string id_3 = "=JackType/Dev3/HiFi";
1051 std::string value_3 = "something";
1052
1053 snd_use_case_get_value[id_1] = value_1;
1054 snd_use_case_get_value[id_2] = value_2;
1055 snd_use_case_get_value[id_3] = value_3;
1056
1057 jack_type_1 = ucm_get_jack_type_for_dev(mgr, "Dev1");
1058 jack_type_2 = ucm_get_jack_type_for_dev(mgr, "Dev2");
1059 jack_type_3 = ucm_get_jack_type_for_dev(mgr, "Dev3");
1060 jack_type_4 = ucm_get_jack_type_for_dev(mgr, "Dev4");
1061
1062 /* Only "hctl" and "gpio" are valid types. */
1063 EXPECT_EQ(0, strcmp(jack_type_1, value_1.c_str()));
1064 EXPECT_EQ(0, strcmp(jack_type_2, value_2.c_str()));
1065 EXPECT_EQ(NULL, jack_type_3);
1066 EXPECT_EQ(NULL, jack_type_4);
1067
1068 free((void *)jack_type_1);
1069 free((void *)jack_type_2);
1070 free((void *)jack_type_3);
1071 free((void *)jack_type_4);
1072 }
1073
TEST(AlsaUcm,GetPeriodFramesForDevice)1074 TEST(AlsaUcm, GetPeriodFramesForDevice) {
1075 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
1076 int dma_period_1, dma_period_2, dma_period_3;
1077 const char *devices[] = { "Dev1", "Comment for Dev1",
1078 "Dev2", "Comment for Dev2",
1079 "Dev3", "Comment for Dev3" };
1080
1081 ResetStubData();
1082
1083 fake_list["_devices/HiFi"] = devices;
1084 fake_list_size["_devices/HiFi"] = 6;
1085 std::string id_1 = "=DmaPeriodMicrosecs/Dev1/HiFi";
1086 std::string value_1 = "1000";
1087 std::string id_2 = "=DmaPeriodMicrosecs/Dev2/HiFi";
1088 std::string value_2 = "-10";
1089
1090 snd_use_case_get_value[id_1] = value_1;
1091 snd_use_case_get_value[id_2] = value_2;
1092
1093 dma_period_1 = ucm_get_dma_period_for_dev(mgr, "Dev1");
1094 dma_period_2 = ucm_get_dma_period_for_dev(mgr, "Dev2");
1095 dma_period_3 = ucm_get_dma_period_for_dev(mgr, "Dev3");
1096
1097 /* Only "hctl" and "gpio" are valid types. */
1098 EXPECT_EQ(1000, dma_period_1);
1099 EXPECT_EQ(0, dma_period_2);
1100 EXPECT_EQ(0, dma_period_3);
1101 }
1102
TEST(AlsaUcm,UcmSection)1103 TEST(AlsaUcm, UcmSection) {
1104 struct ucm_section *section_list = NULL;
1105 struct ucm_section *section;
1106 struct mixer_name *controls = NULL;
1107 struct mixer_name *m_name;
1108 int dev_idx = 0;
1109 size_t i;
1110 enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_OUTPUT;
1111 static const char *name = "Headphone";
1112 static const char *jack_name = "my-card-name Headset Jack";
1113 static const char *jack_type = "gpio";
1114 static const char *mixer_name = "Control1";
1115 static const char *coupled_names[] = {
1116 "Coupled1",
1117 "Coupled2"
1118 };
1119
1120 section = ucm_section_create(NULL, 0, CRAS_STREAM_OUTPUT, NULL, NULL);
1121 EXPECT_EQ(reinterpret_cast<struct ucm_section*>(NULL), section);
1122
1123 section = ucm_section_create(name, dev_idx, dir, jack_name, jack_type);
1124 EXPECT_NE(reinterpret_cast<struct ucm_section*>(NULL), section);
1125 EXPECT_NE(name, section->name);
1126 EXPECT_EQ(0, strcmp(name, section->name));
1127 EXPECT_EQ(dev_idx, section->dev_idx);
1128 EXPECT_EQ(dir, section->dir);
1129 EXPECT_NE(jack_name, section->jack_name);
1130 EXPECT_NE(jack_type, section->jack_type);
1131 EXPECT_EQ(section->prev, section);
1132 EXPECT_EQ(reinterpret_cast<const char *>(NULL), section->mixer_name);
1133 EXPECT_EQ(reinterpret_cast<struct mixer_name*>(NULL), section->coupled);
1134
1135 EXPECT_EQ(-EINVAL, ucm_section_set_mixer_name(section, NULL));
1136 EXPECT_EQ(-EINVAL, ucm_section_set_mixer_name(NULL, mixer_name));
1137 EXPECT_EQ(0, ucm_section_set_mixer_name(section, mixer_name));
1138
1139 EXPECT_NE(section->mixer_name, mixer_name);
1140 EXPECT_EQ(0, strcmp(section->mixer_name, mixer_name));
1141
1142 EXPECT_EQ(-EINVAL, ucm_section_add_coupled(
1143 section, NULL, MIXER_NAME_VOLUME));
1144 EXPECT_EQ(-EINVAL, ucm_section_add_coupled(
1145 NULL, coupled_names[0], MIXER_NAME_VOLUME));
1146 EXPECT_EQ(0, ucm_section_add_coupled(
1147 section, coupled_names[0], MIXER_NAME_VOLUME));
1148
1149 EXPECT_EQ(-EINVAL, ucm_section_concat_coupled(section, NULL));
1150 EXPECT_EQ(-EINVAL, ucm_section_concat_coupled(
1151 NULL, reinterpret_cast<struct mixer_name*>(0x1111)));
1152
1153 controls = NULL;
1154 for (i = 1; i < ARRAY_SIZE(coupled_names); i++) {
1155 controls = mixer_name_add(controls, coupled_names[i],
1156 CRAS_STREAM_OUTPUT, MIXER_NAME_VOLUME);
1157 }
1158 /* Add controls to the list of coupled controls for this section. */
1159 EXPECT_EQ(0, ucm_section_concat_coupled(section, controls));
1160
1161 i = 0;
1162 DL_FOREACH(section->coupled, m_name) {
1163 EXPECT_NE(m_name->name, coupled_names[i]);
1164 EXPECT_EQ(0, strcmp(m_name->name, coupled_names[i]));
1165 i++;
1166 }
1167 EXPECT_EQ(i, ARRAY_SIZE(coupled_names));
1168
1169 DL_APPEND(section_list, section);
1170 ucm_section_free_list(section_list);
1171 }
1172
TEST(AlsaUcm,GetSections)1173 TEST(AlsaUcm, GetSections) {
1174 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
1175 struct ucm_section* sections;
1176 struct ucm_section* section;
1177 struct mixer_name* m_name;
1178 int section_count = 0;
1179 int i = 0;
1180 const char *devices[] = { "Headphone", "The headphones jack.",
1181 "Speaker", "The speakers.",
1182 "Mic", "Microphone jack.",
1183 "Internal Mic", "Internal Microphones",
1184 "HDMI", "HDMI output" };
1185 const char* ids[] = {
1186 "=PlaybackPCM/Headphone/HiFi",
1187 "=JackName/Headphone/HiFi",
1188 "=JackType/Headphone/HiFi",
1189 "=JackSwitch/Headphone/HiFi",
1190 "=CoupledMixers/Headphone/HiFi",
1191
1192 "=PlaybackPCM/Speaker/HiFi",
1193 "=CoupledMixers/Speaker/HiFi",
1194
1195 "=CapturePCM/Mic/HiFi",
1196 "=JackName/Mic/HiFi",
1197 "=JackType/Mic/HiFi",
1198 "=JackSwitch/Mic/HiFi",
1199 "=MixerName/Mic/HiFi",
1200
1201 "=CapturePCM/Internal Mic/HiFi",
1202 "=CoupledMixers/Internal Mic/HiFi",
1203 "=JackSwitch/Internal Mic/HiFi",
1204
1205 "=PlaybackPCM/HDMI/HiFi",
1206 "=MixerName/HDMI/HiFi",
1207
1208 NULL
1209 };
1210 const char* values[] = {
1211 "hw:my-sound-card,0",
1212 "my-sound-card Headset Jack",
1213 "gpio",
1214 "2",
1215 "HP-L,HP-R",
1216
1217 "hw:my-sound-card,0",
1218 "SPK-L,SPK-R",
1219
1220 "hw:my-sound-card,0",
1221 "my-sound-card Headset Jack",
1222 "gpio",
1223 "0",
1224 "CAPTURE",
1225
1226 "hw:my-sound-card,0",
1227 "MIC-L,MIC-R",
1228 "-10",
1229
1230 "hw:my-sound-card,2",
1231 "HDMI",
1232 };
1233
1234 ResetStubData();
1235
1236 fake_list["_devices/HiFi"] = devices;
1237 fake_list_size["_devices/HiFi"] = ARRAY_SIZE(devices);
1238
1239 while (ids[i]) {
1240 snd_use_case_get_value[ids[i]] = values[i];
1241 i++;
1242 }
1243
1244 sections = ucm_get_sections(mgr);
1245 ASSERT_NE(sections, (struct ucm_section*)NULL);
1246 DL_FOREACH(sections, section) {
1247 section_count++;
1248 }
1249 EXPECT_EQ(section_count, ARRAY_SIZE(devices) / 2);
1250
1251 // Headphone
1252 section = sections;
1253 EXPECT_EQ(0, strcmp(section->name, "Headphone"));
1254 EXPECT_EQ(0, section->dev_idx);
1255 EXPECT_EQ(CRAS_STREAM_OUTPUT, section->dir);
1256 EXPECT_EQ(0, strcmp(section->jack_name, values[1]));
1257 EXPECT_EQ(0, strcmp(section->jack_type, values[2]));
1258 EXPECT_EQ(NULL, section->mixer_name);
1259 ASSERT_NE((struct mixer_name*)NULL, section->coupled);
1260 m_name = section->coupled;
1261 EXPECT_EQ(0, strcmp(m_name->name, "HP-L"));
1262 m_name = m_name->next;
1263 EXPECT_EQ(0, strcmp(m_name->name, "HP-R"));
1264 EXPECT_EQ(NULL, m_name->next);
1265 EXPECT_EQ(2, section->jack_switch);
1266
1267 // Speaker
1268 section = section->next;
1269 EXPECT_EQ(0, strcmp(section->name, "Speaker"));
1270 EXPECT_EQ(0, section->dev_idx);
1271 EXPECT_EQ(CRAS_STREAM_OUTPUT, section->dir);
1272 EXPECT_EQ(NULL, section->jack_name);
1273 EXPECT_EQ(NULL, section->jack_type);
1274 EXPECT_EQ(-1, section->jack_switch);
1275 EXPECT_EQ(NULL, section->mixer_name);
1276 ASSERT_NE((struct mixer_name*)NULL, section->coupled);
1277 m_name = section->coupled;
1278 EXPECT_EQ(0, strcmp(m_name->name, "SPK-L"));
1279 m_name = m_name->next;
1280 EXPECT_EQ(0, strcmp(m_name->name, "SPK-R"));
1281 EXPECT_EQ(NULL, m_name->next);
1282
1283 // Mic
1284 section = section->next;
1285 EXPECT_EQ(0, strcmp(section->name, "Mic"));
1286 EXPECT_EQ(0, section->dev_idx);
1287 EXPECT_EQ(CRAS_STREAM_INPUT, section->dir);
1288 EXPECT_EQ(0, strcmp(section->jack_name, values[1]));
1289 EXPECT_EQ(0, strcmp(section->jack_type, values[2]));
1290 EXPECT_EQ(0, section->jack_switch);
1291 ASSERT_NE((const char *)NULL, section->mixer_name);
1292 EXPECT_EQ(0, strcmp(section->mixer_name, "CAPTURE"));
1293 EXPECT_EQ(NULL, section->coupled);
1294
1295 // Internal Mic
1296 section = section->next;
1297 EXPECT_EQ(0, strcmp(section->name, "Internal Mic"));
1298 EXPECT_EQ(0, section->dev_idx);
1299 EXPECT_EQ(CRAS_STREAM_INPUT, section->dir);
1300 EXPECT_EQ(NULL, section->jack_name);
1301 EXPECT_EQ(NULL, section->jack_type);
1302 EXPECT_EQ(-1, section->jack_switch);
1303 EXPECT_EQ(NULL, section->mixer_name);
1304 ASSERT_NE((struct mixer_name*)NULL, section->coupled);
1305 m_name = section->coupled;
1306 EXPECT_EQ(0, strcmp(m_name->name, "MIC-L"));
1307 m_name = m_name->next;
1308 EXPECT_EQ(0, strcmp(m_name->name, "MIC-R"));
1309
1310 // HDMI
1311 section = section->next;
1312 EXPECT_EQ(0, strcmp(section->name, "HDMI"));
1313 EXPECT_EQ(2, section->dev_idx);
1314 EXPECT_EQ(CRAS_STREAM_OUTPUT, section->dir);
1315 EXPECT_EQ(NULL, section->jack_name);
1316 EXPECT_EQ(NULL, section->jack_type);
1317 EXPECT_EQ(-1, section->jack_switch);
1318 ASSERT_NE((const char *)NULL, section->mixer_name);
1319 EXPECT_EQ(0, strcmp(section->mixer_name, "HDMI"));
1320
1321 EXPECT_EQ(NULL, section->next);
1322 ucm_section_free_list(sections);
1323 }
1324
TEST(AlsaUcm,GetSectionsMissingPCM)1325 TEST(AlsaUcm, GetSectionsMissingPCM) {
1326 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
1327 struct ucm_section* sections;
1328 int i = 0;
1329 const char *devices[] = { "Headphone", "The headphones jack." };
1330 const char* ids[] = {
1331 "=JackName/Headphone/HiFi",
1332 "=CoupledMixers/Headphone/HiFi",
1333 NULL
1334 };
1335 const char* values[] = {
1336 "my-sound-card Headset Jack",
1337 "HP-L,HP-R",
1338 };
1339
1340 ResetStubData();
1341
1342 fake_list["_devices/HiFi"] = devices;
1343 fake_list_size["_devices/HiFi"] = ARRAY_SIZE(devices);
1344
1345 while (ids[i]) {
1346 snd_use_case_get_value[ids[i]] = values[i];
1347 i++;
1348 }
1349
1350 sections = ucm_get_sections(mgr);
1351 EXPECT_EQ(NULL, sections);
1352 }
1353
TEST(AlsaUcm,GetSectionsBadPCM)1354 TEST(AlsaUcm, GetSectionsBadPCM) {
1355 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
1356 struct ucm_section* sections;
1357 int i = 0;
1358 const char *devices[] = { "Headphone", "The headphones jack." };
1359 const char* ids[] = {
1360 "=PlaybackPCM/Headphone/HiFi",
1361 "=JackName/Headphone/HiFi",
1362 "=CoupledMixers/Headphone/HiFi",
1363 NULL
1364 };
1365 const char* values[] = {
1366 "hw:my-sound-card:0",
1367 "my-sound-card Headset Jack",
1368 "HP-L,HP-R",
1369 };
1370
1371 ResetStubData();
1372
1373 fake_list["_devices/HiFi"] = devices;
1374 fake_list_size["_devices/HiFi"] = ARRAY_SIZE(devices);
1375
1376 while (ids[i]) {
1377 snd_use_case_get_value[ids[i]] = values[i];
1378 i++;
1379 }
1380
1381 sections = ucm_get_sections(mgr);
1382 EXPECT_EQ(NULL, sections);
1383 }
1384
TEST(AlsaUcm,CheckUseCaseVerbs)1385 TEST(AlsaUcm, CheckUseCaseVerbs) {
1386 struct cras_use_case_mgr *mgr = &cras_ucm_mgr;
1387
1388 /* Verifies the mapping between stream types and verbs are correct. */
1389 mgr->use_case = CRAS_STREAM_TYPE_DEFAULT;
1390 EXPECT_EQ(0, strcmp("HiFi", uc_verb(mgr)));
1391 mgr->use_case = CRAS_STREAM_TYPE_MULTIMEDIA;
1392 EXPECT_EQ(0, strcmp("Multimedia", uc_verb(mgr)));
1393 mgr->use_case = CRAS_STREAM_TYPE_VOICE_COMMUNICATION;
1394 EXPECT_EQ(0, strcmp("Voice Call", uc_verb(mgr)));
1395 mgr->use_case = CRAS_STREAM_TYPE_SPEECH_RECOGNITION;
1396 EXPECT_EQ(0, strcmp("Speech", uc_verb(mgr)));
1397 mgr->use_case = CRAS_STREAM_TYPE_PRO_AUDIO;
1398 EXPECT_EQ(0, strcmp("Pro Audio", uc_verb(mgr)));
1399 }
1400
TEST(AlsaUcm,GetAvailUseCases)1401 TEST(AlsaUcm, GetAvailUseCases) {
1402 struct cras_use_case_mgr *mgr;
1403 const char *verbs[] = { "HiFi", "Comment for Verb1",
1404 "Voice Call", "Comment for Verb2",
1405 "Speech", "Comment for Verb3" };
1406
1407 ResetStubData();
1408
1409 fake_list["_verbs"] = verbs;
1410 fake_list_size["_verbs"] = 6;
1411
1412 mgr = ucm_create("foo");
1413 EXPECT_EQ(0x0D, mgr->avail_use_cases);
1414 ucm_destroy(mgr);
1415 }
1416
TEST(AlsaUcm,SetUseCase)1417 TEST(AlsaUcm, SetUseCase) {
1418 struct cras_use_case_mgr *mgr;
1419 const char *verbs[] = { "HiFi", "Comment for Verb1",
1420 "Voice Call", "Comment for Verb2",
1421 "Speech", "Comment for Verb3" };
1422 int rc;
1423
1424 ResetStubData();
1425
1426 fake_list["_verbs"] = verbs;
1427 fake_list_size["_verbs"] = 6;
1428
1429 mgr = ucm_create("foo");
1430 EXPECT_EQ(snd_use_case_set_param[0],
1431 std::make_pair(std::string("_verb"), std::string("HiFi")));
1432
1433 rc = ucm_set_use_case(mgr, CRAS_STREAM_TYPE_VOICE_COMMUNICATION);
1434 EXPECT_EQ(0, rc);
1435 EXPECT_EQ(mgr->use_case, CRAS_STREAM_TYPE_VOICE_COMMUNICATION);
1436 EXPECT_EQ(snd_use_case_set_param[1],
1437 std::make_pair(std::string("_verb"), std::string("Voice Call")));
1438
1439 /* Request unavailable use case will fail. */
1440 rc = ucm_set_use_case(mgr, CRAS_STREAM_TYPE_PRO_AUDIO);
1441 EXPECT_EQ(-1, rc);
1442 /* cras_use_case_mgr's use case should not be changed. */
1443 EXPECT_EQ(mgr->use_case, CRAS_STREAM_TYPE_VOICE_COMMUNICATION);
1444 /* And snd_use_case_set not being called. */
1445 EXPECT_EQ(2, snd_use_case_set_param.size());
1446
1447 ucm_destroy(mgr);
1448 }
1449
1450 /* Stubs */
1451
1452 extern "C" {
1453
snd_use_case_mgr_open(snd_use_case_mgr_t ** uc_mgr,const char * card_name)1454 int snd_use_case_mgr_open(snd_use_case_mgr_t** uc_mgr, const char* card_name) {
1455 snd_use_case_mgr_open_called++;
1456 *uc_mgr = snd_use_case_mgr_open_mgr_ptr;
1457 return snd_use_case_mgr_open_return;
1458 }
1459
snd_use_case_mgr_close(snd_use_case_mgr_t * uc_mgr)1460 int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr) {
1461 snd_use_case_mgr_close_called++;
1462 return 0;
1463 }
1464
snd_use_case_get(snd_use_case_mgr_t * uc_mgr,const char * identifier,const char ** value)1465 int snd_use_case_get(snd_use_case_mgr_t* uc_mgr,
1466 const char *identifier,
1467 const char **value) {
1468 snd_use_case_get_called++;
1469 snd_use_case_get_id.push_back(std::string(identifier));
1470 if (snd_use_case_get_value.find(identifier) == snd_use_case_get_value.end()) {
1471 *value = NULL;
1472 return -1;
1473 }
1474 *value = strdup(snd_use_case_get_value[identifier].c_str());
1475 return 0;
1476 }
1477
snd_use_case_set(snd_use_case_mgr_t * uc_mgr,const char * identifier,const char * value)1478 int snd_use_case_set(snd_use_case_mgr_t* uc_mgr,
1479 const char *identifier,
1480 const char *value) {
1481 snd_use_case_set_called++;
1482 snd_use_case_set_param.push_back(
1483 std::make_pair(std::string(identifier), std::string(value)));
1484 return snd_use_case_set_return;
1485 }
1486
snd_use_case_get_list(snd_use_case_mgr_t * uc_mgr,const char * identifier,const char ** list[])1487 int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
1488 const char *identifier,
1489 const char **list[]) {
1490 *list = fake_list[identifier];
1491 return fake_list_size[identifier];
1492 }
1493
snd_use_case_free_list(const char * list[],int items)1494 int snd_use_case_free_list(const char *list[], int items) {
1495 snd_use_case_free_list_called++;
1496 return 0;
1497 }
1498
1499 } /* extern "C" */
1500
1501 } // namespace
1502
main(int argc,char ** argv)1503 int main(int argc, char** argv) {
1504 ::testing::InitGoogleTest(&argc, argv);
1505 openlog(NULL, LOG_PERROR, LOG_USER);
1506 return RUN_ALL_TESTS();
1507 }
1508