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