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