Use proper API get_current_device_list
[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 #include <system_info.h>
20
21 #define FEATURE_MICROPHONE          "http://tizen.org/feature/microphone"
22
23 _session_interrupt_info_s g_session_interrupt_cb_table = {0, 0, NULL, NULL};
24 _volume_changed_info_s g_volume_changed_cb_table = {0, NULL, NULL};
25 _device_connected_info_s g_device_connected_cb_table = {0, NULL, NULL};
26 _device_changed_info_s g_device_info_changed_cb_table = {0, NULL, NULL};
27 _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
28
29 sound_session_type_e g_cached_session = -1;
30 _session_mode_e g_cached_session_mode = -1;
31 int g_cached_voip_device_id = -1;
32 extern sound_stream_info_s *g_voip_stream_info;
33 extern virtual_sound_stream_info_s *g_voip_vstream_h;
34
35 /* These variables will be removed when session features are deprecated. */
36 extern int g_stream_info_count;
37 extern pthread_mutex_t g_stream_info_count_mutex;
38 pthread_mutex_t g_interrupt_cb_mutex, g_device_info_cb_mutex, g_device_conn_cb_mutex, g_volume_cb_mutex;
39
40 int sound_manager_get_max_volume(sound_type_e type, int *max)
41 {
42         const char *volume_type = NULL;
43         unsigned int max_level = 0;
44         int ret = MM_ERROR_NONE;
45
46         SM_NULL_ARG_CHECK(max);
47         if (type >= SOUND_TYPE_NUM || type < 0)
48                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
49
50         ret = _convert_sound_type(type, &volume_type);
51         if (ret == MM_ERROR_NONE) {
52                 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
53                 if (ret == MM_ERROR_NONE)
54                         *max = (int)max_level -1;       /* actual volume step can be max step - 1 */
55         }
56
57         return _convert_sound_manager_error_code(__func__, ret);
58 }
59
60 int sound_manager_set_volume(sound_type_e type, int volume)
61 {
62         int ret = MM_ERROR_NONE;
63
64         if (type >= SOUND_TYPE_NUM || type < 0)
65                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
66         if (volume < 0)
67                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
68
69         ret = mm_sound_volume_set_value(type, volume);
70         LOGI("type=%d, volume=%d", type, volume);
71
72         return _convert_sound_manager_error_code(__func__, ret);
73 }
74
75 int sound_manager_get_volume(sound_type_e type, int *volume)
76 {
77         int ret = MM_ERROR_NONE;
78         unsigned int uvolume;
79
80         if (type >= SOUND_TYPE_NUM || type < 0)
81                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
82         if (volume == NULL)
83                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
84
85         ret = mm_sound_volume_get_value(type, &uvolume);
86         if (ret == MM_ERROR_NONE)
87                 *volume = uvolume;
88
89         LOGI("type=%d, volume=%d", type, *volume);
90
91         return _convert_sound_manager_error_code(__func__, ret);
92 }
93
94 int sound_manager_set_current_sound_type(sound_type_e type)
95 {
96         int ret = MM_ERROR_NONE;
97
98         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
99         if (type >= SOUND_TYPE_NUM || type < 0)
100                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
101
102         ret = mm_sound_volume_primary_type_set(type);
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 = MM_ERROR_NONE;
110         volume_type_t mm_sound_vol_type = VOLUME_TYPE_UNKNOWN;
111         char *volume_type = NULL;
112
113         if (type == NULL)
114                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
115
116         ret  = mm_sound_volume_primary_type_get(&mm_sound_vol_type);
117         if (ret == MM_ERROR_NONE) {
118                 if (mm_sound_vol_type == VOLUME_TYPE_UNKNOWN) {
119                         /* get the volume type of the current playing stream */
120                         ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
121                         if (ret == MM_ERROR_NONE)
122                                 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
123                 } else {
124                         *type = mm_sound_vol_type;
125                 }
126         }
127         LOGI("type=%d", *type);
128
129         return _convert_sound_manager_error_code(__func__, ret);
130 }
131
132 int sound_manager_unset_current_sound_type(void)
133 {
134         int ret = MM_ERROR_NONE;
135
136         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
137         ret = mm_sound_volume_primary_type_set(VOLUME_TYPE_UNKNOWN);
138
139         return _convert_sound_manager_error_code(__func__, ret);
140 }
141
142 int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback, void* user_data)
143 {
144         int ret = MM_ERROR_NONE;
145         unsigned int subs_id = 0;
146
147         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
148                 "Use sound_manager_add_volume_changed_cb() instead.", __func__);
149
150         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
151
152         ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, &subs_id);
153         if (ret == MM_ERROR_NONE) {
154                 g_volume_changed_cb_table.subs_id = subs_id;
155                 g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
156                 g_volume_changed_cb_table.user_data = user_data;
157         }
158
159         SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
160
161         return _convert_sound_manager_error_code(__func__, ret);
162 }
163
164 int sound_manager_unset_volume_changed_cb(void)
165 {
166         int ret = MM_ERROR_NONE;
167
168         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
169                 "Use sound_manager_remove_volume_changed_cb() instead.", __func__);
170
171         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
172
173         if (g_volume_changed_cb_table.subs_id > 0) {
174                 ret = mm_sound_remove_volume_changed_callback(g_volume_changed_cb_table.subs_id);
175                 if (ret == MM_ERROR_NONE) {
176                         g_volume_changed_cb_table.subs_id = 0;
177                         g_volume_changed_cb_table.user_cb = NULL;
178                         g_volume_changed_cb_table.user_data = NULL;
179                 }
180         } else {
181                 ret = MM_ERROR_SOUND_INTERNAL;
182         }
183
184         SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
185
186         return _convert_sound_manager_error_code(__func__, ret);
187 }
188
189 int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id)
190 {
191         int ret = MM_ERROR_NONE;
192
193         if (!callback || !id)
194                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
195
196         ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, (unsigned int*)id);
197
198         return _convert_sound_manager_error_code(__func__, ret);
199 }
200
201 int sound_manager_remove_volume_changed_cb(int id)
202 {
203         int ret = MM_ERROR_NONE;
204
205         if (id < 0)
206                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
207
208         ret = mm_sound_remove_volume_changed_callback(id);
209
210         return _convert_sound_manager_error_code(__func__, ret);
211 }
212
213 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)
214 {
215         int ret = MM_ERROR_NONE;
216
217         LOGI(">> enter");
218
219         SM_NULL_ARG_CHECK(stream_info);
220
221         if (g_session_interrupt_cb_table.is_registered)
222                 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INTERNAL);
223
224         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
225
226         sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
227         if (!stream_h) {
228                 ret = MM_ERROR_OUT_OF_MEMORY;
229                 goto LEAVE;
230         }
231
232         memset(stream_h, 0, sizeof(sound_stream_info_s));
233         ret = _convert_stream_type(stream_type, &stream_h->stream_type);
234         if (ret == MM_ERROR_NONE) {
235                 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
236                 if (ret == MM_ERROR_NONE) {
237                         *stream_info = (sound_stream_info_h)stream_h;
238                         SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
239                         LOGI("stream_h(%p), index(%u), user_cb(%p), cnt(%d), ret(0x%x)", stream_h, stream_h->index, stream_h->user_cb, g_stream_info_count, ret);
240                 }
241         }
242
243 LEAVE:
244         if (ret && stream_h)
245                 free(stream_h);
246
247         SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
248
249         return _convert_sound_manager_error_code(__func__, ret);
250 }
251
252 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
253 {
254         int ret = MM_ERROR_NONE;
255         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
256
257         LOGI(">> enter");
258
259         SM_INSTANCE_CHECK(stream_h);
260
261         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
262         ret = _destroy_pa_connection_and_unregister_focus(stream_h);
263         if (ret == MM_ERROR_NONE) {
264                 free(stream_h);
265                 stream_h = NULL;
266                 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
267         }
268         SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
269
270         LOGD("cnt(%d)", g_stream_info_count);
271
272         return _convert_sound_manager_error_code(__func__, ret);
273 }
274
275 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
276 {
277         int ret = MM_ERROR_NONE;
278         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
279
280         LOGI(">> enter");
281
282         SM_INSTANCE_CHECK(stream_h);
283         SM_NULL_ARG_CHECK(sound_type);
284
285         if (stream_h->stream_conf_info.volume_type == NULL) {
286                 ret = MM_ERROR_SOUND_NO_DATA;
287                 goto LEAVE;
288         }
289
290         ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
291         LOGI("sound type(%d)", *sound_type);
292
293 LEAVE:
294         return _convert_sound_manager_error_code(__func__, ret);
295 }
296
297 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
298 {
299         int ret = MM_ERROR_NONE;
300         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
301
302         LOGI(">> enter");
303
304         ret = _add_device_for_stream_routing(stream_h, device);
305
306         return _convert_sound_manager_error_code(__func__, ret);
307 }
308
309 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
310 {
311         int ret = MM_ERROR_NONE;
312         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
313
314         LOGI(">> enter");
315
316         ret = _remove_device_for_stream_routing(stream_h, device);
317
318         return _convert_sound_manager_error_code(__func__, ret);
319 }
320
321 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
322 {
323         int ret = MM_ERROR_NONE;
324         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
325
326         LOGI(">> enter");
327
328         ret = _apply_stream_routing(stream_h);
329
330         return _convert_sound_manager_error_code(__func__, ret);
331 }
332
333 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
334 {
335         int ret = MM_ERROR_NONE;
336         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
337
338         LOGI(">> enter");
339
340         SM_INSTANCE_CHECK(stream_h);
341
342         ret = mm_sound_set_focus_reacquisition(stream_h->index, enable);
343
344         return _convert_sound_manager_error_code(__func__, ret);
345 }
346
347 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
348 {
349         int ret = MM_ERROR_NONE;
350         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
351
352         LOGI(">> enter");
353
354         SM_INSTANCE_CHECK(stream_h);
355         SM_NULL_ARG_CHECK(enabled);
356
357         ret = mm_sound_get_focus_reacquisition(stream_h->index, enabled);
358
359         return _convert_sound_manager_error_code(__func__, ret);
360 }
361
362 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)
363 {
364         int ret = MM_ERROR_NONE;
365         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
366
367         LOGI(">> enter");
368
369         SM_INSTANCE_CHECK(stream_h);
370
371         if (stream_h->is_focus_unavailable) {
372                 LOGE("acquiring focus is not allowed for this strema type(%s)", stream_h->stream_type);
373                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
374         }
375
376         if (stream_h->user_cb == NULL) {
377                 LOGE("focus state changed callback should be set before acquiring focus");
378                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
379         }
380
381         ret = mm_sound_acquire_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
382         if (ret == MM_ERROR_NONE) {
383                 stream_h->acquired_focus |= focus_mask;
384                 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
385         }
386
387         return _convert_sound_manager_error_code(__func__, ret);
388 }
389
390 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)
391 {
392         int ret = MM_ERROR_NONE;
393         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
394
395         LOGI(">> enter");
396
397         SM_INSTANCE_CHECK(stream_h);
398
399         ret = mm_sound_release_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
400         if (ret == MM_ERROR_NONE) {
401                 stream_h->acquired_focus &= ~focus_mask;
402                 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
403         }
404
405         return _convert_sound_manager_error_code(__func__, ret);
406 }
407
408 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)
409 {
410         int ret = MM_ERROR_NONE;
411         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
412
413         LOGI(">> enter");
414
415         SM_INSTANCE_CHECK(stream_h);
416         if (!state_for_playback && !state_for_recording) {
417                 ret = MM_ERROR_INVALID_ARGUMENT;
418                 goto LEAVE;
419         }
420
421         if (state_for_playback)
422                 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
423         if (state_for_recording)
424                 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
425
426         LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
427
428 LEAVE:
429         return _convert_sound_manager_error_code(__func__, ret);
430 }
431
432 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
433 {
434         int ret = MM_ERROR_NONE;
435         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
436
437         LOGI(">> enter");
438
439         SM_NULL_ARG_CHECK(stream_h);
440         SM_NULL_ARG_CHECK(device);
441         SM_NULL_ARG_CHECK(is_on);
442
443         ret = mm_sound_is_stream_on_device(stream_h->index, device, is_on);
444
445         return _convert_sound_manager_error_code(__func__, ret);
446 }
447
448 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
449 {
450         int ret = MM_ERROR_NONE;
451
452         LOGI(">> enter");
453
454         SM_NULL_ARG_CHECK(device_type);
455
456         ret = _get_current_media_routing_path("out", device_type);
457
458         return _convert_sound_manager_error_code(__func__, ret);
459 }
460
461 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
462 {
463         int ret = MM_ERROR_NONE;
464         char *stream_type_str = NULL;
465         char *extra_info_str = NULL;
466         int option = 0;
467         bool is_focus_cb_thread = false;
468
469         LOGI(">> enter");
470
471         SM_NULL_ARG_CHECK(acquired_by);
472         SM_NULL_ARG_CHECK(flags);
473
474         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
475                 return _convert_sound_manager_error_code(__func__, ret);
476
477         if (is_focus_cb_thread) {
478                 LOGE("this API should not be called in focus callback");
479                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
480         }
481
482         ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
483         if (ret == MM_ERROR_NONE) {
484                 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
485                 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
486                 if (ret == MM_ERROR_NONE) {
487                         LOGI("                                : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
488                         *flags = option;
489                         if (extra_info)
490                                 *extra_info = extra_info_str;
491                         else
492                                 free(extra_info_str);
493                 }
494         }
495
496         return _convert_sound_manager_error_code(__func__, ret);
497 }
498
499 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
500 {
501         int ret = MM_ERROR_NONE;
502         char *stream_type_str = NULL;
503         char *extra_info_str = NULL;
504         int option = 0;
505         bool is_focus_cb_thread = false;
506
507         LOGI(">> enter");
508
509         SM_NULL_ARG_CHECK(acquired_by);
510         SM_NULL_ARG_CHECK(flags);
511
512         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
513                 return _convert_sound_manager_error_code(__func__, ret);
514
515         if (is_focus_cb_thread) {
516                 LOGE("this API should not be called in focus callback");
517                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
518         }
519
520         ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
521         if (ret == MM_ERROR_NONE) {
522                 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
523                 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
524                 if (ret == MM_ERROR_NONE) {
525                         LOGI("                                 : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
526                         *flags = option;
527                         if (extra_info)
528                                 *extra_info = extra_info_str;
529                         else
530                                 free(extra_info_str);
531                 }
532         }
533
534         return _convert_sound_manager_error_code(__func__, ret);
535 }
536
537 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)
538 {
539         int ret = MM_ERROR_NONE;
540         int i = 0;
541
542         LOGI(">> enter");
543
544         SM_NULL_ARG_CHECK(callback);
545         SM_NULL_ARG_CHECK(id);
546         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
547
548         for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
549                 if (focus_watch_info_arr[i].id == 0)
550                         break;
551         if (i == SOUND_STREAM_INFO_ARR_MAX) {
552                 LOGE("focus watch info array is full");
553                 ret = MM_ERROR_SOUND_INTERNAL;
554                 goto LEAVE;
555         }
556
557         ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, id);
558         if (ret == MM_ERROR_NONE) {
559                 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
560                 focus_watch_info_arr[i].id = *id;
561                 focus_watch_info_arr[i].user_data = user_data;
562                 focus_watch_info_arr[i].user_cb = callback;
563         }
564
565 LEAVE:
566         SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
567
568         LOGD("cnt(%d), id(%d)", g_stream_info_count, *id);
569
570         return _convert_sound_manager_error_code(__func__, ret);
571 }
572
573 int sound_manager_remove_focus_state_watch_cb(int id)
574 {
575         int ret = MM_ERROR_NONE;
576         int i = 0;
577
578         LOGI(">> enter");
579
580         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
581
582         for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
583                 if (focus_watch_info_arr[i].id == id)
584                         break;
585         if (i == SOUND_STREAM_INFO_ARR_MAX) {
586                 LOGE("cound not find item in focus watch info array for this id(%d)", id);
587                 ret = MM_ERROR_INVALID_ARGUMENT;
588                 goto LEAVE;
589         }
590
591         ret = mm_sound_unset_focus_watch_callback(id);
592         if (ret == MM_ERROR_NONE) {
593                 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
594                 focus_watch_info_arr[i].id = 0;
595                 focus_watch_info_arr[i].user_data = NULL;
596                 focus_watch_info_arr[i].user_cb = NULL;
597         }
598
599 LEAVE:
600         SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
601
602         LOGD("cnt(%d)", g_stream_info_count);
603
604         return _convert_sound_manager_error_code(__func__, ret);
605 }
606
607 int sound_manager_set_session_type(sound_session_type_e type)
608 {
609         int ret = MM_ERROR_NONE;
610         int cur_session = -1;
611         int new_session = MM_SESSION_TYPE_MEDIA;
612         bool mic_enable = false;
613
614         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
615         LOGI(">> enter : type=%d", type);
616
617         if (type < SOUND_SESSION_TYPE_MEDIA || type >  SOUND_SESSION_TYPE_VOIP)
618                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
619
620         /* If session type is VOIP but MIC is not enabled, return false */
621         if (type == SOUND_SESSION_TYPE_VOIP) {
622                 ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
623                 LOGI("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
624                 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
625                         return _convert_sound_manager_error_code(__func__, MM_ERROR_NOT_SUPPORT_API);
626         }
627
628         /* it is not supported both session and stream feature at the same time */
629         if (g_stream_info_count) {
630                 LOGE("Could not set this type(%d) because of being used stream feature", type);
631                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
632         }
633
634         switch (type) {
635         case SOUND_SESSION_TYPE_MEDIA:
636                 new_session = MM_SESSION_TYPE_MEDIA;
637                 break;
638         case SOUND_SESSION_TYPE_ALARM:
639                 new_session = MM_SESSION_TYPE_ALARM;
640                 break;
641         case SOUND_SESSION_TYPE_NOTIFICATION:
642                 new_session = MM_SESSION_TYPE_NOTIFY;
643                 break;
644         case SOUND_SESSION_TYPE_EMERGENCY:
645                 new_session = MM_SESSION_TYPE_EMERGENCY;
646                 break;
647         case SOUND_SESSION_TYPE_VOIP:
648                 new_session = MM_SESSION_TYPE_VOIP;
649                 break;
650         }
651
652         /* valid session check */
653         ret = mm_session_get_current_type(&cur_session);
654         if (ret == MM_ERROR_NONE) {
655                 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
656                         if (type > SOUND_SESSION_TYPE_MEDIA) {
657                                 LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
658                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
659                         }
660                 }
661         }
662
663         if (g_session_interrupt_cb_table.is_registered) {
664                 if (new_session == cur_session ||
665                         ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
666                         LOGI("already set type=%d, ret=0x%x", type, ret);
667                         return SOUND_MANAGER_ERROR_NONE;
668                 } else {
669                         ret = mm_session_finish();
670                         if (ret != MM_ERROR_NONE)
671                                 return _convert_sound_manager_error_code(__func__, ret);
672
673                         g_session_interrupt_cb_table.is_registered = 0;
674                         if (cur_session == MM_SESSION_TYPE_VOIP) {
675                                 g_cached_session_mode = -1;
676                                 g_cached_voip_device_id = -1;
677                                 if (g_voip_vstream_h) {
678                                         _stop_virtual_stream(g_voip_vstream_h);
679                                         _destroy_virtual_stream(g_voip_vstream_h);
680                                         g_voip_vstream_h = NULL;
681                                 }
682                                 /*voip stream destruction*/
683                                 if (g_voip_stream_info) {
684                                         ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
685                                         free(g_voip_stream_info);
686                                         g_voip_stream_info = NULL;
687                                         if (ret != MM_ERROR_NONE)
688                                                 return _convert_sound_manager_error_code(__func__, ret);
689                                 }
690                         }
691                 }
692         }
693         ret = mm_session_init(new_session);
694         if (ret == MM_ERROR_NONE)
695                 g_session_interrupt_cb_table.is_registered = 1;
696
697         LOGI("type=%d", type);
698
699         return _convert_sound_manager_error_code(__func__, ret);
700 }
701
702 int sound_manager_get_session_type(sound_session_type_e *type)
703 {
704         int ret = MM_ERROR_NONE;
705         int cur_session;
706
707         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
708         if (type == NULL)
709                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
710
711         ret = mm_session_get_current_type(&cur_session);
712         if (ret != MM_ERROR_NONE) {
713                 LOGW("session hasn't been set, setting default session");
714                 cur_session = SOUND_SESSION_TYPE_DEFAULT;
715                 ret = mm_session_init(cur_session);
716                 if (ret == MM_ERROR_NONE)
717                         g_session_interrupt_cb_table.is_registered = 1;
718         }
719         if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
720                         (cur_session != MM_SESSION_TYPE_VOIP)) {
721                 if (g_cached_session != -1)
722                         cur_session = g_cached_session;
723                 else /* will be never reached here. just prevent code */
724                         cur_session = SOUND_SESSION_TYPE_DEFAULT;
725         }
726
727         switch (cur_session) {
728         case MM_SESSION_TYPE_MEDIA:
729         case MM_SESSION_TYPE_MEDIA_RECORD:
730                 *type = SOUND_SESSION_TYPE_MEDIA;
731                 break;
732         case MM_SESSION_TYPE_ALARM:
733                 *type = SOUND_SESSION_TYPE_ALARM;
734                 break;
735         case MM_SESSION_TYPE_NOTIFY:
736                 *type = SOUND_SESSION_TYPE_NOTIFICATION;
737                 break;
738         case MM_SESSION_TYPE_EMERGENCY:
739                 *type = SOUND_SESSION_TYPE_EMERGENCY;
740                 break;
741         case MM_SESSION_TYPE_VOIP:
742                 *type = SOUND_SESSION_TYPE_VOIP;
743                 break;
744         default:
745                 *type = cur_session;
746                 break;
747         }
748
749         LOGI("type=%d", *type);
750
751         return SOUND_MANAGER_ERROR_NONE;
752 }
753
754 int sound_manager_set_media_session_option(sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
755 {
756         int ret = MM_ERROR_NONE;
757         int session = 0;
758         int session_option = 0;
759         int updated = 0;
760
761         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
762         LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
763
764         if (s_option < 0 || s_option >  SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
765                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
766         if (d_option < 0 || d_option >  SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
767                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
768
769         ret = mm_session_get_current_information(&session, &session_option);
770         if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
771                 LOGW("session hasn't been set, setting default session");
772                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
773                 if (ret == 0)
774                         g_session_interrupt_cb_table.is_registered = 1;
775
776         } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
777                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
778                         if (!g_session_interrupt_cb_table.is_registered) {
779                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
780                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
781                         }
782                 } else {
783                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
784                 }
785         }
786
787         switch (s_option) {
788         case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
789                 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
790                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
791                         if (ret)
792                                 return _convert_sound_manager_error_code(__func__, ret);
793
794                         updated = 1;
795                 }
796                 break;
797         case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
798                 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
799                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
800                         if (ret)
801                                 return _convert_sound_manager_error_code(__func__, ret);
802
803                         updated = 1;
804                 }
805                 break;
806         }
807
808         switch (d_option) {
809         case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
810                 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
811                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
812                         if (ret)
813                                 return _convert_sound_manager_error_code(__func__, ret);
814
815                         updated = 1;
816                 }
817                 break;
818         case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
819                 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
820                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
821                         if (ret)
822                                 return _convert_sound_manager_error_code(__func__, ret);
823
824                         updated = 1;
825                 }
826                 break;
827         }
828
829         if (updated)
830                 LOGI("updated");
831         else
832                 LOGI("already set same option(%x), skip it", session_option);
833
834         return _convert_sound_manager_error_code(__func__, ret);
835 }
836
837 int sound_manager_get_media_session_option(sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
838 {
839         int ret = MM_ERROR_NONE;
840         int session = 0;
841         int session_options = 0;
842
843         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
844         LOGI(">> enter");
845
846         if (s_option == NULL || d_option == NULL)
847                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
848
849         ret = mm_session_get_current_information(&session, &session_options);
850         if (ret != 0) {
851                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
852                 if (ret == 0)
853                         g_session_interrupt_cb_table.is_registered = 1;
854
855         } else if (session > SOUND_SESSION_TYPE_MEDIA) {
856                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
857                         if (!g_session_interrupt_cb_table.is_registered) {
858                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
859                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
860                         }
861                 } else
862                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
863         }
864         /* get option */
865         if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS)
866                 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
867         else
868                 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
869
870         if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
871                 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
872         else
873                 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
874
875         LOGI(" option for starting=%d, for during play=%d", *s_option, *d_option);
876
877         return SOUND_MANAGER_ERROR_NONE;
878 }
879
880 int sound_manager_set_media_session_resumption_option(sound_session_option_for_resumption_e option)
881 {
882         int ret = MM_ERROR_NONE;
883         int session = 0;
884         int session_option = 0;
885         int updated = 0;
886
887         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
888         LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
889
890         if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
891                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
892
893         ret = mm_session_get_current_information(&session, &session_option);
894         if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
895                 LOGW("session hasn't been set, setting default session");
896                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
897                 if (ret == 0)
898                         g_session_interrupt_cb_table.is_registered = 1;
899
900         } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
901                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
902                         if (!g_session_interrupt_cb_table.is_registered) {
903                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
904                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
905                         }
906                 } else
907                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
908
909         }
910
911         switch (option) {
912         case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
913                 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
914                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
915                         if (ret)
916                                 return _convert_sound_manager_error_code(__func__, ret);
917
918                         updated = 1;
919                 }
920                 break;
921         case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
922                 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
923                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
924                         if (ret)
925                                 return _convert_sound_manager_error_code(__func__, ret);
926
927                         updated = 1;
928                 }
929                 break;
930         }
931
932         if (updated)
933                 LOGI("updated");
934         else
935                 LOGI("already set same option(0x%x), skip it", session_option);
936
937         return _convert_sound_manager_error_code(__func__, ret);
938 }
939
940 int sound_manager_get_media_session_resumption_option(sound_session_option_for_resumption_e *option)
941 {
942         int ret = MM_ERROR_NONE;
943         int session = 0;
944         int session_options = 0;
945
946         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
947         LOGI(">> enter");
948
949         if (option == NULL)
950                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
951
952         ret = mm_session_get_current_information(&session, &session_options);
953         if (ret != 0) {
954                 LOGW("session hasn't been set, setting default session");
955                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
956                 if (ret == 0)
957                         g_session_interrupt_cb_table.is_registered = 1;
958
959         } else if (session > SOUND_SESSION_TYPE_MEDIA) {
960                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
961                         if (!g_session_interrupt_cb_table.is_registered) {
962                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
963                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
964                         }
965                 } else
966                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
967         }
968         /* get option */
969         if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)
970                 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
971         else
972                 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
973
974         LOGI("option for resumption=%d (0:by system, 1:by system or media paused)", *option);
975
976         return SOUND_MANAGER_ERROR_NONE;
977 }
978
979 int sound_manager_set_voip_session_mode(sound_session_voip_mode_e mode)
980 {
981         int ret = MM_ERROR_NONE;
982         int session = 0;
983         int session_options = 0;
984
985         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
986         LOGI(">> enter : mode=%d", mode);
987
988         ret = mm_session_get_current_information(&session, &session_options);
989         if (ret != MM_ERROR_NONE)
990                 goto LEAVE;
991
992         if (session != MM_SESSION_TYPE_VOIP) {
993                 ret = MM_ERROR_POLICY_INTERNAL;
994                 goto LEAVE;
995         }
996
997         if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
998                 ret = MM_ERROR_INVALID_ARGUMENT;
999                 goto LEAVE;
1000         }
1001
1002         ret = _set_session_mode((_session_mode_e)mode);
1003
1004         LOGI("session=%d, mode=%d", session, mode);
1005
1006 LEAVE:
1007         return _convert_sound_manager_error_code(__func__, ret);
1008 }
1009
1010 int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
1011 {
1012         int ret = MM_ERROR_NONE;
1013         int session = 0;
1014         int session_options = 0;
1015
1016         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1017         if (mode == NULL) {
1018                 LOGE("mode is null");
1019                 ret = MM_ERROR_INVALID_ARGUMENT;
1020                 goto LEAVE;
1021         }
1022
1023         ret = mm_session_get_current_information(&session, &session_options);
1024         if (ret != MM_ERROR_NONE) {
1025                 LOGI("session = %d, option = %d", session, session_options);
1026                 goto LEAVE;
1027         }
1028
1029         if (session != MM_SESSION_TYPE_VOIP || g_cached_session_mode == -1) {
1030                 ret = MM_ERROR_POLICY_INTERNAL;
1031                 goto LEAVE;
1032         }
1033
1034         *mode = (sound_session_voip_mode_e)g_cached_session_mode;
1035
1036         LOGI("session=%d, mode=%d", session, *mode);
1037
1038 LEAVE:
1039         return _convert_sound_manager_error_code(__func__, ret);
1040 }
1041
1042 int sound_manager_set_session_interrupted_cb(sound_session_interrupted_cb callback, void *user_data)
1043 {
1044         int ret = MM_ERROR_NONE;
1045         unsigned int subs_id = 0;
1046
1047         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1048         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1049
1050         if (callback == NULL) {
1051                 ret = MM_ERROR_INVALID_ARGUMENT;
1052                 goto LEAVE;
1053         }
1054
1055         /* it is not supported both session and stream feature at the same time */
1056         if (g_stream_info_count) {
1057                 ret =  MM_ERROR_POLICY_INTERNAL;
1058                 goto LEAVE;
1059         }
1060
1061         if (g_session_interrupt_cb_table.user_cb == NULL) {
1062                 ret = mm_sound_add_device_connected_callback(SOUND_DEVICE_ALL_MASK, (mm_sound_device_connected_cb)_device_connected_cb, NULL, &subs_id);
1063                 if (ret)
1064                         goto LEAVE;
1065                 ret = mm_sound_focus_set_session_interrupt_callback((mm_sound_focus_session_interrupt_cb)_focus_session_interrupt_cb, NULL);
1066                 if (ret) {
1067                         if (mm_sound_remove_device_connected_callback(subs_id) != MM_ERROR_NONE)
1068                                 LOGW("mm_sound_remove_device_connected_callback failed");
1069                         goto LEAVE;
1070                 }
1071                 g_session_interrupt_cb_table.subs_id = subs_id;
1072         }
1073         g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
1074         g_session_interrupt_cb_table.user_data = user_data;
1075
1076 LEAVE:
1077         SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1078
1079         return _convert_sound_manager_error_code(__func__, ret);
1080 }
1081
1082 int sound_manager_unset_session_interrupted_cb(void)
1083 {
1084         int ret = MM_ERROR_NONE;
1085
1086         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1087         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1088
1089         if (!g_session_interrupt_cb_table.user_cb) {
1090                 ret = MM_ERROR_SOUND_INTERNAL;
1091                 goto LEAVE;
1092         }
1093
1094         ret = mm_sound_focus_unset_session_interrupt_callback();
1095         if (ret) {
1096                 if (mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id) != MM_ERROR_NONE)
1097                         LOGW("mm_sound_remove_device_connected_callback failed");
1098                 goto LEAVE;
1099         }
1100
1101         ret = mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id);
1102         if (ret)
1103                 goto LEAVE;
1104
1105         g_session_interrupt_cb_table.subs_id = 0;
1106         g_session_interrupt_cb_table.user_cb = NULL;
1107         g_session_interrupt_cb_table.user_data = NULL;
1108
1109 LEAVE:
1110         SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1111
1112         return _convert_sound_manager_error_code(__func__, ret);
1113 }
1114
1115 int sound_manager_get_current_device_list(sound_device_mask_e device_mask, sound_device_list_h *device_list)
1116 {
1117         int ret = MM_ERROR_NONE;
1118
1119         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_get_device_list() instead.", __func__);
1120         ret = mm_sound_get_current_device_list(device_mask, device_list);
1121
1122         return _convert_sound_manager_error_code(__func__, ret);
1123 }
1124
1125 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
1126 {
1127         int ret = MM_ERROR_NONE;
1128
1129         ret = mm_sound_get_device_list(device_mask, device_list);
1130
1131         return _convert_sound_manager_error_code(__func__, ret);
1132 }
1133
1134 int sound_manager_free_device_list(sound_device_list_h device_list)
1135 {
1136         int ret = MM_ERROR_NONE;
1137
1138         ret = mm_sound_free_device_list(device_list);
1139
1140         return _convert_sound_manager_error_code(__func__, ret);
1141 }
1142
1143 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
1144 {
1145         int ret = MM_ERROR_NONE;
1146
1147         ret = mm_sound_get_next_device(device_list, device);
1148
1149         return _convert_sound_manager_error_code(__func__, ret);
1150 }
1151
1152 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
1153 {
1154         int ret = MM_ERROR_NONE;
1155
1156         ret = mm_sound_get_prev_device(device_list, device);
1157
1158         return _convert_sound_manager_error_code(__func__, ret);
1159 }
1160
1161 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
1162 {
1163         int ret = MM_ERROR_NONE;
1164         mm_sound_device_type_e mm_sound_device_type;
1165
1166         ret = mm_sound_get_device_type(device, &mm_sound_device_type);
1167         if (ret == MM_ERROR_NONE)
1168                 _convert_device_type(mm_sound_device_type, type);
1169
1170         return _convert_sound_manager_error_code(__func__, ret);
1171 }
1172
1173 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
1174 {
1175         int ret = MM_ERROR_NONE;
1176         mm_sound_device_io_direction_e mm_sound_io_direction;
1177
1178         ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
1179         if (ret == MM_ERROR_NONE)
1180                 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
1181
1182         return _convert_sound_manager_error_code(__func__, ret);
1183 }
1184
1185 int sound_manager_get_device_id(sound_device_h device, int *id)
1186 {
1187         int ret = MM_ERROR_NONE;
1188
1189         ret = mm_sound_get_device_id(device, id);
1190
1191         return _convert_sound_manager_error_code(__func__, ret);
1192 }
1193
1194 int sound_manager_get_device_name(sound_device_h device, char **name)
1195 {
1196         int ret = MM_ERROR_NONE;
1197
1198         ret = mm_sound_get_device_name(device, name);
1199
1200         return _convert_sound_manager_error_code(__func__, ret);
1201 }
1202
1203 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
1204 {
1205         int ret = MM_ERROR_NONE;
1206
1207         ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1208
1209         return _convert_sound_manager_error_code(__func__, ret);
1210 }
1211
1212 int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1213 {
1214         int ret = MM_ERROR_NONE;
1215         unsigned int subs_id = 0;
1216
1217         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1218                 "Use sound_manager_add_device_connection_changed_cb() instead.", __func__);
1219
1220         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1221
1222         ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, &subs_id);
1223         if (ret == MM_ERROR_NONE) {
1224                 g_device_connected_cb_table.subs_id = subs_id;
1225                 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1226                 g_device_connected_cb_table.user_data = user_data;
1227         }
1228
1229         SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1230
1231         return _convert_sound_manager_error_code(__func__, ret);
1232 }
1233
1234 int sound_manager_unset_device_connected_cb(void)
1235 {
1236         int ret = MM_ERROR_NONE;
1237
1238         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1239                 "Use sound_manager_remove_device_connection_changed_cb() instead.", __func__);
1240
1241         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1242
1243         if (g_device_connected_cb_table.subs_id == 0) {
1244                 ret = MM_ERROR_SOUND_INTERNAL;
1245                 goto LEAVE;
1246         }
1247
1248         ret = mm_sound_remove_device_connected_callback(g_device_connected_cb_table.subs_id);
1249         if (ret == MM_ERROR_NONE) {
1250                 g_device_connected_cb_table.subs_id = 0;
1251                 g_device_connected_cb_table.user_cb = NULL;
1252                 g_device_connected_cb_table.user_data = NULL;
1253         }
1254
1255 LEAVE:
1256         SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1257
1258         return _convert_sound_manager_error_code(__func__, ret);
1259 }
1260
1261 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connected_cb callback, void *user_data, int *id)
1262 {
1263         int ret = MM_ERROR_NONE;
1264
1265         if (!callback || !id)
1266                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1267
1268         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);
1269
1270         return _convert_sound_manager_error_code(__func__, ret);
1271 }
1272
1273 int sound_manager_remove_device_connection_changed_cb(int id)
1274 {
1275         int ret = MM_ERROR_NONE;
1276
1277         if (id < 0)
1278                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1279
1280         ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1281
1282         return _convert_sound_manager_error_code(__func__, ret);
1283 }
1284
1285 int sound_manager_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1286 {
1287         int ret = MM_ERROR_NONE;
1288         unsigned int subs_id = 0;
1289
1290         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1291                 "Use sound_manager_add_device_state_changed_cb() instead.", __func__);
1292         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1293
1294         ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data, &subs_id);
1295         if (ret == MM_ERROR_NONE) {
1296                 g_device_info_changed_cb_table.subs_id = subs_id;
1297                 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1298                 g_device_info_changed_cb_table.user_data = user_data;
1299         }
1300
1301         SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1302
1303         return _convert_sound_manager_error_code(__func__, ret);
1304 }
1305
1306 int sound_manager_unset_device_information_changed_cb(void)
1307 {
1308         int ret = MM_ERROR_NONE;
1309
1310         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1311                 "Use sound_manager_remove_device_state_changed_cb() instead.", __func__);
1312         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1313
1314         if (g_device_info_changed_cb_table.subs_id == 0) {
1315                 ret = MM_ERROR_SOUND_INTERNAL;
1316                 goto LEAVE;
1317         }
1318
1319         ret = mm_sound_remove_device_information_changed_callback(g_device_info_changed_cb_table.subs_id);
1320         if (ret == MM_ERROR_NONE) {
1321                 g_device_info_changed_cb_table.subs_id = 0;
1322                 g_device_info_changed_cb_table.user_cb = NULL;
1323                 g_device_info_changed_cb_table.user_data = NULL;
1324         }
1325
1326 LEAVE:
1327         SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1328
1329         return _convert_sound_manager_error_code(__func__, ret);
1330 }
1331
1332 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1333 {
1334         int ret = MM_ERROR_NONE;
1335
1336         if (!callback || !id)
1337                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1338
1339         ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
1340
1341         return _convert_sound_manager_error_code(__func__, ret);
1342 }
1343
1344 int sound_manager_remove_device_state_changed_cb(int id)
1345 {
1346         int ret = MM_ERROR_NONE;
1347
1348         if (id < 0)
1349                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1350
1351         ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
1352
1353         return _convert_sound_manager_error_code(__func__, ret);
1354 }
1355
1356 __attribute__ ((destructor))
1357 void __sound_manager_finalize(void)
1358 {
1359         int ret = MM_ERROR_NONE;
1360
1361         if (g_session_interrupt_cb_table.is_registered) {
1362                 LOGI("<ENTER>");
1363                 ret = mm_session_finish();
1364                 if (ret != MM_ERROR_NONE)
1365                         LOGE("[%s] failed to mm_session_finish(), ret(0x%x)", __func__, ret);
1366
1367                 g_session_interrupt_cb_table.is_registered = 0;
1368                 LOGI("<LEAVE>");
1369         }
1370 }
1371
1372 __attribute__ ((constructor))
1373 void __sound_manager_initialize(void)
1374 {
1375
1376 }