Get device-type as string and convert it
[platform/core/api/sound-manager.git] / src / sound_manager.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "sound_manager.h"
18 #include "sound_manager_private.h"
19
20 _session_interrupt_info_s g_session_interrupt_cb_table = {0, NULL, NULL};
21 _volume_changed_info_s g_volume_changed_cb_table = {NULL, NULL};
22 _focus_watch_info_s g_focus_watch_cb_table = {NULL, NULL};
23 _device_connected_info_s g_device_connected_cb_table = {NULL, NULL};
24 _device_changed_info_s g_device_info_changed_cb_table = {NULL, NULL};
25
26 sound_session_type_e g_cached_session = -1;
27 _session_mode_e g_cached_session_mode = -1;
28
29 #ifdef TMP_CODE
30 /*temporary variable for set/get voip session mode. When 2.4  feature for routing is fully implemented, it will be removed.*/
31 sound_session_voip_mode_e tmp_mode = -1;
32 #endif
33
34 int sound_manager_get_max_volume (sound_type_e type, int *max)
35 {
36         const char *volume_type = NULL;
37         unsigned int max_level = 0;
38         int ret = MM_ERROR_NONE;
39         if(max == NULL)
40                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
41
42         if(type >= SOUND_TYPE_NUM || type < 0)
43                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
44         ret = __convert_sound_type (type, &volume_type);
45         if (!ret)
46                 ret = __get_volume_max_level("out", volume_type, &max_level);
47
48         if(ret == 0)
49                 *max = (int)max_level -1;       // actual volume step can be max step - 1
50
51         return __convert_sound_manager_error_code(__func__, ret);
52 }
53
54 int sound_manager_set_volume (sound_type_e type, int volume)
55 {
56         if(type >= SOUND_TYPE_NUM || type < 0)
57                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
58         if(volume < 0)
59                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
60
61         int ret = mm_sound_volume_set_value(type, volume);
62         LOGI("returns : type=%d, volume=%d, ret=%p", type, volume, ret);
63
64         return __convert_sound_manager_error_code(__func__, ret);
65 }
66
67 int sound_manager_get_volume (sound_type_e type, int *volume)
68 {
69         unsigned int uvolume;
70         if(type >= SOUND_TYPE_NUM || type < 0)
71                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
72         if(volume == NULL)
73                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
74         int ret = mm_sound_volume_get_value(type, &uvolume);
75
76         if(ret == 0)
77                 *volume = uvolume;
78
79         LOGI("returns : type=%d, volume=%d, ret=%p", type, *volume, ret);
80
81         return __convert_sound_manager_error_code(__func__, ret);
82 }
83
84 int sound_manager_set_current_sound_type (sound_type_e type)
85 {
86         int ret = MM_ERROR_NONE;
87         if(type >= SOUND_TYPE_NUM || type < 0)
88                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
89
90         ret = mm_sound_volume_primary_type_set(type);
91
92         return __convert_sound_manager_error_code(__func__, ret);
93 }
94
95 int sound_manager_get_current_sound_type (sound_type_e *type)
96 {
97         int ret = MM_ERROR_NONE;
98         if(type == NULL)
99                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
100         ret = mm_sound_volume_get_current_playing_type((volume_type_t *)type);
101
102         LOGI("returns : type=%d, ret=%p", *type, ret);
103
104         return __convert_sound_manager_error_code(__func__, ret);
105 }
106
107 int sound_manager_unset_current_sound_type (void)
108 {
109         int ret = MM_ERROR_NONE;
110         ret = mm_sound_volume_primary_type_clear();
111
112         return __convert_sound_manager_error_code(__func__, ret);
113 }
114
115 int sound_manager_set_volume_changed_cb (sound_manager_volume_changed_cb callback, void* user_data)
116 {
117         int ret = MM_ERROR_NONE;
118
119         ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data);
120         if (ret == MM_ERROR_NONE) {
121                 g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
122                 g_volume_changed_cb_table.user_data = user_data;
123         }
124
125         return __convert_sound_manager_error_code(__func__, ret);
126 }
127
128 int sound_manager_unset_volume_changed_cb (void)
129 {
130         int ret = MM_ERROR_NONE;
131
132         if (g_volume_changed_cb_table.user_cb) {
133                 ret = mm_sound_remove_volume_changed_callback();
134                 if (ret == MM_ERROR_NONE) {
135                         g_volume_changed_cb_table.user_cb = NULL;
136                         g_volume_changed_cb_table.user_data = NULL;
137                 }
138         } else {
139                 ret = MM_ERROR_SOUND_INTERNAL;
140         }
141
142         return __convert_sound_manager_error_code(__func__, ret);
143 }
144
145 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)
146 {
147         int ret = MM_ERROR_NONE;
148
149         LOGI(">> enter");
150
151         SM_NULL_ARG_CHECK(stream_info);
152         SM_NULL_ARG_CHECK(callback);
153
154         sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
155         if (!stream_h) {
156                 ret = MM_ERROR_OUT_OF_MEMORY;
157         } else {
158                 memset(stream_h, 0, sizeof(sound_stream_info_s));
159                 ret = __convert_stream_type(stream_type, stream_h->stream_type);
160                 if (ret == MM_ERROR_NONE) {
161                         ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
162                         if (!ret) {
163                                 *stream_info = (sound_stream_info_h)stream_h;
164                                 LOGI("<< leave : stream_h(%p), index(%u), user_cb(%p), ret(%p)", stream_h, stream_h->index, stream_h->user_cb, ret);
165                         }
166                 }
167         }
168
169         return __convert_sound_manager_error_code(__func__, ret);
170 }
171
172 int sound_manager_destroy_stream_information (sound_stream_info_h stream_info)
173 {
174         int ret = MM_ERROR_NONE;
175         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
176
177         LOGI(">> enter");
178
179         SM_INSTANCE_CHECK(stream_h);
180
181         ret = _destroy_pa_connection_and_unregister_focus(stream_h);
182
183         LOGI("<< leave : ret(%p)", ret);
184
185         return __convert_sound_manager_error_code(__func__, ret);
186 }
187
188 int sound_manager_add_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
189 {
190         int ret = MM_ERROR_NONE;
191         int i = 0;
192         int j = 0;
193         bool added_successfully = false;
194         char *device_type_str = NULL;
195         int device_id = 0;
196         mm_sound_device_io_direction_e device_direction;
197         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
198
199         LOGI(">> enter");
200
201         SM_INSTANCE_CHECK(stream_h);
202         SM_NULL_ARG_CHECK(device);
203
204         if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
205                 ret = mm_sound_get_device_id(device, &device_id);
206                 if (ret) {
207                         return __convert_sound_manager_error_code(__func__, ret);
208                 }
209                 ret = mm_sound_get_device_type(device, &device_type_str);
210                 if (ret) {
211                         return __convert_sound_manager_error_code(__func__, ret);
212                 }
213                 ret = mm_sound_get_device_io_direction(device, &device_direction);
214                 if (ret) {
215                         return __convert_sound_manager_error_code(__func__, ret);
216                 }
217                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
218                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
219                                 if (stream_h->stream_conf_info.avail_in_devices[i]) {
220                                         if(!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
221                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
222                                                         if (!stream_h->manual_route_info.route_in_devices[j]) {
223                                                                 stream_h->manual_route_info.route_in_devices[j] = (unsigned int)device_id;
224                                                                 added_successfully = true;
225                                                                 break;
226                                                         }
227                                                         if (stream_h->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
228                                                                 /* it was already set */
229                                                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED);
230                                                         }
231                                                 }
232                                         }
233                                 } else {
234                                         break;
235                                 }
236                         }
237                 }
238                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
239                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
240                                 if (stream_h->stream_conf_info.avail_out_devices[i]) {
241                                         if(!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
242                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
243                                                         if (!stream_h->manual_route_info.route_out_devices[j]) {
244                                                                 stream_h->manual_route_info.route_out_devices[j] = (unsigned int)device_id;
245                                                                 added_successfully = true;
246                                                                 break;
247                                                         }
248                                                         if (stream_h->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
249                                                                 /* it was already set */
250                                                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED);
251                                                         }
252                                                 }
253                                         }
254                                 } else {
255                                         break;
256                                 }
257                         }
258                 }
259         }
260
261         if (!added_successfully) {
262                 ret = MM_ERROR_POLICY_INTERNAL;
263         }
264
265         LOGI("<< leave : ret(%p)", ret);
266
267         return __convert_sound_manager_error_code(__func__, ret);
268 }
269
270 int sound_manager_remove_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
271 {
272         int ret = MM_ERROR_NONE;
273         int i = 0;
274         int j = 0;
275         bool removed_successfully = false;
276         char *device_type_str = NULL;
277         int device_id = 0;
278         mm_sound_device_io_direction_e device_direction;
279         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
280
281         LOGI(">> enter");
282
283         SM_INSTANCE_CHECK(stream_h);
284         SM_NULL_ARG_CHECK(device);
285
286         if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
287                 ret = mm_sound_get_device_id(device, &device_id);
288                 if (ret) {
289                         return __convert_sound_manager_error_code(__func__, ret);
290                 }
291                 ret = mm_sound_get_device_type(device, &device_type_str);
292                 if (ret) {
293                         return __convert_sound_manager_error_code(__func__, ret);
294                 }
295                 ret = mm_sound_get_device_io_direction(device, &device_direction);
296                 if (ret) {
297                         return __convert_sound_manager_error_code(__func__, ret);
298                 }
299                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
300                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
301                                 if (stream_h->stream_conf_info.avail_in_devices[i]) {
302                                         if(!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
303                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
304                                                         if (stream_h->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
305                                                                 removed_successfully = true;
306                                                                 stream_h->manual_route_info.route_in_devices[j] = 0;
307                                                                 break;
308                                                         }
309                                                 }
310                                         }
311                                 } else {
312                                         break;
313                                 }
314                         }
315                 }
316                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
317                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
318                                 if (stream_h->stream_conf_info.avail_out_devices[i]) {
319                                         if(!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
320                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
321                                                         if (stream_h->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
322                                                                 removed_successfully = true;
323                                                                 stream_h->manual_route_info.route_out_devices[j] = 0;
324                                                                 break;
325                                                         }
326                                                 }
327                                         }
328                                 } else {
329                                         break;
330                                 }
331                         }
332                 }
333         }
334
335         if (!removed_successfully) {
336                 ret = MM_ERROR_INVALID_ARGUMENT;
337         }
338
339         LOGI("<< leave : ret(%p)", ret);
340
341         return __convert_sound_manager_error_code(__func__, ret);
342 }
343
344 int sound_manager_apply_stream_routing (sound_stream_info_h stream_info)
345 {
346         int ret = MM_ERROR_NONE;
347         int i = 0;
348         bool need_to_apply = false;
349         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
350
351         LOGI(">> enter");
352
353         SM_INSTANCE_CHECK(stream_h);
354
355         if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
356                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
357                         if (stream_h->manual_route_info.route_in_devices[i]) {
358                                 need_to_apply = true;
359                                 break;
360                         }
361                         if (stream_h->manual_route_info.route_out_devices[i]) {
362                                 need_to_apply = true;
363                                 break;
364                         }
365                 }
366                 if (need_to_apply) {
367                         ret = __set_manual_route_info(stream_h->index, &stream_h->manual_route_info);
368                 } else {
369                         __convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_STATE);
370                 }
371         } else {
372                 ret = MM_ERROR_SOUND_INVALID_STATE;
373         }
374
375         LOGI("<< leave : ret(%p)", ret);
376
377         return __convert_sound_manager_error_code(__func__, ret);
378 }
379
380 int sound_manager_acquire_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
381 {
382         int ret = MM_ERROR_NONE;
383         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
384
385         LOGI(">> enter");
386
387         SM_INSTANCE_CHECK(stream_h);
388
389         ret = mm_sound_acquire_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
390         if (ret == MM_ERROR_NONE) {
391                 stream_h->acquired_focus |= focus_mask;
392         }
393
394         LOGI("<< leave : ret(%p)", ret);
395
396         return __convert_sound_manager_error_code(__func__, ret);
397 }
398
399 int sound_manager_release_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
400 {
401         int ret = MM_ERROR_NONE;
402         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
403
404         LOGI(">> enter");
405
406         SM_INSTANCE_CHECK(stream_h);
407
408         ret = mm_sound_release_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
409         if (ret == MM_ERROR_NONE) {
410                 stream_h->acquired_focus &= ~focus_mask;
411         }
412
413         LOGI("<< leave : ret(%p)", ret);
414
415         return __convert_sound_manager_error_code(__func__, ret);
416 }
417
418 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)
419 {
420         int ret = MM_ERROR_NONE;
421         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
422
423         LOGI(">> enter");
424
425         SM_INSTANCE_CHECK(stream_h);
426         if (!state_for_playback && !state_for_recording)
427                 ret = MM_ERROR_INVALID_ARGUMENT;
428
429         if (state_for_playback)
430                 *state_for_playback = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
431         if (state_for_recording)
432                 *state_for_recording = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
433
434         LOGI("<< leave : acquired_focus(%p)", stream_h->acquired_focus);
435
436         return __convert_sound_manager_error_code(__func__, ret);
437 }
438
439 int sound_manager_set_focus_state_watch_cb (sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_watch_cb callback, void *user_data)
440 {
441         int ret = MM_ERROR_NONE;
442
443         LOGI(">> enter");
444
445         SM_NULL_ARG_CHECK(callback);
446
447         if (!g_focus_watch_cb_table.user_cb) {
448                 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data);
449                 if (ret == MM_ERROR_NONE) {
450                         g_focus_watch_cb_table.user_cb = callback;
451                         g_focus_watch_cb_table.user_data = user_data;
452                 }
453         } else {
454                 ret = MM_ERROR_SOUND_INTERNAL;
455         }
456
457         LOGI("<< leave : ret(%p)", ret);
458
459         return __convert_sound_manager_error_code(__func__, ret);
460 }
461
462 int sound_manager_unset_focus_state_watch_cb (void)
463 {
464         int ret = MM_ERROR_NONE;
465
466         LOGI(">> enter");
467
468         if (g_focus_watch_cb_table.user_cb) {
469                 ret = mm_sound_unset_focus_watch_callback();
470                 if (ret == MM_ERROR_NONE) {
471                         g_focus_watch_cb_table.user_cb = NULL;
472                         g_focus_watch_cb_table.user_data = NULL;
473                 } else {
474                         ret = MM_ERROR_SOUND_INTERNAL;
475                 }
476         } else {
477                 ret = MM_ERROR_SOUND_INTERNAL;
478         }
479
480         LOGI("<< leave : ret(%p)", ret);
481
482         return __convert_sound_manager_error_code(__func__, ret);
483 }
484
485 int sound_manager_set_session_type (sound_session_type_e type)
486 {
487         int ret = MM_ERROR_NONE;
488         int cur_session = -1;
489         int new_session = MM_SESSION_TYPE_MEDIA;
490
491         LOGI(">> enter : type=%d", type);
492
493         if(type < SOUND_SESSION_TYPE_MEDIA || type >  SOUND_SESSION_TYPE_VOIP)
494                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
495
496         switch(type) {
497         case SOUND_SESSION_TYPE_MEDIA:
498                 new_session = MM_SESSION_TYPE_MEDIA;
499                 break;
500         case SOUND_SESSION_TYPE_ALARM:
501                 new_session = MM_SESSION_TYPE_ALARM;
502                 break;
503         case SOUND_SESSION_TYPE_NOTIFICATION:
504                 new_session = MM_SESSION_TYPE_NOTIFY;
505                 break;
506         case SOUND_SESSION_TYPE_EMERGENCY:
507                 new_session = MM_SESSION_TYPE_EMERGENCY;
508                 break;
509         case SOUND_SESSION_TYPE_VOIP:
510                 new_session = MM_SESSION_TYPE_VOIP;
511                 break;
512         }
513
514         /* valid session check */
515         ret = mm_session_get_current_type(&cur_session);
516         if(ret == 0) {
517                 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
518                         if (type > SOUND_SESSION_TYPE_MEDIA) {
519                                 LOGE("<< leave : Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
520                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
521                         }
522                 }
523                 if (cur_session == MM_SESSION_TYPE_VIDEOCALL ||
524                         cur_session >= MM_SESSION_TYPE_VOICE_RECOGNITION) {
525                         return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
526                 }
527         }
528
529         if(g_session_interrupt_cb_table.is_registered) {
530                 if (new_session == cur_session ||
531                         ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
532                         LOGI("<< leave : already set type=%d, ret=%p", type, ret);
533                         return SOUND_MANAGER_ERROR_NONE;
534                 } else {
535                         ret = mm_session_finish();
536                         if (ret != MM_ERROR_NONE) {
537                                 return __convert_sound_manager_error_code(__func__, ret);
538                         }
539                         g_session_interrupt_cb_table.is_registered = 0;
540                         g_cached_session_mode = -1;
541                 }
542         }
543         ret = mm_session_init_ex(new_session , _session_interrupt_cb, NULL);
544         if(ret == 0){
545                 g_session_interrupt_cb_table.is_registered = 1;
546         }
547         if (new_session == MM_SESSION_TYPE_VOIP || new_session == MM_SESSION_TYPE_CALL) {
548                 /* set default sub-session for voip */
549                 ret = mm_session_set_subsession (MM_SUBSESSION_TYPE_RINGTONE, MM_SUBSESSION_OPTION_NONE);
550                 if (ret != MM_ERROR_NONE) {
551                         return __convert_sound_manager_error_code(__func__, ret);
552                 }
553                 g_cached_session_mode = _SESSION_MODE_RINGTONE;
554         }
555         LOGI("<< leave : type=%d, ret=%p", type, ret);
556
557         return __convert_sound_manager_error_code(__func__, ret);
558 }
559
560 int sound_manager_get_session_type (sound_session_type_e *type)
561 {
562         int ret = MM_ERROR_NONE;
563         int cur_session;
564
565         if( type == NULL )
566                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
567         ret = mm_session_get_current_type(&cur_session);
568         if (ret != 0)
569                 cur_session = SOUND_SESSION_TYPE_DEFAULT;
570         if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
571                         (cur_session != MM_SESSION_TYPE_VOIP)) {
572                 if( g_cached_session != -1 )
573                         cur_session = g_cached_session;
574                 else //will be never reach here. just prevent code
575                         cur_session = SOUND_SESSION_TYPE_DEFAULT;
576         }
577
578         switch(cur_session) {
579         case MM_SESSION_TYPE_MEDIA:
580         case MM_SESSION_TYPE_MEDIA_RECORD:
581                 *type = SOUND_SESSION_TYPE_MEDIA;
582                 break;
583         case MM_SESSION_TYPE_ALARM:
584                 *type = SOUND_SESSION_TYPE_ALARM;
585                 break;
586         case MM_SESSION_TYPE_NOTIFY:
587                 *type = SOUND_SESSION_TYPE_NOTIFICATION;
588                 break;
589         case MM_SESSION_TYPE_EMERGENCY:
590                 *type = SOUND_SESSION_TYPE_EMERGENCY;
591                 break;
592         case MM_SESSION_TYPE_VOIP:
593                 *type = SOUND_SESSION_TYPE_VOIP;
594                 break;
595         default:
596                 *type = cur_session;
597                 break;
598         }
599
600         LOGI("returns : type=%d, ret=%p", *type, ret);
601
602         return 0;
603 }
604
605 int sound_manager_set_media_session_option (sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
606 {
607         int ret = MM_ERROR_NONE;
608         int session = 0;
609         int session_option = 0;
610         int updated = 0;
611
612         LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
613
614         if(s_option < 0 || s_option >  SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
615                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
616         if(d_option < 0 || d_option >  SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
617                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
618
619         ret = mm_session_get_current_information(&session, &session_option);
620         if ( ret != 0 || !g_session_interrupt_cb_table.is_registered) {
621                 LOGW("need to set session type first");
622                 return __convert_sound_manager_error_code(__func__, ret);
623         } else if ( ret == 0 && session > MM_SESSION_TYPE_MEDIA ) {
624                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
625                         if (!g_session_interrupt_cb_table.is_registered) {
626                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
627                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
628                         }
629                 } else {
630                         return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
631                 }
632         }
633
634         switch (s_option) {
635         case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
636                 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
637                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
638                         if(ret){
639                                 return __convert_sound_manager_error_code(__func__, ret);
640                         }
641                         updated = 1;
642                 }
643                 break;
644         case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
645                 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
646                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
647                         if(ret){
648                                 return __convert_sound_manager_error_code(__func__, ret);
649                         }
650                         updated = 1;
651                 }
652                 break;
653         }
654
655         switch (d_option) {
656         case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
657                 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
658                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
659                         if(ret){
660                                 return __convert_sound_manager_error_code(__func__, ret);
661                         }
662                         updated = 1;
663                 }
664                 break;
665         case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
666                 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
667                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
668                         if(ret){
669                                 return __convert_sound_manager_error_code(__func__, ret);
670                         }
671                         updated = 1;
672                 }
673                 break;
674         }
675
676         if (updated) {
677                 LOGI("<< leave : updated");
678         } else {
679                 LOGI("<< leave : already set same option(%x), skip it", session_option);
680         }
681
682         return __convert_sound_manager_error_code(__func__, ret);
683 }
684
685 int sound_manager_get_media_session_option (sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
686 {
687         int ret = MM_ERROR_NONE;
688         int session = 0;
689         int session_options = 0;
690
691         LOGI(">> enter");
692
693         if( s_option == NULL || d_option == NULL )
694                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
695
696         ret = mm_session_get_current_information(&session, &session_options);
697         if( ret != 0 ) {
698                 return __convert_sound_manager_error_code(__func__, ret);
699         } else if (session > SOUND_SESSION_TYPE_MEDIA ) {
700                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
701                         if (!g_session_interrupt_cb_table.is_registered) {
702                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
703                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
704                         }
705                 } else {
706                         return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
707                 }
708         }
709         /* get option */
710         if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS) {
711                 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
712         } else {
713                 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
714         }
715         if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
716                 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
717         } else {
718                 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
719         }
720
721         LOGI("<< leave : option for starting=%d, for during play=%d", *s_option, *d_option);
722
723         return SOUND_MANAGER_ERROR_NONE;
724 }
725
726 int sound_manager_set_media_session_resumption_option (sound_session_option_for_resumption_e option)
727 {
728         int ret = MM_ERROR_NONE;
729         int session = 0;
730         int session_option = 0;
731         int updated = 0;
732
733         LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
734
735         if(option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
736                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
737
738         ret = mm_session_get_current_information(&session, &session_option);
739         if ( ret != 0 || !g_session_interrupt_cb_table.is_registered) {
740                 LOGW("need to set session type first");
741                 return __convert_sound_manager_error_code(__func__, ret);
742         } else if ( ret == 0 && session > MM_SESSION_TYPE_MEDIA ) {
743                 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
744                         if (!g_session_interrupt_cb_table.is_registered) {
745                                 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
746                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
747                         }
748                 } else {
749                         return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
750                 }
751         }
752
753         switch (option) {
754         case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
755                 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
756                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
757                         if(ret){
758                                 return __convert_sound_manager_error_code(__func__, ret);
759                         }
760                         updated = 1;
761                 }
762                 break;
763         case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
764                 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
765                         ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
766                         if(ret){
767                                 return __convert_sound_manager_error_code(__func__, ret);
768                         }
769                         updated = 1;
770                 }
771                 break;
772         }
773
774         if (updated) {
775                 LOGI("<< leave : updated");
776         } else {
777                 LOGI("<< leave : already set same option(%x), skip it", session_option);
778         }
779
780         return __convert_sound_manager_error_code(__func__, ret);
781 }
782
783 int sound_manager_get_media_session_resumption_option (sound_session_option_for_resumption_e *option)
784 {
785         int ret = MM_ERROR_NONE;
786         int session = 0;
787         int session_options = 0;
788
789         LOGI(">> enter");
790
791         if( option == NULL )
792                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
793         ret = mm_session_get_current_information(&session, &session_options);
794         if( ret != 0 ) {
795                 return __convert_sound_manager_error_code(__func__, ret);
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         }
806         /* get option */
807         if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
808                 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
809         } else {
810                 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
811         }
812
813         LOGI("<< leave : option for resumption=%d (0:by system, 1:by system or media paused)", *option);
814
815         return SOUND_MANAGER_ERROR_NONE;
816 }
817
818 int sound_manager_set_voip_session_mode (sound_session_voip_mode_e mode)
819 {
820         int ret = MM_ERROR_NONE;
821         int session = 0;
822         int session_options = 0;
823
824         LOGI(">> enter : mode=%d", mode);
825
826         ret = mm_session_get_current_information(&session, &session_options);
827         if( ret != MM_ERROR_NONE ) {
828                 return __convert_sound_manager_error_code(__func__, ret);
829         } else if (session != MM_SESSION_TYPE_VOIP ) {
830                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
831         }
832         if(mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
833                 ret = MM_ERROR_INVALID_ARGUMENT;
834                 return __convert_sound_manager_error_code(__func__, ret);
835         }
836         ret = __set_session_mode ((_session_mode_e)mode);
837
838 #ifdef TMP_CODE
839         /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */
840         tmp_mode = mode;
841 #endif
842
843         LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret);
844
845         return __convert_sound_manager_error_code(__func__, ret);
846 }
847
848 int sound_manager_get_voip_session_mode (sound_session_voip_mode_e *mode)
849 {
850         int ret = MM_ERROR_NONE;
851         int session = 0;
852         int session_options = 0;
853         _session_mode_e _mode = 0;
854
855         if(mode == NULL) {
856                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
857         }
858
859         ret = mm_session_get_current_information(&session, &session_options);
860         if( ret != MM_ERROR_NONE ) {
861                 return __convert_sound_manager_error_code(__func__, ret);
862         } else if (session != MM_SESSION_TYPE_VOIP ) {
863                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
864         }
865         ret = __get_session_mode(&_mode);
866         if (ret == MM_ERROR_NONE)
867                 *mode = (sound_session_voip_mode_e)_mode;
868
869 #ifdef TMP_CODE
870         /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */
871         *mode = tmp_mode;
872 #endif
873
874         LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret);
875
876         return __convert_sound_manager_error_code(__func__, ret);
877 }
878
879 int sound_manager_set_session_interrupted_cb (sound_session_interrupted_cb callback, void *user_data)
880 {
881         int ret = MM_ERROR_NONE;
882         if(callback == NULL)
883                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
884
885         if(g_session_interrupt_cb_table.is_registered ==0){
886                 ret = mm_session_init_ex(SOUND_SESSION_TYPE_DEFAULT /*default*/ , _session_interrupt_cb, NULL);
887                 if(ret != 0)
888                         return __convert_sound_manager_error_code(__func__, ret);
889                 g_session_interrupt_cb_table.is_registered = 1;
890         }
891
892         g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
893         g_session_interrupt_cb_table.user_data = user_data;
894         return SOUND_MANAGER_ERROR_NONE;
895 }
896
897 int sound_manager_unset_session_interrupted_cb (void)
898 {
899         int ret = MM_ERROR_NONE;
900         if (g_session_interrupt_cb_table.user_cb) {
901                 g_session_interrupt_cb_table.user_cb = NULL;
902                 g_session_interrupt_cb_table.user_data = NULL;
903         } else {
904                 ret = MM_ERROR_SOUND_INTERNAL;
905         }
906         return __convert_sound_manager_error_code(__func__, ret);
907 }
908
909 int sound_manager_get_current_device_list (sound_device_mask_e device_mask, sound_device_list_h *device_list)
910 {
911         int ret = MM_ERROR_NONE;
912         ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
913
914         return __convert_sound_manager_error_code(__func__, ret);
915 }
916
917 int sound_manager_get_next_device (sound_device_list_h device_list, sound_device_h *device)
918 {
919         int ret = MM_ERROR_NONE;
920         ret = mm_sound_get_next_device(device_list, device);
921
922         return __convert_sound_manager_error_code(__func__, ret);
923 }
924
925 int sound_manager_get_prev_device (sound_device_list_h device_list, sound_device_h *device)
926 {
927         int ret = MM_ERROR_NONE;
928         ret = mm_sound_get_prev_device(device_list, device);
929
930         return __convert_sound_manager_error_code(__func__, ret);
931 }
932
933 int sound_manager_get_device_type (sound_device_h device, sound_device_type_e *type)
934 {
935         int ret = MM_ERROR_NONE;
936         char *device_type = NULL;
937         ret = mm_sound_get_device_type(device, &device_type);
938         if (ret == MM_ERROR_NONE) {
939                 ret = __convert_device_type_to_enum(device_type, type);
940         }
941
942         return __convert_sound_manager_error_code(__func__, ret);
943 }
944
945 int sound_manager_get_device_io_direction (sound_device_h device, sound_device_io_direction_e *io_direction)
946 {
947         int ret = MM_ERROR_NONE;
948         mm_sound_device_io_direction_e mm_sound_io_direction;
949         ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
950         if (ret == MM_ERROR_NONE) {
951                 ret = __convert_device_io_direction(mm_sound_io_direction, io_direction);
952         }
953
954         return __convert_sound_manager_error_code(__func__, ret);
955 }
956
957 int sound_manager_get_device_id (sound_device_h device, int *id)
958 {
959         int ret = MM_ERROR_NONE;
960         ret = mm_sound_get_device_id(device, id);
961
962         return __convert_sound_manager_error_code(__func__, ret);
963 }
964
965 int sound_manager_get_device_name (sound_device_h device, char **name)
966 {
967         int ret = MM_ERROR_NONE;
968         ret = mm_sound_get_device_name(device, name);
969
970         return __convert_sound_manager_error_code(__func__, ret);
971 }
972
973 int sound_manager_get_device_state (sound_device_h device, sound_device_state_e *state)
974 {
975         int ret = MM_ERROR_NONE;
976         ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
977
978         return __convert_sound_manager_error_code(__func__, ret);
979 }
980
981 int sound_manager_set_device_connected_cb (sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
982 {
983         int ret = MM_ERROR_NONE;
984         ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data);
985         if (ret == MM_ERROR_NONE) {
986                 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
987                 g_device_connected_cb_table.user_data = user_data;
988         }
989
990         return __convert_sound_manager_error_code(__func__, ret);
991 }
992
993 int sound_manager_unset_device_connected_cb (void)
994 {
995         int ret = MM_ERROR_NONE;
996         if (g_device_connected_cb_table.user_cb) {
997                 ret = mm_sound_remove_device_connected_callback();
998                 if (ret == MM_ERROR_NONE) {
999                         g_device_connected_cb_table.user_cb = NULL;
1000                         g_device_connected_cb_table.user_data = NULL;
1001                 }
1002         } else {
1003                 ret = MM_ERROR_SOUND_INTERNAL;
1004         }
1005
1006         return __convert_sound_manager_error_code(__func__, ret);
1007 }
1008
1009 int sound_manager_set_device_information_changed_cb (sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1010 {
1011         int ret = MM_ERROR_NONE;
1012         ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data);
1013         if (ret == MM_ERROR_NONE) {
1014                 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1015                 g_device_info_changed_cb_table.user_data = user_data;
1016         }
1017
1018         return __convert_sound_manager_error_code(__func__, ret);
1019 }
1020
1021 int sound_manager_unset_device_information_changed_cb (void)
1022 {
1023         int ret = MM_ERROR_NONE;
1024         if (g_device_info_changed_cb_table.user_cb) {
1025                 ret = mm_sound_remove_device_information_changed_callback();
1026                 if (ret == MM_ERROR_NONE) {
1027                         g_device_info_changed_cb_table.user_cb = NULL;
1028                         g_device_info_changed_cb_table.user_data = NULL;
1029                 }
1030         } else {
1031                 ret = MM_ERROR_SOUND_INTERNAL;
1032         }
1033
1034         return __convert_sound_manager_error_code(__func__, ret);
1035 }
1036
1037 __attribute__ ((destructor))
1038 void __sound_manager_finalize (void)
1039 {
1040         int ret = MM_ERROR_NONE;
1041
1042         if(g_session_interrupt_cb_table.is_registered){
1043                 LOGI("<ENTER>");
1044                 ret = mm_session_finish();
1045                 if (ret != MM_ERROR_NONE) {
1046                         LOGE("[%s] failed to mm_session_finish(), ret(%p)", __func__, ret);
1047                 }
1048                 g_session_interrupt_cb_table.is_registered = 0;
1049                 LOGI("<LEAVE>");
1050         }
1051 }
1052
1053 __attribute__ ((constructor))
1054 void __sound_manager_initialize (void)
1055 {
1056
1057 }