Disable _get_current_media_routing_path() temporally.
[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 #if 0
443         ret = mm_sound_get_device_id(device, &device_id);
444         if (ret == MM_ERROR_NONE)
445                 ret = _is_using_device(stream_h->index, device_id, is_on);
446
447         if (ret == MM_ERROR_NONE)
448                 LOGI("stream info index(%u), device_id(%d), is_on(%d)", stream_h->index, device_id, *is_on);
449 #endif
450         return _convert_sound_manager_error_code(__func__, ret);
451 }
452
453 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
454 {
455         int ret = MM_ERROR_NONE;
456 #if 0
457         char *device_type_str = NULL;
458 #endif
459
460         LOGI(">> enter");
461
462         SM_NULL_ARG_CHECK(device_type);
463
464 #if 0
465         ret = _get_current_media_routing_path("out", &device_type_str);
466         if (ret == MM_ERROR_NONE)
467                 ret = _convert_device_type_str_to_enum(device_type_str, device_type);
468 #endif
469
470         return _convert_sound_manager_error_code(__func__, ret);
471 }
472
473 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
474 {
475         int ret = MM_ERROR_NONE;
476         char *stream_type_str = NULL;
477         char *extra_info_str = NULL;
478         int option = 0;
479         bool is_focus_cb_thread = false;
480
481         LOGI(">> enter");
482
483         SM_NULL_ARG_CHECK(acquired_by);
484         SM_NULL_ARG_CHECK(flags);
485
486         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
487                 return _convert_sound_manager_error_code(__func__, ret);
488
489         if (is_focus_cb_thread) {
490                 LOGE("this API should not be called in focus callback");
491                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
492         }
493
494         ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
495         if (ret == MM_ERROR_NONE) {
496                 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
497                 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
498                 if (ret == MM_ERROR_NONE) {
499                         LOGI("                                : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
500                         *flags = option;
501                         if (extra_info)
502                                 *extra_info = extra_info_str;
503                         else
504                                 free(extra_info_str);
505                 }
506         }
507
508         return _convert_sound_manager_error_code(__func__, ret);
509 }
510
511 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
512 {
513         int ret = MM_ERROR_NONE;
514         char *stream_type_str = NULL;
515         char *extra_info_str = NULL;
516         int option = 0;
517         bool is_focus_cb_thread = false;
518
519         LOGI(">> enter");
520
521         SM_NULL_ARG_CHECK(acquired_by);
522         SM_NULL_ARG_CHECK(flags);
523
524         if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
525                 return _convert_sound_manager_error_code(__func__, ret);
526
527         if (is_focus_cb_thread) {
528                 LOGE("this API should not be called in focus callback");
529                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
530         }
531
532         ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
533         if (ret == MM_ERROR_NONE) {
534                 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
535                 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
536                 if (ret == MM_ERROR_NONE) {
537                         LOGI("                                 : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
538                         *flags = option;
539                         if (extra_info)
540                                 *extra_info = extra_info_str;
541                         else
542                                 free(extra_info_str);
543                 }
544         }
545
546         return _convert_sound_manager_error_code(__func__, ret);
547 }
548
549 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)
550 {
551         int ret = MM_ERROR_NONE;
552         int i = 0;
553
554         LOGI(">> enter");
555
556         SM_NULL_ARG_CHECK(callback);
557         SM_NULL_ARG_CHECK(id);
558         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
559
560         for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
561                 if (focus_watch_info_arr[i].id == 0)
562                         break;
563         if (i == SOUND_STREAM_INFO_ARR_MAX) {
564                 LOGE("focus watch info array is full");
565                 ret = MM_ERROR_SOUND_INTERNAL;
566                 goto LEAVE;
567         }
568
569         ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, id);
570         if (ret == MM_ERROR_NONE) {
571                 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
572                 focus_watch_info_arr[i].id = *id;
573                 focus_watch_info_arr[i].user_data = user_data;
574                 focus_watch_info_arr[i].user_cb = callback;
575         }
576
577 LEAVE:
578         SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
579
580         LOGD("cnt(%d), id(%d)", g_stream_info_count, *id);
581
582         return _convert_sound_manager_error_code(__func__, ret);
583 }
584
585 int sound_manager_remove_focus_state_watch_cb(int id)
586 {
587         int ret = MM_ERROR_NONE;
588         int i = 0;
589
590         LOGI(">> enter");
591
592         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
593
594         for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
595                 if (focus_watch_info_arr[i].id == id)
596                         break;
597         if (i == SOUND_STREAM_INFO_ARR_MAX) {
598                 LOGE("cound not find item in focus watch info array for this id(%d)", id);
599                 ret = MM_ERROR_INVALID_ARGUMENT;
600                 goto LEAVE;
601         }
602
603         ret = mm_sound_unset_focus_watch_callback(id);
604         if (ret == MM_ERROR_NONE) {
605                 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
606                 focus_watch_info_arr[i].id = 0;
607                 focus_watch_info_arr[i].user_data = NULL;
608                 focus_watch_info_arr[i].user_cb = NULL;
609         }
610
611 LEAVE:
612         SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
613
614         LOGD("cnt(%d)", g_stream_info_count);
615
616         return _convert_sound_manager_error_code(__func__, ret);
617 }
618
619 int sound_manager_set_session_type(sound_session_type_e type)
620 {
621         int ret = MM_ERROR_NONE;
622         int cur_session = -1;
623         int new_session = MM_SESSION_TYPE_MEDIA;
624         bool mic_enable = false;
625
626         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
627         LOGI(">> enter : type=%d", type);
628
629         if (type < SOUND_SESSION_TYPE_MEDIA || type >  SOUND_SESSION_TYPE_VOIP)
630                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
631
632         /* If session type is VOIP but MIC is not enabled, return false */
633         if (type == SOUND_SESSION_TYPE_VOIP) {
634                 ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
635                 LOGI("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
636                 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
637                         return _convert_sound_manager_error_code(__func__, MM_ERROR_NOT_SUPPORT_API);
638         }
639
640         /* it is not supported both session and stream feature at the same time */
641         if (g_stream_info_count) {
642                 LOGE("Could not set this type(%d) because of being used stream feature", type);
643                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
644         }
645
646         switch (type) {
647         case SOUND_SESSION_TYPE_MEDIA:
648                 new_session = MM_SESSION_TYPE_MEDIA;
649                 break;
650         case SOUND_SESSION_TYPE_ALARM:
651                 new_session = MM_SESSION_TYPE_ALARM;
652                 break;
653         case SOUND_SESSION_TYPE_NOTIFICATION:
654                 new_session = MM_SESSION_TYPE_NOTIFY;
655                 break;
656         case SOUND_SESSION_TYPE_EMERGENCY:
657                 new_session = MM_SESSION_TYPE_EMERGENCY;
658                 break;
659         case SOUND_SESSION_TYPE_VOIP:
660                 new_session = MM_SESSION_TYPE_VOIP;
661                 break;
662         }
663
664         /* valid session check */
665         ret = mm_session_get_current_type(&cur_session);
666         if (ret == MM_ERROR_NONE) {
667                 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
668                         if (type > SOUND_SESSION_TYPE_MEDIA) {
669                                 LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
670                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
671                         }
672                 }
673         }
674
675         if (g_session_interrupt_cb_table.is_registered) {
676                 if (new_session == cur_session ||
677                         ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
678                         LOGI("already set type=%d, ret=0x%x", type, ret);
679                         return SOUND_MANAGER_ERROR_NONE;
680                 } else {
681                         ret = mm_session_finish();
682                         if (ret != MM_ERROR_NONE)
683                                 return _convert_sound_manager_error_code(__func__, ret);
684
685                         g_session_interrupt_cb_table.is_registered = 0;
686                         if (cur_session == MM_SESSION_TYPE_VOIP) {
687                                 g_cached_session_mode = -1;
688                                 g_cached_voip_device_id = -1;
689                                 if (g_voip_vstream_h) {
690                                         _stop_virtual_stream(g_voip_vstream_h);
691                                         _destroy_virtual_stream(g_voip_vstream_h);
692                                         g_voip_vstream_h = NULL;
693                                 }
694                                 /*voip stream destruction*/
695                                 if (g_voip_stream_info) {
696                                         ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
697                                         free(g_voip_stream_info);
698                                         g_voip_stream_info = NULL;
699                                         if (ret != MM_ERROR_NONE)
700                                                 return _convert_sound_manager_error_code(__func__, ret);
701                                 }
702                         }
703                 }
704         }
705         ret = mm_session_init(new_session);
706         if (ret == MM_ERROR_NONE)
707                 g_session_interrupt_cb_table.is_registered = 1;
708
709         LOGI("type=%d", type);
710
711         return _convert_sound_manager_error_code(__func__, ret);
712 }
713
714 int sound_manager_get_session_type(sound_session_type_e *type)
715 {
716         int ret = MM_ERROR_NONE;
717         int cur_session;
718
719         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
720         if (type == NULL)
721                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
722
723         ret = mm_session_get_current_type(&cur_session);
724         if (ret != MM_ERROR_NONE) {
725                 LOGW("session hasn't been set, setting default session");
726                 cur_session = SOUND_SESSION_TYPE_DEFAULT;
727                 ret = mm_session_init(cur_session);
728                 if (ret == MM_ERROR_NONE)
729                         g_session_interrupt_cb_table.is_registered = 1;
730         }
731         if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
732                         (cur_session != MM_SESSION_TYPE_VOIP)) {
733                 if (g_cached_session != -1)
734                         cur_session = g_cached_session;
735                 else /* will be never reached here. just prevent code */
736                         cur_session = SOUND_SESSION_TYPE_DEFAULT;
737         }
738
739         switch (cur_session) {
740         case MM_SESSION_TYPE_MEDIA:
741         case MM_SESSION_TYPE_MEDIA_RECORD:
742                 *type = SOUND_SESSION_TYPE_MEDIA;
743                 break;
744         case MM_SESSION_TYPE_ALARM:
745                 *type = SOUND_SESSION_TYPE_ALARM;
746                 break;
747         case MM_SESSION_TYPE_NOTIFY:
748                 *type = SOUND_SESSION_TYPE_NOTIFICATION;
749                 break;
750         case MM_SESSION_TYPE_EMERGENCY:
751                 *type = SOUND_SESSION_TYPE_EMERGENCY;
752                 break;
753         case MM_SESSION_TYPE_VOIP:
754                 *type = SOUND_SESSION_TYPE_VOIP;
755                 break;
756         default:
757                 *type = cur_session;
758                 break;
759         }
760
761         LOGI("type=%d", *type);
762
763         return SOUND_MANAGER_ERROR_NONE;
764 }
765
766 int sound_manager_set_media_session_option(sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
767 {
768         int ret = MM_ERROR_NONE;
769         int session = 0;
770         int session_option = 0;
771         int updated = 0;
772
773         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
774         LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
775
776         if (s_option < 0 || s_option >  SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
777                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
778         if (d_option < 0 || d_option >  SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
779                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
780
781         ret = mm_session_get_current_information(&session, &session_option);
782         if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
783                 LOGW("session hasn't been set, setting default session");
784                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
785                 if (ret == 0)
786                         g_session_interrupt_cb_table.is_registered = 1;
787
788         } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
789                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
790                         if (!g_session_interrupt_cb_table.is_registered) {
791                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
792                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
793                         }
794                 } else {
795                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
796                 }
797         }
798
799         switch (s_option) {
800         case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
801                 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
802                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
803                         if (ret)
804                                 return _convert_sound_manager_error_code(__func__, ret);
805
806                         updated = 1;
807                 }
808                 break;
809         case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
810                 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
811                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
812                         if (ret)
813                                 return _convert_sound_manager_error_code(__func__, ret);
814
815                         updated = 1;
816                 }
817                 break;
818         }
819
820         switch (d_option) {
821         case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
822                 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
823                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
824                         if (ret)
825                                 return _convert_sound_manager_error_code(__func__, ret);
826
827                         updated = 1;
828                 }
829                 break;
830         case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
831                 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
832                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
833                         if (ret)
834                                 return _convert_sound_manager_error_code(__func__, ret);
835
836                         updated = 1;
837                 }
838                 break;
839         }
840
841         if (updated)
842                 LOGI("updated");
843         else
844                 LOGI("already set same option(%x), skip it", session_option);
845
846         return _convert_sound_manager_error_code(__func__, ret);
847 }
848
849 int sound_manager_get_media_session_option(sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
850 {
851         int ret = MM_ERROR_NONE;
852         int session = 0;
853         int session_options = 0;
854
855         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
856         LOGI(">> enter");
857
858         if (s_option == NULL || d_option == NULL)
859                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
860
861         ret = mm_session_get_current_information(&session, &session_options);
862         if (ret != 0) {
863                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
864                 if (ret == 0)
865                         g_session_interrupt_cb_table.is_registered = 1;
866
867         } else if (session > SOUND_SESSION_TYPE_MEDIA) {
868                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
869                         if (!g_session_interrupt_cb_table.is_registered) {
870                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
871                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
872                         }
873                 } else
874                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
875         }
876         /* get option */
877         if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS)
878                 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
879         else
880                 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
881
882         if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
883                 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
884         else
885                 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
886
887         LOGI(" option for starting=%d, for during play=%d", *s_option, *d_option);
888
889         return SOUND_MANAGER_ERROR_NONE;
890 }
891
892 int sound_manager_set_media_session_resumption_option(sound_session_option_for_resumption_e option)
893 {
894         int ret = MM_ERROR_NONE;
895         int session = 0;
896         int session_option = 0;
897         int updated = 0;
898
899         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
900         LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
901
902         if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
903                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
904
905         ret = mm_session_get_current_information(&session, &session_option);
906         if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
907                 LOGW("session hasn't been set, setting default session");
908                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
909                 if (ret == 0)
910                         g_session_interrupt_cb_table.is_registered = 1;
911
912         } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
913                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
914                         if (!g_session_interrupt_cb_table.is_registered) {
915                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
916                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
917                         }
918                 } else
919                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
920
921         }
922
923         switch (option) {
924         case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
925                 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
926                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
927                         if (ret)
928                                 return _convert_sound_manager_error_code(__func__, ret);
929
930                         updated = 1;
931                 }
932                 break;
933         case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
934                 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
935                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
936                         if (ret)
937                                 return _convert_sound_manager_error_code(__func__, ret);
938
939                         updated = 1;
940                 }
941                 break;
942         }
943
944         if (updated)
945                 LOGI("updated");
946         else
947                 LOGI("already set same option(0x%x), skip it", session_option);
948
949         return _convert_sound_manager_error_code(__func__, ret);
950 }
951
952 int sound_manager_get_media_session_resumption_option(sound_session_option_for_resumption_e *option)
953 {
954         int ret = MM_ERROR_NONE;
955         int session = 0;
956         int session_options = 0;
957
958         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
959         LOGI(">> enter");
960
961         if (option == NULL)
962                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
963
964         ret = mm_session_get_current_information(&session, &session_options);
965         if (ret != 0) {
966                 LOGW("session hasn't been set, setting default session");
967                 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
968                 if (ret == 0)
969                         g_session_interrupt_cb_table.is_registered = 1;
970
971         } else if (session > SOUND_SESSION_TYPE_MEDIA) {
972                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
973                         if (!g_session_interrupt_cb_table.is_registered) {
974                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
975                                 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
976                         }
977                 } else
978                         return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
979         }
980         /* get option */
981         if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)
982                 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
983         else
984                 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
985
986         LOGI("option for resumption=%d (0:by system, 1:by system or media paused)", *option);
987
988         return SOUND_MANAGER_ERROR_NONE;
989 }
990
991 int sound_manager_set_voip_session_mode(sound_session_voip_mode_e mode)
992 {
993         int ret = MM_ERROR_NONE;
994         int session = 0;
995         int session_options = 0;
996
997         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
998         LOGI(">> enter : mode=%d", mode);
999
1000         ret = mm_session_get_current_information(&session, &session_options);
1001         if (ret != MM_ERROR_NONE)
1002                 goto LEAVE;
1003
1004         if (session != MM_SESSION_TYPE_VOIP) {
1005                 ret = MM_ERROR_POLICY_INTERNAL;
1006                 goto LEAVE;
1007         }
1008
1009         if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
1010                 ret = MM_ERROR_INVALID_ARGUMENT;
1011                 goto LEAVE;
1012         }
1013
1014         ret = _set_session_mode((_session_mode_e)mode);
1015
1016         LOGI("session=%d, mode=%d", session, mode);
1017
1018 LEAVE:
1019         return _convert_sound_manager_error_code(__func__, ret);
1020 }
1021
1022 int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
1023 {
1024         int ret = MM_ERROR_NONE;
1025         int session = 0;
1026         int session_options = 0;
1027
1028         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1029         if (mode == NULL) {
1030                 LOGE("mode is null");
1031                 ret = MM_ERROR_INVALID_ARGUMENT;
1032                 goto LEAVE;
1033         }
1034
1035         ret = mm_session_get_current_information(&session, &session_options);
1036         if (ret != MM_ERROR_NONE) {
1037                 LOGI("session = %d, option = %d", session, session_options);
1038                 goto LEAVE;
1039         }
1040
1041         if (session != MM_SESSION_TYPE_VOIP || g_cached_session_mode == -1) {
1042                 ret = MM_ERROR_POLICY_INTERNAL;
1043                 goto LEAVE;
1044         }
1045
1046         *mode = (sound_session_voip_mode_e)g_cached_session_mode;
1047
1048         LOGI("session=%d, mode=%d", session, *mode);
1049
1050 LEAVE:
1051         return _convert_sound_manager_error_code(__func__, ret);
1052 }
1053
1054 int sound_manager_set_session_interrupted_cb(sound_session_interrupted_cb callback, void *user_data)
1055 {
1056         int ret = MM_ERROR_NONE;
1057         unsigned int subs_id = 0;
1058
1059         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1060         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1061
1062         if (callback == NULL) {
1063                 ret = MM_ERROR_INVALID_ARGUMENT;
1064                 goto LEAVE;
1065         }
1066
1067         /* it is not supported both session and stream feature at the same time */
1068         if (g_stream_info_count) {
1069                 ret =  MM_ERROR_POLICY_INTERNAL;
1070                 goto LEAVE;
1071         }
1072
1073         if (g_session_interrupt_cb_table.user_cb == NULL) {
1074                 ret = mm_sound_add_device_connected_callback(SOUND_DEVICE_ALL_MASK, (mm_sound_device_connected_cb)_device_connected_cb, NULL, &subs_id);
1075                 if (ret)
1076                         goto LEAVE;
1077                 ret = mm_sound_focus_set_session_interrupt_callback((mm_sound_focus_session_interrupt_cb)_focus_session_interrupt_cb, NULL);
1078                 if (ret) {
1079                         if (mm_sound_remove_device_connected_callback(subs_id) != MM_ERROR_NONE)
1080                                 LOGW("mm_sound_remove_device_connected_callback failed");
1081                         goto LEAVE;
1082                 }
1083                 g_session_interrupt_cb_table.subs_id = subs_id;
1084         }
1085         g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
1086         g_session_interrupt_cb_table.user_data = user_data;
1087
1088 LEAVE:
1089         SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1090
1091         return _convert_sound_manager_error_code(__func__, ret);
1092 }
1093
1094 int sound_manager_unset_session_interrupted_cb(void)
1095 {
1096         int ret = MM_ERROR_NONE;
1097
1098         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1099         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1100
1101         if (!g_session_interrupt_cb_table.user_cb) {
1102                 ret = MM_ERROR_SOUND_INTERNAL;
1103                 goto LEAVE;
1104         }
1105
1106         ret = mm_sound_focus_unset_session_interrupt_callback();
1107         if (ret) {
1108                 if (mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id) != MM_ERROR_NONE)
1109                         LOGW("mm_sound_remove_device_connected_callback failed");
1110                 goto LEAVE;
1111         }
1112
1113         ret = mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id);
1114         if (ret)
1115                 goto LEAVE;
1116
1117         g_session_interrupt_cb_table.subs_id = 0;
1118         g_session_interrupt_cb_table.user_cb = NULL;
1119         g_session_interrupt_cb_table.user_data = NULL;
1120
1121 LEAVE:
1122         SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1123
1124         return _convert_sound_manager_error_code(__func__, ret);
1125 }
1126
1127 int sound_manager_get_current_device_list(sound_device_mask_e device_mask, sound_device_list_h *device_list)
1128 {
1129         int ret = MM_ERROR_NONE;
1130
1131         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_get_device_list() instead.", __func__);
1132         ret = mm_sound_get_device_list(device_mask, device_list);
1133
1134         return _convert_sound_manager_error_code(__func__, ret);
1135 }
1136
1137 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
1138 {
1139         int ret = MM_ERROR_NONE;
1140
1141         ret = mm_sound_get_device_list(device_mask, device_list);
1142
1143         return _convert_sound_manager_error_code(__func__, ret);
1144 }
1145
1146 int sound_manager_free_device_list(sound_device_list_h device_list)
1147 {
1148         int ret = MM_ERROR_NONE;
1149
1150         ret = mm_sound_free_device_list(device_list);
1151
1152         return _convert_sound_manager_error_code(__func__, ret);
1153 }
1154
1155 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
1156 {
1157         int ret = MM_ERROR_NONE;
1158
1159         ret = mm_sound_get_next_device(device_list, device);
1160
1161         return _convert_sound_manager_error_code(__func__, ret);
1162 }
1163
1164 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
1165 {
1166         int ret = MM_ERROR_NONE;
1167
1168         ret = mm_sound_get_prev_device(device_list, device);
1169
1170         return _convert_sound_manager_error_code(__func__, ret);
1171 }
1172
1173 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
1174 {
1175         int ret = MM_ERROR_NONE;
1176         mm_sound_device_type_e mm_sound_device_type;
1177
1178         ret = mm_sound_get_device_type(device, &mm_sound_device_type);
1179         if (ret == MM_ERROR_NONE)
1180                 _convert_device_type(mm_sound_device_type, type);
1181
1182         return _convert_sound_manager_error_code(__func__, ret);
1183 }
1184
1185 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
1186 {
1187         int ret = MM_ERROR_NONE;
1188         mm_sound_device_io_direction_e mm_sound_io_direction;
1189
1190         ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
1191         if (ret == MM_ERROR_NONE)
1192                 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
1193
1194         return _convert_sound_manager_error_code(__func__, ret);
1195 }
1196
1197 int sound_manager_get_device_id(sound_device_h device, int *id)
1198 {
1199         int ret = MM_ERROR_NONE;
1200
1201         ret = mm_sound_get_device_id(device, id);
1202
1203         return _convert_sound_manager_error_code(__func__, ret);
1204 }
1205
1206 int sound_manager_get_device_name(sound_device_h device, char **name)
1207 {
1208         int ret = MM_ERROR_NONE;
1209
1210         ret = mm_sound_get_device_name(device, name);
1211
1212         return _convert_sound_manager_error_code(__func__, ret);
1213 }
1214
1215 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
1216 {
1217         int ret = MM_ERROR_NONE;
1218
1219         ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1220
1221         return _convert_sound_manager_error_code(__func__, ret);
1222 }
1223
1224 int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1225 {
1226         int ret = MM_ERROR_NONE;
1227         unsigned int subs_id = 0;
1228
1229         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1230                 "Use sound_manager_add_device_connection_changed_cb() instead.", __func__);
1231
1232         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1233
1234         ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, &subs_id);
1235         if (ret == MM_ERROR_NONE) {
1236                 g_device_connected_cb_table.subs_id = subs_id;
1237                 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1238                 g_device_connected_cb_table.user_data = user_data;
1239         }
1240
1241         SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1242
1243         return _convert_sound_manager_error_code(__func__, ret);
1244 }
1245
1246 int sound_manager_unset_device_connected_cb(void)
1247 {
1248         int ret = MM_ERROR_NONE;
1249
1250         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1251                 "Use sound_manager_remove_device_connection_changed_cb() instead.", __func__);
1252
1253         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1254
1255         if (g_device_connected_cb_table.subs_id == 0) {
1256                 ret = MM_ERROR_SOUND_INTERNAL;
1257                 goto LEAVE;
1258         }
1259
1260         ret = mm_sound_remove_device_connected_callback(g_device_connected_cb_table.subs_id);
1261         if (ret == MM_ERROR_NONE) {
1262                 g_device_connected_cb_table.subs_id = 0;
1263                 g_device_connected_cb_table.user_cb = NULL;
1264                 g_device_connected_cb_table.user_data = NULL;
1265         }
1266
1267 LEAVE:
1268         SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1269
1270         return _convert_sound_manager_error_code(__func__, ret);
1271 }
1272
1273 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connected_cb callback, void *user_data, int *id)
1274 {
1275         int ret = MM_ERROR_NONE;
1276
1277         if (!callback || !id)
1278                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1279
1280         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);
1281
1282         return _convert_sound_manager_error_code(__func__, ret);
1283 }
1284
1285 int sound_manager_remove_device_connection_changed_cb(int id)
1286 {
1287         int ret = MM_ERROR_NONE;
1288
1289         if (id < 0)
1290                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1291
1292         ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1293
1294         return _convert_sound_manager_error_code(__func__, ret);
1295 }
1296
1297 int sound_manager_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1298 {
1299         int ret = MM_ERROR_NONE;
1300         unsigned int subs_id = 0;
1301
1302         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1303                 "Use sound_manager_add_device_state_changed_cb() instead.", __func__);
1304         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1305
1306         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);
1307         if (ret == MM_ERROR_NONE) {
1308                 g_device_info_changed_cb_table.subs_id = subs_id;
1309                 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1310                 g_device_info_changed_cb_table.user_data = user_data;
1311         }
1312
1313         SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1314
1315         return _convert_sound_manager_error_code(__func__, ret);
1316 }
1317
1318 int sound_manager_unset_device_information_changed_cb(void)
1319 {
1320         int ret = MM_ERROR_NONE;
1321
1322         LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1323                 "Use sound_manager_remove_device_state_changed_cb() instead.", __func__);
1324         SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1325
1326         if (g_device_info_changed_cb_table.subs_id == 0) {
1327                 ret = MM_ERROR_SOUND_INTERNAL;
1328                 goto LEAVE;
1329         }
1330
1331         ret = mm_sound_remove_device_information_changed_callback(g_device_info_changed_cb_table.subs_id);
1332         if (ret == MM_ERROR_NONE) {
1333                 g_device_info_changed_cb_table.subs_id = 0;
1334                 g_device_info_changed_cb_table.user_cb = NULL;
1335                 g_device_info_changed_cb_table.user_data = NULL;
1336         }
1337
1338 LEAVE:
1339         SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1340
1341         return _convert_sound_manager_error_code(__func__, ret);
1342 }
1343
1344 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1345 {
1346         int ret = MM_ERROR_NONE;
1347
1348         if (!callback || !id)
1349                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1350
1351         ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
1352
1353         return _convert_sound_manager_error_code(__func__, ret);
1354 }
1355
1356 int sound_manager_remove_device_state_changed_cb(int id)
1357 {
1358         int ret = MM_ERROR_NONE;
1359
1360         if (id < 0)
1361                 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1362
1363         ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
1364
1365         return _convert_sound_manager_error_code(__func__, ret);
1366 }
1367
1368 __attribute__ ((destructor))
1369 void __sound_manager_finalize(void)
1370 {
1371         int ret = MM_ERROR_NONE;
1372
1373         if (g_session_interrupt_cb_table.is_registered) {
1374                 LOGI("<ENTER>");
1375                 ret = mm_session_finish();
1376                 if (ret != MM_ERROR_NONE)
1377                         LOGE("[%s] failed to mm_session_finish(), ret(0x%x)", __func__, ret);
1378
1379                 g_session_interrupt_cb_table.is_registered = 0;
1380                 LOGI("<LEAVE>");
1381         }
1382 }
1383
1384 __attribute__ ((constructor))
1385 void __sound_manager_initialize(void)
1386 {
1387
1388 }