audio-hal: Remove unused code
[platform/adaptation/samsung_exynos/audio-hal-max98090.git] / tizen-audio-ucm.c
1 /*
2  * audio-hal
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #ifdef ALSA_UCM_DEBUG_TIME
28 #include <sys/time.h>
29 #include <time.h>
30 #endif
31
32 #include "tizen-audio-internal.h"
33
34 #ifdef ALSA_UCM_DEBUG_TIME
35 #define SND_USE_CASE_SET __set_use_case_with_time
36 #else
37 #define SND_USE_CASE_SET snd_use_case_set
38 #endif
39
40 audio_return_t _audio_ucm_init (audio_mgr_t *am)
41 {
42     snd_use_case_mgr_open(&am->ucm.uc_mgr, ALSA_DEFAULT_CARD);
43
44     if (!am->ucm.uc_mgr) {
45         AUDIO_LOG_ERROR("uc_mgr open failed");
46         return AUDIO_ERR_RESOURCE;
47     }
48     return AUDIO_RET_OK;
49 }
50
51 audio_return_t _audio_ucm_deinit (audio_mgr_t *am)
52 {
53     if (am->ucm.uc_mgr != NULL) {
54         snd_use_case_mgr_close(am->ucm.uc_mgr);
55         am->ucm.uc_mgr = NULL;
56     }
57
58     return AUDIO_RET_OK;
59 }
60
61 void _audio_ucm_get_device_name (audio_mgr_t *am, const char *use_case, audio_direction_t direction, const char **value)
62 {
63     char identifier[70] = {0};
64
65     if (direction == AUDIO_DIRECTION_IN) {
66         sprintf(identifier, "CapturePCM//%s", use_case);
67     } else {
68         sprintf(identifier, "PlaybackPCM//%s", use_case);
69     }
70     snd_use_case_get(am->ucm.uc_mgr, identifier, value);
71 }
72
73 static inline void __add_ucm_device_info (audio_mgr_t *am, const char *use_case, audio_direction_t direction, audio_device_info_t *device_info_list, int *device_info_count)
74 {
75     audio_device_info_t *device_info;
76     const char *device_name = NULL;
77     char *needle = NULL;
78
79     _audio_ucm_get_device_name(am, use_case, direction, &device_name);
80     if (device_name) {
81         device_info = &device_info_list[(*device_info_count)++];
82
83         memset(device_info, 0x00, sizeof(audio_device_info_t));
84         device_info->api = AUDIO_DEVICE_API_ALSA;
85         device_info->direction = direction;
86         needle = strstr(&device_name[3], ",");
87         if (needle) {
88             device_info->alsa.device_idx = *(needle+1) - '0';
89             device_info->alsa.card_name = strndup(&device_name[3], needle - (device_name+3));
90             device_info->alsa.card_idx = snd_card_get_index(device_info->alsa.card_name);
91             AUDIO_LOG_DEBUG("Card name: %s", device_info->alsa.card_name);
92         }
93
94         free((void *)device_name);
95     }
96 }
97
98 int _audio_ucm_fill_device_info_list (audio_mgr_t *am, audio_device_info_t *device_info_list, const char *verb)
99 {
100     int device_info_count = 0;
101     const char *curr_verb = NULL;
102
103     if (!verb) {
104         snd_use_case_get(am->ucm.uc_mgr, "_verb", &curr_verb);
105         verb = curr_verb;
106     }
107
108     if (verb) {
109         __add_ucm_device_info(am, verb, AUDIO_DIRECTION_IN, device_info_list, &device_info_count);
110         __add_ucm_device_info(am, verb, AUDIO_DIRECTION_OUT, device_info_list, &device_info_count);
111
112         if (curr_verb)
113             free((void *)curr_verb);
114     }
115
116     return device_info_count;
117 }
118
119 static void __dump_use_case(const char *verb, const char *devices[], int dev_count, const char *modifiers[], int mod_count, char *dump)
120 {
121     int i, len;
122
123     len = sprintf(dump, "Verb [ %s ] Devices [ ", verb ? verb : AUDIO_USE_CASE_VERB_INACTIVE);
124     if (len > 0)
125         dump += len;
126
127     for (i = 0; i < dev_count; i++) {
128         if (i != dev_count - 1) {
129             len = sprintf(dump, "%s, ", devices[i]);
130         } else {
131             len = sprintf(dump, "%s", devices[i]);
132         }
133         if (len > 0)
134             dump += len;
135     }
136
137     len = sprintf(dump, " ] Modifier [ ");
138     if (len > 0)
139         dump += len;
140
141     for (i = 0; i < mod_count; i++) {
142         if (i != mod_count - 1) {
143             len = sprintf(dump, "%s, ", modifiers[i]);
144         } else {
145             len = sprintf(dump, "%s", modifiers[i]);
146         }
147         if (len > 0)
148             dump += len;
149     }
150
151     len = sprintf(dump, " ]");
152     if (len > 0)
153         dump += len;
154
155     *dump = '\0';
156 }
157
158 #ifdef ALSA_UCM_DEBUG_TIME
159 static inline int __set_use_case_with_time(snd_use_case_mgr_t *uc_mgr, const char *identifier, const char *value)
160 {
161     int ret = 0;
162     struct timeval t_start, t_stop;
163     unsigned long long t_diff = 0;
164
165     gettimeofday(&t_start, NULL);
166     ret = snd_use_case_set(uc_mgr, identifier, value);
167     gettimeofday(&t_stop, NULL);
168     if (t_start.tv_sec < t_stop.tv_sec)
169         t_diff = (t_stop.tv_sec - t_start.tv_sec) * 1000000;
170     t_diff += (t_stop.tv_usec - t_start.tv_usec);
171     AUDIO_LOG_DEBUG("identifier %s value %s takes %lluusec", identifier, value, t_diff);
172
173     return ret;
174 }
175 #endif
176
177 /* UCM sequence
178     1) If verb is null or verb is not changed
179     1-1) If device is changed
180          (If there is request for same device, it will be ignored)
181          -> Set "Inactive" verb, disable modifiers & devices, set current verb again, enable devices & modifiers
182             (playback/capture device will be enabled again if there is no request for playback/capture device)
183     1-2) If device is not changed
184      1-2-1) If modifier is changed
185             (If there is request for same modifier, it will be ignored)
186             -> Disable modifiers, enable modifiers
187    2) If verb is changed
188       -> Reset, set new verb, enable devices & modifiers
189  */
190 audio_return_t _audio_ucm_set_use_case (audio_mgr_t *am, const char *verb, const char *devices[], const char *modifiers[])
191 {
192     audio_return_t audio_ret = AUDIO_RET_OK;
193     int is_verb_changed = 0, is_dev_changed = 0, is_mod_changed = 0;
194     const char *old_verb = NULL, **old_dev_list = NULL, **old_mod_list = NULL;
195     int old_dev_count = 0, dev_count = 0;
196     int old_mod_count = 0, mod_count = 0;
197     const char **dis_dev_list = NULL, **ena_dev_list = NULL;
198     const char **dis_mod_list = NULL, **ena_mod_list = NULL;
199     int dis_dev_count = 0, ena_dev_count = 0;
200     int dis_mod_count = 0, ena_mod_count = 0;
201     int i = 0, j = 0;
202     char dump_str[512];
203
204     if (!am->ucm.uc_mgr || !verb)
205         return AUDIO_ERR_PARAMETER;
206
207     snd_use_case_get(am->ucm.uc_mgr, "_verb", &old_verb);
208     old_dev_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enadevs", &old_dev_list);
209     old_mod_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enamods", &old_mod_list);
210     __dump_use_case(old_verb, old_dev_list, old_dev_count, old_mod_list, old_mod_count, &dump_str[0]);
211     AUDIO_LOG_INFO(">>> UCM current %s", dump_str);
212
213     if (devices) {
214         for (dev_count = 0; devices[dev_count]; dev_count++);
215     }
216     if (modifiers) {
217         for (mod_count = 0; modifiers[mod_count]; mod_count++);
218     }
219
220     __dump_use_case(verb, devices, dev_count, modifiers, mod_count, &dump_str[0]);
221     AUDIO_LOG_INFO("> UCM requested %s", dump_str);
222
223     if (old_verb && streq(verb, old_verb)) {
224         AUDIO_LOG_DEBUG("current verb and new verb is same. No need to change verb, disable devices explicitely");
225
226         if (old_dev_count > 0) {
227             dis_dev_list = (const char **)malloc(sizeof(const char *) * old_dev_count);
228             for (i = 0; i < old_dev_count; i++) {
229                 dis_dev_list[i] = NULL;
230             }
231         }
232         if (dev_count > 0) {
233             ena_dev_list = (const char **)malloc(sizeof(const char *) * dev_count);
234             for (i = 0; i < dev_count; i++) {
235                 ena_dev_list[i] = NULL;
236             }
237         }
238         if (old_mod_count > 0) {
239             dis_mod_list = (const char **)malloc(sizeof(const char *) * old_mod_count);
240             for (i = 0; i < old_mod_count; i++) {
241                 dis_mod_list[i] = NULL;
242             }
243         }
244         if (mod_count > 0) {
245             ena_mod_list = (const char **)malloc(sizeof(const char *) * mod_count);
246             for (i = 0; i < mod_count; i++) {
247                 ena_mod_list[i] = NULL;
248             }
249         }
250
251         /* update disable modifiers list which are not present in new modifier list */
252         for (i = 0; i < old_mod_count; i++) {
253             int need_disable_mod = 1;
254
255             for (j = 0; j < mod_count; j++) {
256                 if (streq(old_mod_list[i], modifiers[j])) {
257                     need_disable_mod = 0;
258                     break;
259                 }
260             }
261             if (need_disable_mod) {
262                 if (is_mod_changed == 0)
263                     is_mod_changed = 1;
264                 dis_mod_list[dis_mod_count++] = old_mod_list[i];
265             }
266         }
267
268         /* update disable devices list which are not present in new device list */
269         for (i = 0; i < old_dev_count; i++) {
270             int need_disable_dev = 1;
271
272             for (j = 0; j < dev_count; j++) {
273                 if (streq(old_dev_list[i], devices[j])) {
274                     need_disable_dev = 0;
275                     break;
276                 }
277             }
278             if (need_disable_dev) {
279                 if (is_dev_changed == 0)
280                     is_dev_changed = 1;
281                 dis_dev_list[dis_dev_count++] = old_dev_list[i];
282             }
283         }
284
285         /* update enable devices list which are not present in old device list */
286         for (i = 0; i < dev_count; i++) {
287             int need_enable_dev = 1;
288
289             for (j = 0; j < old_dev_count; j++) {
290                 if (streq(devices[i], old_dev_list[j])) {
291                     need_enable_dev = 0;
292                     break;
293                 }
294             }
295             if (need_enable_dev) {
296                 if (is_dev_changed == 0)
297                     is_dev_changed = 1;
298                 ena_dev_list[ena_dev_count++] = devices[i];
299             }
300         }
301
302         /* update enable modifiers list which are not present in old modifier list */
303         for (i = 0; i < mod_count; i++) {
304             int need_enable_mod = 1;
305
306             for (j = 0; j < old_mod_count; j++) {
307                 if (streq(modifiers[i], old_mod_list[j])) {
308                     need_enable_mod = 0;
309                     break;
310                 }
311             }
312             if (need_enable_mod) {
313                 if (is_mod_changed == 0)
314                     is_mod_changed = 1;
315                 ena_mod_list[ena_mod_count++] = modifiers[i];
316             }
317         }
318
319         /* disable modifiers */
320         for (i = 0; i < dis_mod_count; i++) {
321             AUDIO_LOG_INFO("Disable modifier : %s", dis_mod_list[i]);
322             if (snd_use_case_set(am->ucm.uc_mgr, "_dismod", dis_mod_list[i]) < 0)
323                 AUDIO_LOG_ERROR("disable %s modifier failed", dis_mod_list[i]);
324         }
325
326         /* disable devices */
327         for (i = 0; i < dis_dev_count; i++) {
328             AUDIO_LOG_INFO("Disable device : %s", dis_dev_list[i]);
329             if (snd_use_case_set(am->ucm.uc_mgr, "_disdev", dis_dev_list[i]) < 0)
330                 AUDIO_LOG_ERROR("disable %s device failed", dis_dev_list[i]);
331         }
332
333         /* enable devices */
334         for (i = 0; i < ena_dev_count; i++) {
335             AUDIO_LOG_INFO("Enable device : %s", ena_dev_list[i]);
336             if (snd_use_case_set(am->ucm.uc_mgr, "_enadev", ena_dev_list[i]) < 0)
337                 AUDIO_LOG_ERROR("enable %s device failed", ena_dev_list[i]);
338         }
339
340         /* enable modifiers */
341         for (i = 0; i < ena_mod_count; i++) {
342             AUDIO_LOG_INFO("Enable modifier : %s", ena_mod_list[i]);
343             if (snd_use_case_set(am->ucm.uc_mgr, "_enamod", ena_mod_list[i]) < 0)
344                 AUDIO_LOG_ERROR("enable %s modifier failed", ena_mod_list[i]);
345         }
346     } else {
347         is_verb_changed = 1;
348
349         AUDIO_LOG_DEBUG("Setting new verb: %s", verb);
350         /* set new verb */
351         if (snd_use_case_set(am->ucm.uc_mgr, "_verb", verb) < 0) {
352             AUDIO_LOG_ERROR("Setting verb %s failed", verb);
353             audio_ret = AUDIO_ERR_UNDEFINED;
354             goto exit;
355         }
356         /* enable devices */
357         for (i = 0; i < dev_count; i++) {
358             AUDIO_LOG_DEBUG("Enable device : %s", devices[i]);
359             if(snd_use_case_set(am->ucm.uc_mgr, "_enadev", devices[i]) < 0)
360                 AUDIO_LOG_ERROR("Enable %s device failed", devices[i]);
361         }
362         /* enable modifiers */
363         for (i = 0; i < mod_count; i++) {
364             AUDIO_LOG_DEBUG("Enable modifier : %s", modifiers[i]);
365             if(snd_use_case_set(am->ucm.uc_mgr, "_enamod", modifiers[i]) < 0)
366                 AUDIO_LOG_ERROR("Enable %s modifier failed", modifiers[i]);
367         }
368     }
369
370 exit:
371     if (old_verb)
372         free((void *)old_verb);
373     if (old_dev_list)
374         snd_use_case_free_list(old_dev_list, old_dev_count);
375     if (old_mod_list)
376         snd_use_case_free_list(old_mod_list, old_mod_count);
377     if (dis_dev_list)
378         free((void *)dis_dev_list);
379     if (ena_dev_list)
380         free((void *)ena_dev_list);
381     if (dis_mod_list)
382         free((void *)dis_mod_list);
383     if (ena_mod_list)
384         free((void *)ena_mod_list);
385
386     if (is_verb_changed == 1 || is_dev_changed == 1 || is_mod_changed == 1) {
387         const char *new_verb = NULL, **new_dev_list = NULL, **new_mod_list = NULL;
388         int new_dev_count = 0, new_mod_count = 0;
389
390         snd_use_case_get(am->ucm.uc_mgr, "_verb", &new_verb);
391         new_dev_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enadevs", &new_dev_list);
392         new_mod_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enamods", &new_mod_list);
393         __dump_use_case(new_verb, new_dev_list, new_dev_count, new_mod_list, new_mod_count, &dump_str[0]);
394         AUDIO_LOG_INFO("<<< UCM changed %s", dump_str);
395
396         if (new_verb)
397             free((void *)new_verb);
398         if (new_dev_list)
399             snd_use_case_free_list(new_dev_list, new_dev_count);
400         if (new_mod_list)
401             snd_use_case_free_list(new_mod_list, new_mod_count);
402     }
403
404     return audio_ret;
405 }
406
407 audio_return_t _audio_ucm_set_devices (audio_mgr_t *am, const char *verb, const char *devices[])
408 {
409     audio_return_t audio_ret = AUDIO_RET_OK;
410     int is_verb_changed = 0, is_dev_changed = 0;
411     const char *old_verb = NULL, **old_dev_list = NULL;
412     int old_dev_count = 0, dev_count = 0;
413     const char **dis_dev_list = NULL, **ena_dev_list = NULL;
414     int dis_dev_count = 0, ena_dev_count = 0;
415     int i = 0, j = 0;
416     char dump_str[512];
417
418     if (!am->ucm.uc_mgr || !verb)
419         return AUDIO_ERR_PARAMETER;
420
421     snd_use_case_get(am->ucm.uc_mgr, "_verb", &old_verb);
422     old_dev_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enadevs", &old_dev_list);
423     __dump_use_case(old_verb, old_dev_list, old_dev_count, NULL, 0, &dump_str[0]);
424     AUDIO_LOG_INFO(">>> UCM current %s", dump_str);
425
426     if (devices) {
427         for (dev_count = 0; devices[dev_count]; dev_count++);
428     }
429
430     __dump_use_case(verb, devices, dev_count, NULL, 0, &dump_str[0]);
431     AUDIO_LOG_INFO("> UCM requested %s", dump_str);
432
433     if (old_verb && streq(verb, old_verb)) {
434         AUDIO_LOG_DEBUG("current verb and new verb is same. No need to change verb, disable devices explicitely");
435
436         if (old_dev_count > 0) {
437             dis_dev_list = (const char **)malloc(sizeof(const char *) * old_dev_count);
438             for (i = 0; i < old_dev_count; i++) {
439                 dis_dev_list[i] = NULL;
440             }
441         }
442         if (dev_count > 0) {
443             ena_dev_list = (const char **)malloc(sizeof(const char *) * dev_count);
444             for (i = 0; i < dev_count; i++) {
445                 ena_dev_list[i] = NULL;
446             }
447         }
448
449         /* update disable devices list which are not present in new device list */
450         for (i = 0; i < old_dev_count; i++) {
451             int need_disable_dev = 1;
452
453             for (j = 0; j < dev_count; j++) {
454                 if (streq(old_dev_list[i], devices[j])) {
455                     need_disable_dev = 0;
456                     break;
457                 }
458             }
459             if (need_disable_dev) {
460                 if (is_dev_changed == 0)
461                     is_dev_changed = 1;
462                 dis_dev_list[dis_dev_count++] = old_dev_list[i];
463             }
464         }
465
466         /* update enable devices list which are not present in old device list */
467         for (i = 0; i < dev_count; i++) {
468             int need_enable_dev = 1;
469
470             for (j = 0; j < old_dev_count; j++) {
471                 if (streq(devices[i], old_dev_list[j])) {
472                     need_enable_dev = 0;
473                     break;
474                 }
475             }
476             if (need_enable_dev) {
477                 if (is_dev_changed == 0)
478                     is_dev_changed = 1;
479                 ena_dev_list[ena_dev_count++] = devices[i];
480             }
481         }
482
483         /* disable devices */
484         for (i = 0; i < dis_dev_count; i++) {
485             AUDIO_LOG_INFO("Disable device : %s", dis_dev_list[i]);
486             if (snd_use_case_set(am->ucm.uc_mgr, "_disdev", dis_dev_list[i]) < 0)
487                 AUDIO_LOG_ERROR("disable %s device failed", dis_dev_list[i]);
488         }
489
490         /* enable devices */
491         for (i = 0; i < ena_dev_count; i++) {
492             AUDIO_LOG_INFO("Enable device : %s", ena_dev_list[i]);
493             if (snd_use_case_set(am->ucm.uc_mgr, "_enadev", ena_dev_list[i]) < 0)
494                 AUDIO_LOG_ERROR("enable %s device failed", ena_dev_list[i]);
495         }
496
497     } else {
498         is_verb_changed = 1;
499
500         AUDIO_LOG_DEBUG("Setting new verb: %s", verb);
501         /* set new verb */
502         if (snd_use_case_set(am->ucm.uc_mgr, "_verb", verb) < 0) {
503             AUDIO_LOG_ERROR("Setting verb %s failed", verb);
504             audio_ret = AUDIO_ERR_UNDEFINED;
505             goto exit;
506         }
507         /* enable devices */
508         for (i = 0; i < dev_count; i++) {
509             AUDIO_LOG_DEBUG("Enable device : %s", devices[i]);
510             if(snd_use_case_set(am->ucm.uc_mgr, "_enadev", devices[i]) < 0)
511                 AUDIO_LOG_ERROR("Enable %s device failed", devices[i]);
512         }
513     }
514
515 exit:
516     if (old_verb)
517         free((void *)old_verb);
518     if (old_dev_list)
519         snd_use_case_free_list(old_dev_list, old_dev_count);
520     if (dis_dev_list)
521         free((void *)dis_dev_list);
522     if (ena_dev_list)
523         free((void *)ena_dev_list);
524
525     if (is_verb_changed == 1 || is_dev_changed == 1) {
526         const char *new_verb = NULL, **new_dev_list = NULL;
527         int new_dev_count = 0;
528
529         snd_use_case_get(am->ucm.uc_mgr, "_verb", &new_verb);
530         new_dev_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enadevs", &new_dev_list);
531         __dump_use_case(new_verb, new_dev_list, new_dev_count, NULL, 0, &dump_str[0]);
532         AUDIO_LOG_INFO("<<< UCM changed %s", dump_str);
533
534         if (new_verb)
535             free((void *)new_verb);
536         if (new_dev_list)
537             snd_use_case_free_list(new_dev_list, new_dev_count);
538     }
539
540     return audio_ret;
541
542 }
543
544 audio_return_t _audio_ucm_set_modifiers (audio_mgr_t *am, const char *verb, const char *modifiers[])
545 {
546     audio_return_t audio_ret = AUDIO_RET_OK;
547     int is_verb_changed = 0, is_mod_changed = 0;
548     const char *old_verb = NULL, **old_mod_list = NULL;
549     int old_mod_count = 0, mod_count = 0;
550     const char **dis_mod_list = NULL, **ena_mod_list = NULL;
551     int dis_mod_count = 0, ena_mod_count = 0;
552     int i = 0, j = 0;
553     char dump_str[512];
554
555     if (!am->ucm.uc_mgr || !verb)
556         return AUDIO_ERR_PARAMETER;
557
558     snd_use_case_get(am->ucm.uc_mgr, "_verb", &old_verb);
559     old_mod_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enamods", &old_mod_list);
560     __dump_use_case(old_verb, NULL, 0, old_mod_list, old_mod_count, &dump_str[0]);
561     AUDIO_LOG_INFO(">>> UCM current %s", dump_str);
562
563     if (modifiers) {
564         for (mod_count = 0; modifiers[mod_count]; mod_count++);
565     }
566
567     __dump_use_case(verb, NULL, 0, modifiers, mod_count, &dump_str[0]);
568     AUDIO_LOG_INFO("> UCM requested %s", dump_str);
569
570     if (old_verb && streq(verb, old_verb)) {
571         AUDIO_LOG_DEBUG("current verb and new verb is same. No need to change verb, disable devices explicitely");
572
573         if (old_mod_count > 0) {
574             dis_mod_list = (const char **)malloc(sizeof(const char *) * old_mod_count);
575             for (i = 0; i < old_mod_count; i++) {
576                 dis_mod_list[i] = NULL;
577             }
578         }
579         if (mod_count > 0) {
580             ena_mod_list = (const char **)malloc(sizeof(const char *) * mod_count);
581             for (i = 0; i < mod_count; i++) {
582                 ena_mod_list[i] = NULL;
583             }
584         }
585
586         /* update disable modifiers list which are not present in new modifier list */
587         for (i = 0; i < old_mod_count; i++) {
588             int need_disable_mod = 1;
589
590             for (j = 0; j < mod_count; j++) {
591                 if (streq(old_mod_list[i], modifiers[j])) {
592                     need_disable_mod = 0;
593                     break;
594                 }
595             }
596             if (need_disable_mod) {
597                 if (is_mod_changed == 0)
598                     is_mod_changed = 1;
599                 dis_mod_list[dis_mod_count++] = old_mod_list[i];
600             }
601         }
602
603         /* update enable modifiers list which are not present in old modifier list */
604         for (i = 0; i < mod_count; i++) {
605             int need_enable_mod = 1;
606
607             for (j = 0; j < old_mod_count; j++) {
608                 if (streq(modifiers[i], old_mod_list[j])) {
609                     need_enable_mod = 0;
610                     break;
611                 }
612             }
613             if (need_enable_mod) {
614                 if (is_mod_changed == 0)
615                     is_mod_changed = 1;
616                 ena_mod_list[ena_mod_count++] = modifiers[i];
617             }
618         }
619
620         /* disable modifiers */
621         for (i = 0; i < dis_mod_count; i++) {
622             AUDIO_LOG_INFO("Disable modifier : %s", dis_mod_list[i]);
623             if (snd_use_case_set(am->ucm.uc_mgr, "_dismod", dis_mod_list[i]) < 0)
624                 AUDIO_LOG_ERROR("disable %s modifier failed", dis_mod_list[i]);
625         }
626
627         /* enable modifiers */
628         for (i = 0; i < ena_mod_count; i++) {
629             AUDIO_LOG_INFO("Enable modifier : %s", ena_mod_list[i]);
630             if (snd_use_case_set(am->ucm.uc_mgr, "_enamod", ena_mod_list[i]) < 0)
631                 AUDIO_LOG_ERROR("enable %s modifier failed", ena_mod_list[i]);
632         }
633     } else {
634         is_verb_changed = 1;
635
636         AUDIO_LOG_DEBUG("Setting new verb: %s", verb);
637         /* set new verb */
638         if (snd_use_case_set(am->ucm.uc_mgr, "_verb", verb) < 0) {
639             AUDIO_LOG_ERROR("Setting verb %s failed", verb);
640             audio_ret = AUDIO_ERR_UNDEFINED;
641             goto exit;
642         }
643         /* enable modifiers */
644         for (i = 0; i < mod_count; i++) {
645             AUDIO_LOG_DEBUG("Enable modifier : %s", modifiers[i]);
646             if(snd_use_case_set(am->ucm.uc_mgr, "_enamod", modifiers[i]) < 0)
647                 AUDIO_LOG_ERROR("Enable %s modifier failed", modifiers[i]);
648         }
649     }
650
651 exit:
652     if (old_verb)
653         free((void *)old_verb);
654     if (old_mod_list)
655         snd_use_case_free_list(old_mod_list, old_mod_count);
656     if (dis_mod_list)
657         free((void *)dis_mod_list);
658     if (ena_mod_list)
659         free((void *)ena_mod_list);
660
661     if (is_verb_changed == 1 || is_mod_changed == 1) {
662         const char *new_verb = NULL, **new_mod_list = NULL;
663         int new_mod_count = 0;
664
665         snd_use_case_get(am->ucm.uc_mgr, "_verb", &new_verb);
666         new_mod_count = snd_use_case_get_list(am->ucm.uc_mgr, "_enamods", &new_mod_list);
667         __dump_use_case(new_verb, NULL, 0, new_mod_list, new_mod_count, &dump_str[0]);
668         AUDIO_LOG_INFO("<<< UCM changed %s", dump_str);
669
670         if (new_verb)
671             free((void *)new_verb);
672         if (new_mod_list)
673             snd_use_case_free_list(new_mod_list, new_mod_count);
674     }
675
676     return audio_ret;
677 }
678
679 audio_return_t _audio_ucm_get_verb (audio_mgr_t *am, const char **value)
680 {
681     audio_return_t ret = AUDIO_RET_OK;
682
683     AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
684     AUDIO_RETURN_VAL_IF_FAIL(value, AUDIO_ERR_PARAMETER);
685
686     if ((ret = snd_use_case_get(am->ucm.uc_mgr, "_verb", value)) < 0) {
687         AUDIO_LOG_ERROR("Getting current verb failed: Reason %d", ret);
688         ret = AUDIO_ERR_UNDEFINED;
689     }
690
691     return ret;
692 }
693
694
695 audio_return_t _audio_ucm_reset_use_case (audio_mgr_t *am)
696 {
697     audio_return_t ret = AUDIO_RET_OK;
698
699     AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
700
701     AUDIO_LOG_INFO(">>> UCM reset Verb [ %s ]", AUDIO_USE_CASE_VERB_INACTIVE);
702
703     if ((ret = snd_use_case_set(am->ucm.uc_mgr, "_verb", AUDIO_USE_CASE_VERB_INACTIVE)) < 0) {
704         AUDIO_LOG_ERROR("Reset use case failed: Reason %d", ret);
705         ret = AUDIO_ERR_UNDEFINED;
706     }
707
708     return ret;
709 }
710