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