• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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