Remove unnecessary log in ducking state changed callback
[platform/core/api/sound-manager.git] / src / sound_manager.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "sound_manager.h"
18 #include "sound_manager_private.h"
19
20 static int ducking_arr_count;
21 static unsigned int ducking_cb_subs_id;
22 static pthread_mutex_t ducking_mutex;
23 static sound_stream_ducking_s *ducking_arr[SOUND_DUCKING_ARR_MAX];
24
25 _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
26
27 static void _ducking_state_changed_cb(int pa_index, bool is_ducked, void *user_data)
28 {
29         int i = 0;
30
31         SM_ENTER_CRITICAL_SECTION(&ducking_mutex);
32
33         for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++) {
34                 if (ducking_arr[i] && ducking_arr[i]->pa_info.index == pa_index) {
35                         LOGI("ducking state changed [i:%d,ducked:%u]", pa_index, is_ducked);
36                         if (ducking_arr[i]->user_cb)
37                                 ducking_arr[i]->user_cb((sound_stream_ducking_h)ducking_arr[i], is_ducked, ducking_arr[i]->user_data);
38                         else
39                                 LOGW("no user callback for pa_index %d", pa_index);
40                         break;
41                 }
42         }
43
44         SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
45
46         return;
47 }
48
49 int sound_manager_get_max_volume(sound_type_e type, int *max)
50 {
51         const char *volume_type = NULL;
52         unsigned int max_level = 0;
53         int ret = SOUND_MANAGER_ERROR_NONE;
54
55         SM_ARG_CHECK(max);
56         SM_ARG_CHECK(type < SOUND_TYPE_NUM);
57
58         LOGI("type[%d]", type);
59
60         ret = _convert_sound_type(type, &volume_type);
61         if (ret == SOUND_MANAGER_ERROR_NONE) {
62                 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
63                 if (ret == SOUND_MANAGER_ERROR_NONE) {
64                         *max = (int)max_level -1;       /* actual volume step can be max step - 1 */
65                         LOGI("volume_type[%s] max_volume[%d]", volume_type, *max);
66                 }
67         }
68
69         LOGI("ret[0x%x]", ret);
70
71         return ret;
72 }
73
74 int sound_manager_set_volume(sound_type_e type, int volume)
75 {
76         int ret = MM_ERROR_NONE;
77
78         SM_ARG_CHECK(type < SOUND_TYPE_NUM);
79         SM_ARG_CHECK(volume >= 0);
80
81         LOGI("type[%d] volume[%d]", type, volume);
82
83         ret = mm_sound_volume_set_value(type, volume);
84
85         return _convert_sound_manager_error_code(__func__, ret);
86 }
87
88 int sound_manager_get_volume(sound_type_e type, int *volume)
89 {
90         int ret = MM_ERROR_NONE;
91         unsigned int uvolume;
92
93         SM_ARG_CHECK(type < SOUND_TYPE_NUM);
94         SM_ARG_CHECK(volume);
95
96         LOGI("type[%d]", type);
97
98         ret = mm_sound_volume_get_value(type, &uvolume);
99         if (ret == MM_ERROR_NONE) {
100                 *volume = uvolume;
101                 LOGI("volume[%d]", *volume);
102         }
103
104         return _convert_sound_manager_error_code(__func__, ret);
105 }
106
107 int sound_manager_get_current_sound_type(sound_type_e *type)
108 {
109         int ret = SOUND_MANAGER_ERROR_NONE;
110         char *volume_type = NULL;
111
112         SM_ARG_CHECK(type);
113
114         /* get the volume type of the current playing stream */
115         ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
116         if (ret == SOUND_MANAGER_ERROR_NONE) {
117                 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
118                 if (ret == SOUND_MANAGER_ERROR_NONE)
119                         LOGI("type[%d]", *type);
120         }
121
122         LOGI("ret[0x%x]", ret);
123
124         return ret;
125 }
126
127 int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id)
128 {
129         int ret = MM_ERROR_NONE;
130
131         SM_ARG_CHECK(callback);
132         SM_ARG_CHECK(id);
133
134         LOGI("callback[%p] user_data[%p]", callback, user_data);
135
136         ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, (unsigned int*)id);
137
138         LOGI("id[%d]", *id);
139
140         return _convert_sound_manager_error_code(__func__, ret);
141 }
142
143 int sound_manager_remove_volume_changed_cb(int id)
144 {
145         int ret = MM_ERROR_NONE;
146
147         SM_ARG_CHECK(id >= 0);
148
149         LOGI("id[%d]", id);
150
151         ret = mm_sound_remove_volume_changed_callback(id);
152
153         return _convert_sound_manager_error_code(__func__, ret);
154 }
155
156 int sound_manager_create_stream_information(sound_stream_type_e stream_type, sound_stream_focus_state_changed_cb callback, void *user_data, sound_stream_info_h *stream_info)
157 {
158         int ret = SOUND_MANAGER_ERROR_NONE;
159
160         SM_ARG_CHECK(stream_info);
161
162         LOGI("stream_type[%d] callback[%p] user_data[%p]", stream_type, callback, user_data);
163
164         sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
165         if (!stream_h) {
166                 ret = SOUND_MANAGER_ERROR_INTERNAL;
167                 goto LEAVE;
168         }
169
170         memset(stream_h, 0, sizeof(sound_stream_info_s));
171         ret = _convert_stream_type(stream_type, &stream_h->stream_type);
172         if (ret == SOUND_MANAGER_ERROR_NONE) {
173                 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
174                 if (ret == SOUND_MANAGER_ERROR_NONE) {
175                         *stream_info = (sound_stream_info_h)stream_h;
176                         LOGI("stream_info[%p, type:%s] pa_index[%u] focus_id[%d]",
177                                 stream_info, stream_h->stream_type, stream_h->pa_info.index, stream_h->focus_id);
178                 }
179         }
180
181 LEAVE:
182         if (ret != SOUND_MANAGER_ERROR_NONE)
183                 SM_SAFE_FREE(stream_h);
184
185         LOGI("ret[0x%x]", ret);
186
187         return ret;
188 }
189
190 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
191 {
192         int ret = SOUND_MANAGER_ERROR_NONE;
193         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
194
195         SM_ARG_CHECK(stream_h);
196
197         LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
198
199         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->vstream_mutex, SOUND_MANAGER_ERROR_INTERNAL);
200         if (stream_h->vstream) {
201                 LOGE("virtual stream is still alive");
202                 SM_LEAVE_CRITICAL_SECTION(&stream_h->vstream_mutex);
203                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
204         }
205         SM_LEAVE_CRITICAL_SECTION(&stream_h->vstream_mutex);
206
207         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
208         ret = _destroy_pa_connection_and_unregister_focus(stream_h);
209         SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
210         if (ret == SOUND_MANAGER_ERROR_NONE)
211                 SM_SAFE_FREE(stream_h);
212
213         LOGI("ret[0x%x]", ret);
214
215         return ret;
216 }
217
218 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
219 {
220         int ret = SOUND_MANAGER_ERROR_NONE;
221         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
222
223         SM_ARG_CHECK(stream_h);
224         SM_ARG_CHECK(sound_type);
225
226         LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
227
228         if (stream_h->stream_conf_info.volume_type == NULL) {
229                 ret = SOUND_MANAGER_ERROR_NO_DATA;
230                 LOGW("There's no sound type for this stream_info(%p)", stream_info);
231                 goto LEAVE;
232         }
233
234         ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
235         LOGI("sound type(%d)", *sound_type);
236
237 LEAVE:
238         LOGI("ret[0x%x]", ret);
239
240         return ret;
241 }
242
243 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
244 {
245         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
246
247         SM_ARG_CHECK(stream_h);
248         SM_ARG_CHECK(device);
249
250         LOGI("stream_info[%p, type:%s] device[%p]", stream_info, stream_h->stream_type, device);
251
252         return _add_device_for_stream_routing(stream_h, device);
253 }
254
255 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
256 {
257         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
258
259         SM_ARG_CHECK(stream_h);
260         SM_ARG_CHECK(device);
261
262         LOGI("stream_info[%p, type:%s] device[%p]", stream_info, stream_h->stream_type, device);
263
264         return _remove_device_for_stream_routing(stream_h, device);
265 }
266
267 int sound_manager_remove_all_devices_for_stream_routing(sound_stream_info_h stream_info)
268 {
269         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
270
271         SM_ARG_CHECK(stream_h);
272
273         LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
274
275         return _remove_all_devices_for_stream_routing(stream_h);
276 }
277
278 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
279 {
280         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
281
282         SM_ARG_CHECK(stream_h);
283
284         LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
285
286         return _apply_stream_routing(stream_h);
287 }
288
289 int sound_manager_set_stream_preferred_device(sound_stream_info_h stream_info, sound_device_io_direction_e io_direction, sound_device_h device)
290 {
291         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
292
293         SM_ARG_CHECK(stream_h);
294
295         LOGI("stream_info[%p, type:%s] io_direction[%d] device[%p]", stream_info, stream_h->stream_type, io_direction, device);
296
297         return _set_preferred_device(stream_h, io_direction, device);
298 }
299
300 int sound_manager_get_stream_preferred_device(sound_stream_info_h stream_info, int *in_device_id, int *out_device_id)
301 {
302         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
303
304         SM_ARG_CHECK(stream_h);
305         SM_ARG_CHECK(in_device_id || out_device_id);
306
307         LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
308
309         return _get_preferred_device(stream_h, in_device_id, out_device_id);
310 }
311
312 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
313 {
314         int ret = MM_ERROR_NONE;
315         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
316
317         SM_ARG_CHECK(stream_h);
318
319         LOGI("stream_info[%p, type:%s, focus_id:%d] enable[%d]", stream_info, stream_h->stream_type, stream_h->focus_id, enable);
320
321         ret = mm_sound_set_focus_reacquisition(stream_h->focus_id, enable);
322
323         return _convert_sound_manager_error_code(__func__, ret);
324 }
325
326 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
327 {
328         int ret = MM_ERROR_NONE;
329         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
330
331         SM_ARG_CHECK(stream_h);
332         SM_ARG_CHECK(enabled);
333
334         LOGI("stream_info[%p, type:%s, focus_id:%d]", stream_info, stream_h->stream_type, stream_h->focus_id);
335
336         ret = mm_sound_get_focus_reacquisition(stream_h->focus_id, enabled);
337
338         LOGI("enabled(%d)", *enabled);
339
340         return _convert_sound_manager_error_code(__func__, ret);
341 }
342
343 int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, int sound_behavior, const char *extra_info)
344 {
345         int ret = MM_ERROR_NONE;
346         bool is_focus_cb_thread = false;
347         bool is_focus_watch_cb_thread = false;
348         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
349
350         SM_ARG_CHECK(stream_h);
351
352         LOGI("stream_info[%p, type:%s, focus_id:%d] focus_mask[0x%x] sound_behavior[0x%x] extra_info[%s]",
353                 stream_info, stream_h->stream_type, stream_h->focus_id, focus_mask, sound_behavior, extra_info);
354
355         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
356                 return _convert_sound_manager_error_code(__func__, ret);
357
358         if (stream_h->is_focus_unavailable) {
359                 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
360                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
361         }
362
363         if (stream_h->user_cb == NULL) {
364                 LOGE("focus state changed callback should be set before acquiring focus");
365                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
366         }
367
368         if (!is_focus_cb_thread) {
369                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
370                 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
371         } else {
372                 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
373                  * the focus state mutex could be still locked. Therefore, it returns error here. */
374                 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
375                         LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
376                         return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
377                 }
378                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
379         }
380
381         if (stream_h->acquired_focus & focus_mask) {
382                 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
383                 ret = MM_ERROR_SOUND_INVALID_STATE;
384                 goto LEAVE;
385         }
386
387         if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & ~stream_h->acquired_focus) & focus_mask)) {
388                 LOGE("just lost focus in this callback, it is not allowed to acquire the focus[0x%x] again. acquired_focus[0x%x], prev[0x%x]",
389                         focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
390                 ret = MM_ERROR_POLICY_INTERNAL;
391                 goto LEAVE;
392         }
393
394         stream_h->is_requesting = true;
395
396         ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
397         if (ret == MM_ERROR_NONE) {
398                 stream_h->acquired_focus |= focus_mask;
399                 stream_h->prev_acquired_focus |= focus_mask;
400                 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
401         }
402
403         LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
404
405 LEAVE:
406         stream_h->is_requesting = false;
407         SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
408         if (!is_focus_cb_thread)
409                 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
410
411         return _convert_sound_manager_error_code(__func__, ret);
412 }
413
414 int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, int sound_behavior, const char *extra_info)
415 {
416         int ret = MM_ERROR_NONE;
417         bool is_focus_cb_thread = false;
418         bool is_focus_watch_cb_thread = false;
419         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
420
421         SM_ARG_CHECK(stream_h);
422
423         LOGI("stream_info[%p, type:%s, focus_id:%d] focus_mask[0x%x] sound_behavior[0x%x] extra_info[%s]",
424                 stream_info, stream_h->stream_type, stream_h->focus_id, focus_mask, sound_behavior, extra_info);
425
426         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
427                 return _convert_sound_manager_error_code(__func__, ret);
428
429         if (!is_focus_cb_thread) {
430                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
431                 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
432         } else {
433                 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
434                  * the focus state mutex could be still locked. Therefore, it returns error here. */
435                 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
436                         LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
437                         return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
438                 }
439                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
440         }
441
442         if (!(stream_h->acquired_focus & focus_mask)) {
443                 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
444                 ret = MM_ERROR_SOUND_INVALID_STATE;
445                 goto LEAVE;
446         }
447
448         if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & stream_h->acquired_focus) != focus_mask)) {
449                 LOGE("just acquired focus in this callback, it is not allowed to release the focus[0x%x] again. acquired_focus[0x%x], prev[0x%x]",
450                         focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
451                 ret = MM_ERROR_SOUND_INVALID_STATE;
452                 goto LEAVE;
453         }
454
455         stream_h->is_requesting = true;
456
457         ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
458         if (ret == MM_ERROR_NONE) {
459                 stream_h->acquired_focus &= ~focus_mask;
460                 stream_h->prev_acquired_focus &= ~focus_mask;
461                 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
462         }
463
464         LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
465
466 LEAVE:
467         stream_h->is_requesting = false;
468         SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
469         if (!is_focus_cb_thread)
470                 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
471
472         return _convert_sound_manager_error_code(__func__, ret);
473 }
474
475 int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
476 {
477         int ret = MM_ERROR_NONE;
478         int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
479         bool is_focus_cb_thread = false;
480         bool is_focus_watch_cb_thread = false;
481         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
482
483         SM_ARG_CHECK(stream_h);
484
485         LOGI("stream_info[%p, type:%s, focus_id:%d] sound_behavior[0x%x] extra_info[%s]",
486                 stream_info, stream_h->stream_type, stream_h->focus_id, sound_behavior, extra_info);
487
488         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
489                 return _convert_sound_manager_error_code(__func__, ret);
490
491         if (stream_h->is_focus_unavailable) {
492                 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
493                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
494         }
495
496         if (stream_h->user_cb == NULL) {
497                 LOGE("focus state changed callback should be set before acquiring focus");
498                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
499         }
500
501         if (!is_focus_cb_thread) {
502                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
503                 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
504         } else {
505                 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
506                  * the focus state mutex could be still locked. Therefore, it returns error here. */
507                 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
508                         LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
509                         return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
510                 }
511                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
512         }
513
514         if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
515                 LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
516                         stream_h->acquired_focus, stream_h->prev_acquired_focus);
517                 ret = MM_ERROR_POLICY_INTERNAL;
518                 goto LEAVE;
519         }
520
521         focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH & ~(stream_h->acquired_focus);
522         if (!focus_mask) {
523                 LOGI("PLAYBACK/RECORDING focuses have already been ACQUIRED");
524                 ret = MM_ERROR_NONE;
525                 goto LEAVE;
526         }
527
528         stream_h->is_requesting = true;
529
530         ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
531         if (ret == MM_ERROR_NONE) {
532                 stream_h->acquired_focus |= focus_mask;
533                 stream_h->prev_acquired_focus |= focus_mask;
534                 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
535         }
536
537 LEAVE:
538         stream_h->is_requesting = false;
539         SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
540         if (!is_focus_cb_thread)
541                 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
542
543         return _convert_sound_manager_error_code(__func__, ret);
544 }
545
546 int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
547 {
548         int ret = MM_ERROR_NONE;
549         bool is_focus_cb_thread = false;
550         bool is_focus_watch_cb_thread = false;
551         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
552
553         SM_ARG_CHECK(stream_h);
554
555         LOGI("stream_info[%p, type:%s, focus_id:%d] sound_behavior[0x%x] extra_info[%s]",
556                 stream_info, stream_h->stream_type, stream_h->focus_id, sound_behavior, extra_info);
557
558         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
559                 return _convert_sound_manager_error_code(__func__, ret);
560
561         if (!is_focus_cb_thread) {
562                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
563                 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
564         } else {
565                 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
566                  * the focus state mutex could be still locked. Therefore, it returns error here. */
567                 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
568                         LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
569                         return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
570                 }
571                 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
572         }
573
574         if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
575                 LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
576                         stream_h->acquired_focus, stream_h->prev_acquired_focus);
577                 ret = MM_ERROR_POLICY_INTERNAL;
578                 goto LEAVE;
579         }
580
581         if (!stream_h->acquired_focus) {
582                 LOGI("PLAYBACK/RECORDING focuses have already been RELEASED");
583                 ret = MM_ERROR_NONE;
584                 goto LEAVE;
585         }
586
587         stream_h->is_requesting = true;
588
589         ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
590         if (ret == MM_ERROR_NONE) {
591                 stream_h->acquired_focus = 0;
592                 stream_h->prev_acquired_focus = 0;
593                 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
594         }
595
596 LEAVE:
597         stream_h->is_requesting = false;
598         SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
599         if (!is_focus_cb_thread)
600                 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
601
602         return _convert_sound_manager_error_code(__func__, ret);
603 }
604
605 int sound_manager_get_focus_state(sound_stream_info_h stream_info, sound_stream_focus_state_e *state_for_playback, sound_stream_focus_state_e *state_for_recording)
606 {
607         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
608
609         SM_ARG_CHECK(stream_h);
610         SM_ARG_CHECK(state_for_playback || state_for_recording);
611
612         LOGI("stream_info[%p, type:%s, focus_id:%d]", stream_info, stream_h->stream_type, stream_h->focus_id);
613
614         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
615
616         if (state_for_playback)
617                 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
618         if (state_for_recording)
619                 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
620
621         LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
622
623         SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
624
625         return SOUND_MANAGER_ERROR_NONE;
626 }
627
628 int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
629 {
630         int ret = MM_ERROR_NONE;
631         sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
632         sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
633         bool is_focus_cb_thread = false;
634
635         SM_ARG_CHECK(src_stream_h);
636         SM_ARG_CHECK(dst_stream_h);
637
638         LOGI("SRC stream_info[%p, type:%s, focus_id:%d]", source, src_stream_h->stream_type, src_stream_h->focus_id);
639         LOGI("DST stream_info[%p, type:%s, focus_id:%d]", destination, dst_stream_h->stream_type, dst_stream_h->focus_id);
640         LOGI("focus_mask[0x%x]", focus_mask);
641
642         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
643                 return _convert_sound_manager_error_code(__func__, ret);
644
645         if (is_focus_cb_thread) {
646                 LOGE("not allowed calling this function in focus(watch) callback");
647                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
648         }
649
650         if (src_stream_h->focus_id == dst_stream_h->focus_id) {
651                 LOGE("not allowed because both handles have same id(%u)", src_stream_h->focus_id);
652                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
653         }
654
655         if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
656                 LOGE("focus is unavailable for source(%d)/destination(%d)",
657                         src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
658                 return SOUND_MANAGER_ERROR_POLICY;
659         }
660
661         if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
662                 LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
663                         focus_mask, src_stream_h->acquired_focus);
664                 return SOUND_MANAGER_ERROR_INVALID_STATE;
665         }
666
667         if (dst_stream_h->user_cb == NULL) {
668                 LOGE("focus state changed callback should be set to destination handle");
669                 return SOUND_MANAGER_ERROR_POLICY;
670         }
671
672         ret = mm_sound_deliver_focus(src_stream_h->focus_id, dst_stream_h->focus_id, (mm_sound_focus_type_e)focus_mask);
673         if (ret == MM_ERROR_NONE) {
674                 src_stream_h->acquired_focus &= ~focus_mask;
675                 src_stream_h->prev_acquired_focus &= ~focus_mask;
676                 dst_stream_h->acquired_focus |= focus_mask;
677                 dst_stream_h->prev_acquired_focus |= focus_mask;
678         }
679
680         return _convert_sound_manager_error_code(__func__, ret);
681 }
682
683 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
684 {
685         int ret = MM_ERROR_NONE;
686         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
687
688         SM_ARG_CHECK(stream_h);
689         SM_ARG_CHECK(device);
690         SM_ARG_CHECK(is_on);
691
692         LOGI("stream_info[%p, type:%s] device[%p]", stream_info, stream_h->stream_type, device);
693
694         ret = mm_sound_is_stream_on_device(stream_h->pa_info.index, device, is_on);
695
696         LOGI("is_on[%d]", *is_on);
697
698         return _convert_sound_manager_error_code(__func__, ret);
699 }
700
701 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
702 {
703         SM_ARG_CHECK(device_type);
704
705         return _get_current_media_routing_path("out", device_type);
706 }
707
708 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
709 {
710         int ret = SOUND_MANAGER_ERROR_NONE;
711         int mm_ret = MM_ERROR_NONE;
712         char *stream_type_str = NULL;
713         char *extra_info_str = NULL;
714         int option = 0;
715         bool is_focus_cb_thread = false;
716
717         SM_ARG_CHECK(acquired_by);
718         SM_ARG_CHECK(flags);
719
720         if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
721                 return _convert_sound_manager_error_code(__func__, mm_ret);
722
723         if (is_focus_cb_thread) {
724                 LOGE("this API should not be called in focus callback");
725                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
726         }
727
728         mm_ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
729         if (mm_ret != MM_ERROR_NONE)
730                 return _convert_sound_manager_error_code(__func__, mm_ret);
731
732         LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
733         ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
734         if (ret == SOUND_MANAGER_ERROR_NONE) {
735                 LOGI("                                : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
736                 *flags = option;
737                 if (extra_info)
738                         *extra_info = strdup(extra_info_str);
739         }
740         SM_SAFE_FREE(stream_type_str);
741         SM_SAFE_FREE(extra_info_str);
742
743         return ret;
744 }
745
746 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
747 {
748         int ret = SOUND_MANAGER_ERROR_NONE;
749         int mm_ret = MM_ERROR_NONE;
750         char *stream_type_str = NULL;
751         char *extra_info_str = NULL;
752         int option = 0;
753         bool is_focus_cb_thread = false;
754
755         SM_ARG_CHECK(acquired_by);
756         SM_ARG_CHECK(flags);
757
758         if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
759                 return _convert_sound_manager_error_code(__func__, mm_ret);
760
761         if (is_focus_cb_thread) {
762                 LOGE("this API should not be called in focus callback");
763                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
764         }
765
766         mm_ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
767         if (mm_ret != MM_ERROR_NONE)
768                 return _convert_sound_manager_error_code(__func__, mm_ret);
769
770         LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
771         ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
772         if (ret == SOUND_MANAGER_ERROR_NONE) {
773                 LOGI("                                 : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
774                 *flags = option;
775                 if (extra_info)
776                         *extra_info = strdup(extra_info_str);
777         }
778         SM_SAFE_FREE(stream_type_str);
779         SM_SAFE_FREE(extra_info_str);
780
781         return ret;
782 }
783
784 int sound_manager_add_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_watch_cb callback, void *user_data, int *id)
785 {
786         int ret = MM_ERROR_NONE;
787         int i = 0;
788
789         SM_ARG_CHECK(callback);
790         SM_ARG_CHECK(id);
791
792         LOGI("focus_mask[0x%x] callback[%p] user_data[%p]", focus_mask, callback, user_data);
793
794         for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
795                 if (focus_watch_info_arr[i].id == 0)
796                         break;
797         if (i == SOUND_STREAM_INFO_ARR_MAX) {
798                 //LCOV_EXCL_START
799                 LOGE("focus watch info array is full");
800                 ret = MM_ERROR_SOUND_INTERNAL;
801                 goto LEAVE;
802                 //LCOV_EXCL_STOP
803         }
804
805         ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
806         if (ret == MM_ERROR_NONE) {
807                 focus_watch_info_arr[i].id = *id;
808                 focus_watch_info_arr[i].user_data = user_data;
809                 focus_watch_info_arr[i].user_cb = callback;
810         }
811
812 LEAVE:
813         LOGI("id[%d]", *id);
814
815         return _convert_sound_manager_error_code(__func__, ret);
816 }
817
818 int sound_manager_remove_focus_state_watch_cb(int id)
819 {
820         int ret = MM_ERROR_NONE;
821         int i = 0;
822
823         LOGI("id[%d]", id);
824
825         for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
826                 if (focus_watch_info_arr[i].id == id)
827                         break;
828         if (i == SOUND_STREAM_INFO_ARR_MAX) {
829                 LOGE("could not find item in focus watch info array for this id(%d)", id);
830                 ret = MM_ERROR_INVALID_ARGUMENT;
831                 goto LEAVE;
832         }
833
834         ret = mm_sound_unset_focus_watch_callback(id);
835         if (ret == MM_ERROR_NONE) {
836                 focus_watch_info_arr[i].id = 0;
837                 focus_watch_info_arr[i].user_data = NULL;
838                 focus_watch_info_arr[i].user_cb = NULL;
839         }
840
841 LEAVE:
842         return _convert_sound_manager_error_code(__func__, ret);
843 }
844
845 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
846 {
847         int ret = MM_ERROR_NONE;
848
849         SM_ARG_CHECK(device_list);
850
851         LOGI("device_mask[0x%x]", device_mask);
852
853         ret = mm_sound_get_device_list(device_mask, device_list);
854
855         LOGI("device_list[%p]", *device_list);
856
857         return _convert_sound_manager_error_code(__func__, ret);
858 }
859
860 int sound_manager_free_device_list(sound_device_list_h device_list)
861 {
862         int ret = MM_ERROR_NONE;
863
864         SM_ARG_CHECK(device_list);
865
866         LOGI("device_list[%p]", device_list);
867
868         ret = mm_sound_free_device_list(device_list);
869
870         return _convert_sound_manager_error_code(__func__, ret);
871 }
872
873 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
874 {
875         int ret = MM_ERROR_NONE;
876
877         SM_ARG_CHECK(device_list);
878         SM_ARG_CHECK(device);
879
880         LOGI("device_list[%p]", device_list);
881
882         ret = mm_sound_get_next_device(device_list, device);
883
884         LOGI("device[%p]", *device);
885
886         return _convert_sound_manager_error_code(__func__, ret);
887 }
888
889 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
890 {
891         int ret = MM_ERROR_NONE;
892
893         SM_ARG_CHECK(device_list);
894         SM_ARG_CHECK(device);
895
896         LOGI("device_list[%p]", device_list);
897
898         ret = mm_sound_get_prev_device(device_list, device);
899
900         LOGI("device[%p]", *device);
901
902         return _convert_sound_manager_error_code(__func__, ret);
903 }
904
905 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
906 {
907         int ret = MM_ERROR_NONE;
908         mm_sound_device_type_e mm_sound_device_type;
909
910         SM_ARG_CHECK(device);
911         SM_ARG_CHECK(type);
912
913         LOGI("device[%p]", device);
914
915         if ((ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE)
916                 return _convert_sound_manager_error_code(__func__, ret);
917
918         return _convert_device_type(mm_sound_device_type, type);
919 }
920
921 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
922 {
923         int ret = MM_ERROR_NONE;
924         mm_sound_device_io_direction_e mm_sound_io_direction;
925
926         SM_ARG_CHECK(device);
927         SM_ARG_CHECK(io_direction);
928
929         LOGI("device[%p]", device);
930
931         if ((ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction)) != MM_ERROR_NONE)
932                 return _convert_sound_manager_error_code(__func__, ret);
933
934         return _convert_device_io_direction(mm_sound_io_direction, io_direction);
935 }
936
937 int sound_manager_get_device_id(sound_device_h device, int *id)
938 {
939         int ret = MM_ERROR_NONE;
940
941         SM_ARG_CHECK(device);
942         SM_ARG_CHECK(id);
943
944         LOGI("device[%p]", device);
945
946         ret = mm_sound_get_device_id(device, id);
947
948         LOGI("id[%d]", *id);
949
950         return _convert_sound_manager_error_code(__func__, ret);
951 }
952
953 int sound_manager_get_device_name(sound_device_h device, char **name)
954 {
955         int ret = MM_ERROR_NONE;
956
957         SM_ARG_CHECK(device);
958         SM_ARG_CHECK(name);
959
960         LOGI("device[%p]", device);
961
962         ret = mm_sound_get_device_name(device, name);
963
964         LOGI("name[%s]", *name);
965
966         return _convert_sound_manager_error_code(__func__, ret);
967 }
968
969 int sound_manager_is_device_running(sound_device_h device, bool *is_running)
970 {
971         int ret = MM_ERROR_NONE;
972
973         SM_ARG_CHECK(device);
974         SM_ARG_CHECK(is_running);
975
976         LOGI("device[%p]", device);
977
978         ret = mm_sound_is_device_running(device, is_running);
979
980         LOGI("is_running[%d]", *is_running);
981
982         return _convert_sound_manager_error_code(__func__, ret);
983 }
984
985 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
986 {
987         int ret = MM_ERROR_NONE;
988
989         SM_ARG_CHECK(device);
990         SM_ARG_CHECK(state);
991
992         LOGI("device[%p]", device);
993
994         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
995         ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
996
997         LOGI("state[%d]", *state);
998
999         return _convert_sound_manager_error_code(__func__, ret);
1000 }
1001
1002 int sound_manager_get_supported_sample_formats(sound_device_h device, sound_sample_format_e **formats, unsigned int *num_of_elems)
1003 {
1004         int ret = SOUND_MANAGER_ERROR_NONE;
1005         int mm_ret = MM_ERROR_NONE;
1006         int device_id;
1007
1008         SM_ARG_CHECK(device);
1009         SM_ARG_CHECK(formats);
1010         SM_ARG_CHECK(num_of_elems);
1011
1012         LOGI("device[%p]", device);
1013
1014         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1015                 return ret;
1016
1017         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1018                 return _convert_sound_manager_error_code(__func__, mm_ret);
1019
1020         return _get_supported_sample_formats(device_id, formats, num_of_elems);
1021 }
1022
1023 int sound_manager_set_sample_format(sound_device_h device, sound_sample_format_e format)
1024 {
1025         int ret = SOUND_MANAGER_ERROR_NONE;
1026         int mm_ret = MM_ERROR_NONE;
1027         int device_id;
1028
1029         SM_ARG_CHECK(device);
1030
1031         LOGI("device[%p] format[%d]", device, format);
1032
1033         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1034                 return ret;
1035
1036         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1037                 return _convert_sound_manager_error_code(__func__, mm_ret);
1038
1039         return _set_sample_format(device_id, format);
1040 }
1041
1042 int sound_manager_get_sample_format(sound_device_h device, sound_sample_format_e *format)
1043 {
1044         int ret = SOUND_MANAGER_ERROR_NONE;
1045         int mm_ret = MM_ERROR_NONE;
1046         int device_id;
1047
1048         SM_ARG_CHECK(device);
1049         SM_ARG_CHECK(format);
1050
1051         LOGI("device[%p]", device);
1052
1053         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1054                 return ret;
1055
1056         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1057                 return _convert_sound_manager_error_code(__func__, mm_ret);
1058
1059         return _get_sample_format(device_id, format);
1060 }
1061
1062 int sound_manager_get_supported_sample_rates(sound_device_h device, sound_sample_rate_e **rates, unsigned int *num_of_elems)
1063 {
1064         int ret = SOUND_MANAGER_ERROR_NONE;
1065         int mm_ret = MM_ERROR_NONE;
1066         int device_id;
1067
1068         SM_ARG_CHECK(device);
1069         SM_ARG_CHECK(rates);
1070         SM_ARG_CHECK(num_of_elems);
1071
1072         LOGI("device[%p]", device);
1073
1074         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1075                 return ret;
1076
1077         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1078                 return _convert_sound_manager_error_code(__func__, mm_ret);
1079
1080         return _get_supported_sample_rates(device_id, rates, num_of_elems);
1081 }
1082
1083 int sound_manager_set_sample_rate(sound_device_h device, sound_sample_rate_e rate)
1084 {
1085         int ret = SOUND_MANAGER_ERROR_NONE;
1086         int mm_ret = MM_ERROR_NONE;
1087         int device_id;
1088
1089         SM_ARG_CHECK(device);
1090
1091         LOGI("device[%p] rate[%d]", device, rate);
1092
1093         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1094                 return ret;
1095
1096         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1097                 return _convert_sound_manager_error_code(__func__, mm_ret);
1098
1099         return _set_sample_rate(device_id, rate);
1100 }
1101
1102 int sound_manager_get_sample_rate(sound_device_h device, sound_sample_rate_e *rate)
1103 {
1104         int ret = SOUND_MANAGER_ERROR_NONE;
1105         int mm_ret = MM_ERROR_NONE;
1106         int device_id;
1107
1108         SM_ARG_CHECK(device);
1109         SM_ARG_CHECK(rate);
1110
1111         LOGI("device[%p]", device);
1112
1113         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1114                 return ret;
1115
1116         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1117                 return _convert_sound_manager_error_code(__func__, mm_ret);
1118
1119         return _get_sample_rate(device_id, rate);
1120 }
1121
1122 int sound_manager_set_avoid_resampling(sound_device_h device, bool enable)
1123 {
1124         int ret = SOUND_MANAGER_ERROR_NONE;
1125         int mm_ret = MM_ERROR_NONE;
1126         int device_id;
1127
1128         SM_ARG_CHECK(device);
1129
1130         LOGI("device[%p] enable[%d]", device, enable);
1131
1132         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1133                 return ret;
1134
1135         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1136                 return _convert_sound_manager_error_code(__func__, mm_ret);
1137
1138         return _set_avoid_resampling(device_id, enable);
1139 }
1140
1141 int sound_manager_get_avoid_resampling(sound_device_h device, bool *enabled)
1142 {
1143         int ret = SOUND_MANAGER_ERROR_NONE;
1144         int mm_ret = MM_ERROR_NONE;
1145         int device_id;
1146
1147         SM_ARG_CHECK(device);
1148         SM_ARG_CHECK(enabled);
1149
1150         LOGI("device[%p]", device);
1151
1152         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1153                 return ret;
1154
1155         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1156                 return _convert_sound_manager_error_code(__func__, mm_ret);
1157
1158         return _get_avoid_resampling(device_id, enabled);
1159 }
1160
1161 int sound_manager_set_media_stream_only(sound_device_h device, bool enable)
1162 {
1163         int ret = SOUND_MANAGER_ERROR_NONE;
1164         int mm_ret = MM_ERROR_NONE;
1165         int device_id;
1166
1167         SM_ARG_CHECK(device);
1168
1169         LOGI("device[%p] enable[%d]", device, enable);
1170
1171         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1172                 return ret;
1173
1174         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1175                 return _convert_sound_manager_error_code(__func__, mm_ret);
1176
1177         return _set_media_stream_only(device_id, enable);
1178 }
1179
1180 int sound_manager_get_media_stream_only(sound_device_h device, bool *enabled)
1181 {
1182         int ret = SOUND_MANAGER_ERROR_NONE;
1183         int mm_ret = MM_ERROR_NONE;
1184         int device_id;
1185
1186         SM_ARG_CHECK(device);
1187         SM_ARG_CHECK(enabled);
1188
1189         LOGI("device[%p]", device);
1190
1191         if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1192                 return ret;
1193
1194         if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1195                 return _convert_sound_manager_error_code(__func__, mm_ret);
1196
1197         return _get_media_stream_only(device_id, enabled);
1198 }
1199
1200 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id)
1201 {
1202         int ret = MM_ERROR_NONE;
1203
1204         SM_ARG_CHECK(callback);
1205         SM_ARG_CHECK(id);
1206
1207         LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1208
1209         ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, (unsigned int*)id);
1210
1211         LOGI("id[%d]", *id);
1212
1213         return _convert_sound_manager_error_code(__func__, ret);
1214 }
1215
1216 int sound_manager_remove_device_connection_changed_cb(int id)
1217 {
1218         int ret = MM_ERROR_NONE;
1219
1220         SM_ARG_CHECK(id >= 0);
1221
1222         LOGI("id[%d]", id);
1223
1224         ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1225
1226         return _convert_sound_manager_error_code(__func__, ret);
1227 }
1228
1229 int sound_manager_add_device_running_changed_cb(int device_mask, sound_device_running_changed_cb callback, void *user_data, int *id)
1230 {
1231         int ret = MM_ERROR_NONE;
1232
1233         SM_ARG_CHECK(callback);
1234         SM_ARG_CHECK(id);
1235
1236         LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1237
1238         ret = mm_sound_add_device_running_changed_callback(device_mask, (mm_sound_device_running_changed_cb)callback, user_data, (unsigned int*)id);
1239
1240         LOGI("id[%d]", *id);
1241
1242         return _convert_sound_manager_error_code(__func__, ret);
1243 }
1244
1245 int sound_manager_remove_device_running_changed_cb(int id)
1246 {
1247         int ret = MM_ERROR_NONE;
1248
1249         SM_ARG_CHECK(id >= 0);
1250
1251         LOGI("id[%d]", id);
1252
1253         ret = mm_sound_remove_device_running_changed_callback((unsigned int)id);
1254
1255         return _convert_sound_manager_error_code(__func__, ret);
1256 }
1257
1258 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1259 {
1260         int ret = MM_ERROR_NONE;
1261
1262         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1263         SM_ARG_CHECK(callback);
1264         SM_ARG_CHECK(id);
1265
1266         LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1267
1268         ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
1269
1270         LOGI("id[%d]", *id);
1271
1272         return _convert_sound_manager_error_code(__func__, ret);
1273 }
1274
1275 int sound_manager_remove_device_state_changed_cb(int id)
1276 {
1277         int ret = MM_ERROR_NONE;
1278
1279         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1280         SM_ARG_CHECK(id >= 0);
1281
1282         LOGI("id[%d]", id);
1283
1284         ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
1285
1286         return _convert_sound_manager_error_code(__func__, ret);
1287 }
1288
1289 int sound_manager_create_stream_ducking(sound_stream_type_e target_stream, sound_stream_ducking_state_changed_cb callback, void *user_data, sound_stream_ducking_h *stream_ducking)
1290 {
1291         int i = 0;
1292         int ret = SOUND_MANAGER_ERROR_NONE;
1293         int mm_ret = MM_ERROR_NONE;
1294         sound_stream_ducking_s *new_ducking = NULL;
1295
1296         SM_ARG_CHECK(stream_ducking);
1297
1298         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1299
1300         for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1301                 if (ducking_arr[i] == NULL)
1302                         break;
1303
1304         if (i == SOUND_DUCKING_ARR_MAX) {
1305                 LOGE("ducking array is full");
1306                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1307                 goto LEAVE;
1308         }
1309
1310         LOGI("target_stream[%d] callback[%p] user_data[%p]", target_stream, callback, user_data);
1311
1312         new_ducking = (sound_stream_ducking_s *)calloc(1, sizeof(sound_stream_ducking_s));
1313         if (!new_ducking) {
1314                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1315                 goto LEAVE;
1316         }
1317
1318         ret = _convert_stream_type(target_stream, &new_ducking->target_stream);
1319         if (ret != SOUND_MANAGER_ERROR_NONE)
1320                 goto LEAVE;
1321
1322         ret = _make_pa_connection(&new_ducking->pa_info, "SOUND_MANAGER_STREAM_DUCKING");
1323         if (ret != SOUND_MANAGER_ERROR_NONE)
1324                 goto LEAVE;
1325
1326         if (++ducking_arr_count == 1) {
1327                 /* subscribe ducking finished signal */
1328                 mm_ret = mm_sound_add_ducking_state_changed_callback((mm_sound_ducking_state_changed_cb)_ducking_state_changed_cb,
1329                         NULL, &ducking_cb_subs_id);
1330                 if (mm_ret != MM_ERROR_NONE) {
1331                         ducking_arr_count = 0;
1332                         ret = _convert_sound_manager_error_code(__func__, mm_ret);
1333                         goto LEAVE;
1334                 }
1335
1336                 LOGI("ducking state changed cb subs id %d", ducking_cb_subs_id);
1337         }
1338
1339         new_ducking->user_cb = callback;
1340         new_ducking->user_data = user_data;
1341
1342         ducking_arr[i] = new_ducking;
1343         *stream_ducking = (sound_stream_ducking_h)new_ducking;
1344
1345         LOGI("new stream_ducking[%p] target_stream[%s] pa_index[%u]",
1346                 new_ducking, new_ducking->target_stream, new_ducking->pa_info.index);
1347
1348 LEAVE:
1349         if (ret != SOUND_MANAGER_ERROR_NONE) {
1350                 if (new_ducking) {
1351                         _destroy_pa_connection(&new_ducking->pa_info);
1352                         free(new_ducking);
1353                 }
1354         }
1355
1356         SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1357
1358         LOGI("ret[0x%x]", ret);
1359
1360         return ret;
1361 }
1362
1363 int sound_manager_destroy_stream_ducking(sound_stream_ducking_h stream_ducking)
1364 {
1365         int i = 0;
1366         int ret = SOUND_MANAGER_ERROR_NONE;
1367         bool is_ducked = false;
1368         sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1369
1370         SM_ARG_CHECK(ducking);
1371
1372         LOGI("stream_ducking[%p]", ducking);
1373
1374         ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1375         if (ret != SOUND_MANAGER_ERROR_NONE && !ducking->pa_info.is_disconnected)
1376                 return ret;
1377
1378         if (is_ducked) {
1379                 LOGE("ducked now, it should be deactivated first.");
1380                 return SOUND_MANAGER_ERROR_INVALID_STATE;
1381         }
1382
1383         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1384
1385         _destroy_pa_connection(&ducking->pa_info);
1386
1387         for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1388                 if (ducking_arr[i] == ducking)
1389                         ducking_arr[i] = NULL;
1390
1391         if (--ducking_arr_count == 0) {
1392                 /* unsubscribe ducking finished signal */
1393                 if (mm_sound_remove_ducking_state_changed_callback(ducking_cb_subs_id) != MM_ERROR_NONE)
1394                         LOGW("mm_sound_remove_ducking_state_changed_callback(id:%u) failed", ducking_cb_subs_id);
1395
1396                 ducking_cb_subs_id = 0;
1397         }
1398
1399         free(ducking);
1400
1401         SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1402
1403         return SOUND_MANAGER_ERROR_NONE;
1404 }
1405
1406 int sound_manager_is_ducked(sound_stream_ducking_h stream_ducking, bool *is_ducked)
1407 {
1408         sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1409
1410         SM_ARG_CHECK(ducking);
1411         SM_ARG_CHECK(is_ducked);
1412
1413         LOGI("stream_ducking[%p]", ducking);
1414
1415         return _get_ducking_state(&ducking->pa_info, is_ducked);
1416 }
1417
1418 int sound_manager_activate_ducking(sound_stream_ducking_h stream_ducking, unsigned int duration, double ratio)
1419 {
1420         int ret = SOUND_MANAGER_ERROR_NONE;
1421         bool is_ducked = false;
1422         sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1423
1424         SM_ARG_CHECK(ducking);
1425         SM_ARG_CHECK(duration <= 3000);
1426         SM_ARG_CHECK(ratio < 1.0);
1427         SM_ARG_CHECK(ratio >= 0.0);
1428
1429         LOGI("stream_ducking[%p] duration[%u] ratio[%lf]", ducking, duration, ratio);
1430
1431         ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1432         if (ret != SOUND_MANAGER_ERROR_NONE)
1433                 return ret;
1434
1435         if (is_ducked) {
1436                 LOGE("already ducked");
1437                 return SOUND_MANAGER_ERROR_INVALID_STATE;
1438         }
1439
1440         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1441
1442         ret = _activate_ducking(ducking->pa_info.index,
1443                 true, ducking->target_stream, (uint32_t)duration, ratio);
1444         if (ret == SOUND_MANAGER_ERROR_NONE) {
1445                 ducking->duration = duration;
1446                 ducking->ratio = ratio;
1447         }
1448
1449         SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1450
1451         LOGI("ret[0x%x]", ret);
1452
1453         return ret;
1454 }
1455
1456 int sound_manager_deactivate_ducking(sound_stream_ducking_h stream_ducking)
1457 {
1458         int ret = SOUND_MANAGER_ERROR_NONE;
1459         bool is_ducked = false;
1460         sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1461
1462         SM_ARG_CHECK(ducking);
1463
1464         LOGI("stream_ducking[%p]", ducking);
1465
1466         ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1467         if (ret != SOUND_MANAGER_ERROR_NONE)
1468                 return ret;
1469
1470         if (!is_ducked) {
1471                 LOGE("not ducked");
1472                 return SOUND_MANAGER_ERROR_INVALID_STATE;
1473         }
1474
1475         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1476
1477         ret = _activate_ducking(ducking->pa_info.index,
1478                 false, ducking->target_stream, (uint32_t)ducking->duration, ducking->ratio);
1479
1480         SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1481
1482         LOGI("ret[0x%x]", ret);
1483
1484         return ret;
1485 }