Support new features for sound policy
[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 int sound_manager_get_max_volume (sound_type_e type, int *max)
30 {
31         int volume;
32         if(max == NULL)
33                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
34
35         if(type >= SOUND_TYPE_NUM || type < 0)
36                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
37         int ret = mm_sound_volume_get_step(type, &volume);
38
39         if(ret == 0)
40                 *max = volume -1;       // actual volume step can be max step - 1
41
42         return __convert_sound_manager_error_code(__func__, ret);
43 }
44
45 int sound_manager_set_volume (sound_type_e type, int volume)
46 {
47         if(type >= SOUND_TYPE_NUM || type < 0)
48                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
49         if(volume < 0)
50                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
51
52         int ret = mm_sound_volume_set_value(type, volume);
53         LOGI("returns : type=%d, volume=%d, ret=%p", type, volume, ret);
54
55         return __convert_sound_manager_error_code(__func__, ret);
56 }
57
58 int sound_manager_get_volume (sound_type_e type, int *volume)
59 {
60         unsigned int uvolume;
61         if(type >= SOUND_TYPE_NUM || type < 0)
62                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
63         if(volume == NULL)
64                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
65         int ret = mm_sound_volume_get_value(type, &uvolume);
66
67         if(ret == 0)
68                 *volume = uvolume;
69
70         LOGI("returns : type=%d, volume=%d, ret=%p", type, *volume, ret);
71
72         return __convert_sound_manager_error_code(__func__, ret);
73 }
74
75 int sound_manager_set_current_sound_type (sound_type_e type)
76 {
77         int ret = MM_ERROR_NONE;
78         if(type >= SOUND_TYPE_NUM || type < 0)
79                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
80
81         ret = mm_sound_volume_primary_type_set(type);
82
83         return __convert_sound_manager_error_code(__func__, ret);
84 }
85
86 int sound_manager_get_current_sound_type (sound_type_e *type)
87 {
88         int ret = MM_ERROR_NONE;
89         if(type == NULL)
90                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
91         ret = mm_sound_volume_get_current_playing_type((volume_type_t *)type);
92
93         LOGI("returns : type=%d, ret=%p", *type, ret);
94
95         return __convert_sound_manager_error_code(__func__, ret);
96 }
97
98 int sound_manager_unset_current_sound_type (void)
99 {
100         int ret = MM_ERROR_NONE;
101         ret = mm_sound_volume_primary_type_clear();
102
103         return __convert_sound_manager_error_code(__func__, ret);
104 }
105
106 int sound_manager_set_volume_changed_cb (sound_manager_volume_changed_cb callback, void* user_data)
107 {
108         int ret = MM_ERROR_NONE;
109
110         ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data);
111         if (ret == MM_ERROR_NONE) {
112                 g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
113                 g_volume_changed_cb_table.user_data = user_data;
114         }
115
116         return __convert_sound_manager_error_code(__func__, ret);
117 }
118
119 int sound_manager_unset_volume_changed_cb (void)
120 {
121         int ret = MM_ERROR_NONE;
122
123         if (g_volume_changed_cb_table.user_cb) {
124                 ret = mm_sound_remove_volume_changed_callback();
125                 if (ret == MM_ERROR_NONE) {
126                         g_volume_changed_cb_table.user_cb = NULL;
127                         g_volume_changed_cb_table.user_data = NULL;
128                 }
129         } else {
130                 ret = MM_ERROR_SOUND_INTERNAL;
131         }
132
133         return __convert_sound_manager_error_code(__func__, ret);
134 }
135
136 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)
137 {
138         int ret = MM_ERROR_NONE;
139
140         LOGI(">> enter");
141
142         SM_NULL_ARG_CHECK(stream_info);
143         SM_NULL_ARG_CHECK(callback);
144
145         sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
146         if (!stream_h) {
147                 ret = MM_ERROR_OUT_OF_MEMORY;
148         } else {
149                 memset(stream_h, 0, sizeof(sound_stream_info_s));
150                 ret = __convert_stream_type(stream_type, stream_h->stream_type);
151                 if (ret == MM_ERROR_NONE) {
152                         ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
153                         if (!ret) {
154                                 *stream_info = (sound_stream_info_h)stream_h;
155                                 LOGI("<< leave : stream_h(%p), index(%u), user_cb(%p), ret(%p)", stream_h, stream_h->index, stream_h->user_cb, ret);
156                         }
157                 }
158         }
159
160         return __convert_sound_manager_error_code(__func__, ret);
161 }
162
163 int sound_manager_destroy_stream_information (sound_stream_info_h stream_info)
164 {
165         int ret = MM_ERROR_NONE;
166         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
167
168         LOGI(">> enter");
169
170         SM_INSTANCE_CHECK(stream_h);
171
172         ret = _destroy_pa_connection_and_unregister_focus(stream_h);
173
174         LOGI("<< leave : ret(%p)", ret);
175
176         return __convert_sound_manager_error_code(__func__, ret);
177 }
178
179 int sound_manager_add_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
180 {
181         int ret = MM_ERROR_NONE;
182         int i = 0;
183         int j = 0;
184         bool added_successfully = false;
185         char device_type_str[SOUND_DEVICE_TYPE_LEN] = {0,};
186         mm_sound_device_type_e device_type;
187         mm_sound_device_io_direction_e device_direction;
188         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
189
190         LOGI(">> enter");
191
192         SM_INSTANCE_CHECK(stream_h);
193         SM_NULL_ARG_CHECK(device);
194
195         if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
196                 ret = mm_sound_get_device_type(device, &device_type);
197                 if (ret) {
198                         return __convert_sound_manager_error_code(__func__, ret);
199                 }
200                 ret = __convert_device_type(device_type, device_type_str);
201                 if (ret) {
202                         return __convert_sound_manager_error_code(__func__, ret);
203                 }
204                 ret = mm_sound_get_device_io_direction(device, &device_direction);
205                 if (ret) {
206                         return __convert_sound_manager_error_code(__func__, ret);
207                 }
208                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
209                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
210                                 if (stream_h->stream_conf_info.avail_in_devices[i]) {
211                                         if(!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
212                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
213                                                         if (!stream_h->manual_route_info.route_in_devices[j]) {
214                                                                 stream_h->manual_route_info.route_in_devices[j] = strdup(device_type_str);
215                                                                 added_successfully = true;
216                                                                 break;
217                                                         }
218                                                         if (!strncmp(stream_h->manual_route_info.route_in_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
219                                                                 /* it was already set */
220                                                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED);
221                                                         }
222                                                 }
223                                         }
224                                 } else {
225                                         break;
226                                 }
227                         }
228                 }
229                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
230                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
231                                 if (stream_h->stream_conf_info.avail_out_devices[i]) {
232                                         if(!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
233                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
234                                                         if (!stream_h->manual_route_info.route_out_devices[j]) {
235                                                                 stream_h->manual_route_info.route_out_devices[j] = strdup(device_type_str);
236                                                                 added_successfully = true;
237                                                                 break;
238                                                         }
239                                                         if (!strncmp(stream_h->manual_route_info.route_out_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
240                                                                 /* it was already set */
241                                                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED);
242                                                         }
243                                                 }
244                                         }
245                                 } else {
246                                         break;
247                                 }
248                         }
249                 }
250         }
251
252         if (!added_successfully) {
253                 ret = MM_ERROR_POLICY_INTERNAL;
254         }
255
256         LOGI("<< leave : ret(%p)", ret);
257
258         return __convert_sound_manager_error_code(__func__, ret);
259 }
260
261 int sound_manager_remove_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
262 {
263         int ret = MM_ERROR_NONE;
264         int i = 0;
265         int j = 0;
266         bool removed_successfully = false;
267         char device_type_str[SOUND_DEVICE_TYPE_LEN] = {0,};
268         mm_sound_device_type_e device_type;
269         mm_sound_device_io_direction_e device_direction;
270         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
271
272         LOGI(">> enter");
273
274         SM_INSTANCE_CHECK(stream_h);
275         SM_NULL_ARG_CHECK(device);
276
277         if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
278                 ret = mm_sound_get_device_type(device, &device_type);
279                 if (ret) {
280                         return __convert_sound_manager_error_code(__func__, ret);
281                 }
282                 ret = __convert_device_type(device_type, device_type_str);
283                 if (ret) {
284                         return __convert_sound_manager_error_code(__func__, ret);
285                 }
286                 ret = mm_sound_get_device_io_direction(device, &device_direction);
287                 if (ret) {
288                         return __convert_sound_manager_error_code(__func__, ret);
289                 }
290                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
291                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
292                                 if (stream_h->stream_conf_info.avail_in_devices[i]) {
293                                         if(!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
294                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
295                                                         if (!strncmp(stream_h->manual_route_info.route_in_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
296                                                                 removed_successfully = true;
297                                                                 free(stream_h->manual_route_info.route_in_devices[j]);
298                                                                 stream_h->manual_route_info.route_in_devices[j] = NULL;
299                                                                 break;
300                                                         }
301                                                 }
302                                         }
303                                 } else {
304                                         break;
305                                 }
306                         }
307                 }
308                 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
309                         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
310                                 if (stream_h->stream_conf_info.avail_out_devices[i]) {
311                                         if(!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
312                                                 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
313                                                         if (!strncmp(stream_h->manual_route_info.route_out_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
314                                                                 removed_successfully = true;
315                                                                 free(stream_h->manual_route_info.route_out_devices[j]);
316                                                                 stream_h->manual_route_info.route_out_devices[j] = NULL;
317                                                                 break;
318                                                         }
319                                                 }
320                                         }
321                                 } else {
322                                         break;
323                                 }
324                         }
325                 }
326         }
327
328         if (!removed_successfully) {
329                 ret = MM_ERROR_INVALID_ARGUMENT;
330         }
331
332         LOGI("<< leave : ret(%p)", ret);
333
334         return __convert_sound_manager_error_code(__func__, ret);
335 }
336
337 int sound_manager_apply_stream_routing (sound_stream_info_h stream_info)
338 {
339         int ret = MM_ERROR_NONE;
340         int i = 0;
341         bool need_to_apply = false;
342         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
343
344         LOGI(">> enter");
345
346         SM_INSTANCE_CHECK(stream_h);
347
348         if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
349                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
350                         if (stream_h->manual_route_info.route_in_devices[i]) {
351                                 need_to_apply = true;
352                                 break;
353                         }
354                         if (stream_h->manual_route_info.route_out_devices[i]) {
355                                 need_to_apply = true;
356                                 break;
357                         }
358                 }
359                 if (need_to_apply) {
360                         ret = __set_manual_route_info(stream_h->index, &stream_h->manual_route_info);
361                 } else {
362                         __convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_STATE);
363                 }
364         } else {
365                 ret = MM_ERROR_SOUND_INVALID_STATE;
366         }
367
368         LOGI("<< leave : ret(%p)", ret);
369
370         return __convert_sound_manager_error_code(__func__, ret);
371 }
372
373 int sound_manager_acquire_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
374 {
375         int ret = MM_ERROR_NONE;
376         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
377
378         LOGI(">> enter");
379
380         SM_INSTANCE_CHECK(stream_h);
381
382         ret = mm_sound_acquire_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
383         if (ret == MM_ERROR_NONE) {
384                 stream_h->acquired_focus |= focus_mask;
385         }
386
387         LOGI("<< leave : ret(%p)", ret);
388
389         return __convert_sound_manager_error_code(__func__, ret);
390 }
391
392 int sound_manager_release_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
393 {
394         int ret = MM_ERROR_NONE;
395         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
396
397         LOGI(">> enter");
398
399         SM_INSTANCE_CHECK(stream_h);
400
401         ret = mm_sound_release_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
402         if (ret == MM_ERROR_NONE) {
403                 stream_h->acquired_focus &= ~focus_mask;
404         }
405
406         LOGI("<< leave : ret(%p)", ret);
407
408         return __convert_sound_manager_error_code(__func__, ret);
409 }
410
411 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)
412 {
413         int ret = MM_ERROR_NONE;
414         sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
415
416         LOGI(">> enter");
417
418         SM_INSTANCE_CHECK(stream_h);
419         if (!state_for_playback && !state_for_recording)
420                 ret = MM_ERROR_INVALID_ARGUMENT;
421
422         if (state_for_playback)
423                 *state_for_playback = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
424         if (state_for_recording)
425                 *state_for_recording = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
426
427         LOGI("<< leave : acquired_focus(%p)", stream_h->acquired_focus);
428
429         return __convert_sound_manager_error_code(__func__, ret);
430 }
431
432 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)
433 {
434         int ret = MM_ERROR_NONE;
435
436         LOGI(">> enter");
437
438         SM_NULL_ARG_CHECK(callback);
439
440         if (!g_focus_watch_cb_table.user_cb) {
441                 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data);
442                 if (ret == MM_ERROR_NONE) {
443                         g_focus_watch_cb_table.user_cb = callback;
444                         g_focus_watch_cb_table.user_data = user_data;
445                 }
446         } else {
447                 ret = MM_ERROR_SOUND_INTERNAL;
448         }
449
450         LOGI("<< leave : ret(%p)", ret);
451
452         return __convert_sound_manager_error_code(__func__, ret);
453 }
454
455 int sound_manager_unset_focus_state_watch_cb (void)
456 {
457         int ret = MM_ERROR_NONE;
458
459         LOGI(">> enter");
460
461         if (g_focus_watch_cb_table.user_cb) {
462                 ret = mm_sound_unset_focus_watch_callback();
463                 if (ret == MM_ERROR_NONE) {
464                         g_focus_watch_cb_table.user_cb = NULL;
465                         g_focus_watch_cb_table.user_data = NULL;
466                 } else {
467                         ret = MM_ERROR_SOUND_INTERNAL;
468                 }
469         } else {
470                 ret = MM_ERROR_SOUND_INTERNAL;
471         }
472
473         LOGI("<< leave : ret(%p)", ret);
474
475         return __convert_sound_manager_error_code(__func__, ret);
476 }
477
478 int sound_manager_set_session_type (sound_session_type_e type)
479 {
480         int ret = MM_ERROR_NONE;
481         int cur_session = -1;
482         int new_session = MM_SESSION_TYPE_MEDIA;
483
484         LOGI(">> enter : type=%d", type);
485
486         if(type < SOUND_SESSION_TYPE_MEDIA || type >  SOUND_SESSION_TYPE_CALL)
487                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
488
489         switch(type) {
490         case SOUND_SESSION_TYPE_MEDIA:
491                 new_session = MM_SESSION_TYPE_MEDIA;
492                 break;
493         case SOUND_SESSION_TYPE_ALARM:
494                 new_session = MM_SESSION_TYPE_ALARM;
495                 break;
496         case SOUND_SESSION_TYPE_NOTIFICATION:
497                 new_session = MM_SESSION_TYPE_NOTIFY;
498                 break;
499         case SOUND_SESSION_TYPE_EMERGENCY:
500                 new_session = MM_SESSION_TYPE_EMERGENCY;
501                 break;
502         case SOUND_SESSION_TYPE_VOIP:
503                 new_session = MM_SESSION_TYPE_VOIP;
504                 break;
505         case SOUND_SESSION_TYPE_CALL:
506                 new_session = MM_SESSION_TYPE_CALL;
507                 break;
508         }
509
510         /* valid session check */
511         ret = mm_session_get_current_type(&cur_session);
512         if(ret == 0) {
513                 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
514                         if (type > SOUND_SESSION_TYPE_MEDIA) {
515                                 LOGE("<< leave : Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
516                                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
517                         }
518                 }
519                 if (cur_session == MM_SESSION_TYPE_VIDEOCALL ||
520                         cur_session >= MM_SESSION_TYPE_VOICE_RECOGNITION) {
521                         return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
522                 }
523         }
524
525         if(g_session_interrupt_cb_table.is_registered) {
526                 if (new_session == cur_session ||
527                         ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
528                         LOGI("<< leave : already set type=%d, ret=%p", type, ret);
529                         return SOUND_MANAGER_ERROR_NONE;
530                 } else {
531                         ret = mm_session_finish();
532                         if (ret != MM_ERROR_NONE) {
533                                 return __convert_sound_manager_error_code(__func__, ret);
534                         }
535                         g_session_interrupt_cb_table.is_registered = 0;
536                         g_cached_session_mode = -1;
537                 }
538         }
539         ret = mm_session_init_ex(new_session , _session_interrupt_cb, NULL);
540         if(ret == 0){
541                 g_session_interrupt_cb_table.is_registered = 1;
542         }
543         if (new_session == MM_SESSION_TYPE_VOIP || new_session == MM_SESSION_TYPE_CALL) {
544                 /* set default sub-session for voip */
545                 ret = mm_session_set_subsession (MM_SUBSESSION_TYPE_RINGTONE, MM_SUBSESSION_OPTION_NONE);
546                 if (ret != MM_ERROR_NONE) {
547                         return __convert_sound_manager_error_code(__func__, ret);
548                 }
549                 g_cached_session_mode = _SESSION_MODE_RINGTONE;
550         }
551         LOGI("<< leave : type=%d, ret=%p", type, ret);
552
553         return __convert_sound_manager_error_code(__func__, ret);
554 }
555
556 int sound_manager_get_session_type (sound_session_type_e *type)
557 {
558         int ret = MM_ERROR_NONE;
559         int cur_session;
560
561         if( type == NULL )
562                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
563         ret = mm_session_get_current_type(&cur_session);
564         if (ret != 0)
565                 cur_session = SOUND_SESSION_TYPE_DEFAULT;
566         if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
567                         (cur_session != MM_SESSION_TYPE_VOIP) &&
568                         (cur_session != MM_SESSION_TYPE_CALL)) {
569                 if( g_cached_session != -1 )
570                         cur_session = g_cached_session;
571                 else //will be never reach here. just prevent code
572                         cur_session = SOUND_SESSION_TYPE_DEFAULT;
573         }
574
575         switch(cur_session) {
576         case MM_SESSION_TYPE_MEDIA:
577         case MM_SESSION_TYPE_MEDIA_RECORD:
578                 *type = SOUND_SESSION_TYPE_MEDIA;
579                 break;
580         case MM_SESSION_TYPE_ALARM:
581                 *type = SOUND_SESSION_TYPE_ALARM;
582                 break;
583         case MM_SESSION_TYPE_NOTIFY:
584                 *type = SOUND_SESSION_TYPE_NOTIFICATION;
585                 break;
586         case MM_SESSION_TYPE_EMERGENCY:
587                 *type = SOUND_SESSION_TYPE_EMERGENCY;
588                 break;
589         case MM_SESSION_TYPE_VOIP:
590                 *type = SOUND_SESSION_TYPE_VOIP;
591                 break;
592         case MM_SESSION_TYPE_CALL:
593                 *type = SOUND_SESSION_TYPE_CALL;
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         LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret);
839
840         return __convert_sound_manager_error_code(__func__, ret);
841 }
842
843 int sound_manager_get_voip_session_mode (sound_session_voip_mode_e *mode)
844 {
845         int ret = MM_ERROR_NONE;
846         int session = 0;
847         int session_options = 0;
848         _session_mode_e _mode = 0;
849
850         if(mode == NULL) {
851                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
852         }
853
854         ret = mm_session_get_current_information(&session, &session_options);
855         if( ret != MM_ERROR_NONE ) {
856                 return __convert_sound_manager_error_code(__func__, ret);
857         } else if (session != MM_SESSION_TYPE_VOIP ) {
858                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
859         }
860         ret = __get_session_mode(&_mode);
861         if (ret == MM_ERROR_NONE)
862                 *mode = (sound_session_voip_mode_e)_mode;
863
864         LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret);
865
866         return __convert_sound_manager_error_code(__func__, ret);
867 }
868
869 int sound_manager_set_call_session_mode (sound_session_call_mode_e mode)
870 {
871         int ret = MM_ERROR_NONE;
872         int session = 0;
873         int session_options = 0;
874
875         LOGI(">> enter : mode=%d", mode);
876
877         ret = mm_session_get_current_information(&session, &session_options);
878         if( ret != MM_ERROR_NONE ) {
879                 return __convert_sound_manager_error_code(__func__, ret);
880         } else if (session != MM_SESSION_TYPE_CALL ) {
881                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
882         }
883         if(mode < SOUND_SESSION_CALL_MODE_RINGTONE || mode > SOUND_SESSION_CALL_MODE_VOICE_WITH_BLUETOOTH) {
884                 ret = MM_ERROR_INVALID_ARGUMENT;
885                 return __convert_sound_manager_error_code(__func__, ret);
886         }
887         ret = __set_session_mode ((_session_mode_e)mode);
888
889         LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret);
890
891         return __convert_sound_manager_error_code(__func__, ret);
892 }
893
894 int sound_manager_get_call_session_mode (sound_session_call_mode_e *mode)
895 {
896         int ret = MM_ERROR_NONE;
897         int session = 0;
898         int session_options = 0;
899         _session_mode_e _mode = 0;
900
901         if(mode == NULL) {
902                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
903         }
904
905         ret = mm_session_get_current_information(&session, &session_options);
906         if( ret != MM_ERROR_NONE ) {
907                 return __convert_sound_manager_error_code(__func__, ret);
908         } else if (session != MM_SESSION_TYPE_CALL ) {
909                 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
910         }
911         ret = __get_session_mode(&_mode);
912         if (ret == MM_ERROR_NONE)
913                 *mode = (sound_session_call_mode_e)_mode;
914
915         LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret);
916
917         return __convert_sound_manager_error_code(__func__, ret);
918 }
919
920 int sound_manager_set_session_interrupted_cb (sound_session_interrupted_cb callback, void *user_data)
921 {
922         int ret = MM_ERROR_NONE;
923         if(callback == NULL)
924                 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
925
926         if(g_session_interrupt_cb_table.is_registered ==0){
927                 ret = mm_session_init_ex(SOUND_SESSION_TYPE_DEFAULT /*default*/ , _session_interrupt_cb, NULL);
928                 if(ret != 0)
929                         return __convert_sound_manager_error_code(__func__, ret);
930                 g_session_interrupt_cb_table.is_registered = 1;
931         }
932
933         g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
934         g_session_interrupt_cb_table.user_data = user_data;
935         return SOUND_MANAGER_ERROR_NONE;
936 }
937
938 int sound_manager_unset_session_interrupted_cb (void)
939 {
940         int ret = MM_ERROR_NONE;
941         if (g_session_interrupt_cb_table.user_cb) {
942                 g_session_interrupt_cb_table.user_cb = NULL;
943                 g_session_interrupt_cb_table.user_data = NULL;
944         } else {
945                 ret = MM_ERROR_SOUND_INTERNAL;
946         }
947         return __convert_sound_manager_error_code(__func__, ret);
948 }
949
950 int sound_manager_get_current_device_list (sound_device_mask_e device_mask, sound_device_list_h *device_list)
951 {
952         int ret = MM_ERROR_NONE;
953         ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
954
955         return __convert_sound_manager_error_code(__func__, ret);
956 }
957
958 int sound_manager_get_next_device (sound_device_list_h device_list, sound_device_h *device)
959 {
960         int ret = MM_ERROR_NONE;
961         ret = mm_sound_get_next_device(device_list, device);
962
963         return __convert_sound_manager_error_code(__func__, ret);
964 }
965
966 int sound_manager_get_prev_device (sound_device_list_h device_list, sound_device_h *device)
967 {
968         int ret = MM_ERROR_NONE;
969         ret = mm_sound_get_prev_device(device_list, device);
970
971         return __convert_sound_manager_error_code(__func__, ret);
972 }
973
974 int sound_manager_get_device_type (sound_device_h device, sound_device_type_e *type)
975 {
976         int ret = MM_ERROR_NONE;
977         ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)type);
978
979         return __convert_sound_manager_error_code(__func__, ret);
980 }
981
982 int sound_manager_get_device_io_direction (sound_device_h device, sound_device_io_direction_e *io_direction)
983 {
984         int ret = MM_ERROR_NONE;
985         ret = mm_sound_get_device_io_direction(device, (mm_sound_device_io_direction_e*)io_direction);
986
987         return __convert_sound_manager_error_code(__func__, ret);
988 }
989
990 int sound_manager_get_device_id (sound_device_h device, int *id)
991 {
992         int ret = MM_ERROR_NONE;
993         ret = mm_sound_get_device_id(device, id);
994
995         return __convert_sound_manager_error_code(__func__, ret);
996 }
997
998 int sound_manager_get_device_name (sound_device_h device, char **name)
999 {
1000         int ret = MM_ERROR_NONE;
1001         ret = mm_sound_get_device_name(device, name);
1002
1003         return __convert_sound_manager_error_code(__func__, ret);
1004 }
1005
1006 int sound_manager_get_device_state (sound_device_h device, sound_device_state_e *state)
1007 {
1008         int ret = MM_ERROR_NONE;
1009         ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1010
1011         return __convert_sound_manager_error_code(__func__, ret);
1012 }
1013
1014 int sound_manager_set_device_connected_cb (sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1015 {
1016         int ret = MM_ERROR_NONE;
1017         ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data);
1018         if (ret == MM_ERROR_NONE) {
1019                 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1020                 g_device_connected_cb_table.user_data = user_data;
1021         }
1022
1023         return __convert_sound_manager_error_code(__func__, ret);
1024 }
1025
1026 int sound_manager_unset_device_connected_cb (void)
1027 {
1028         int ret = MM_ERROR_NONE;
1029         if (g_device_connected_cb_table.user_cb) {
1030                 ret = mm_sound_remove_device_connected_callback();
1031                 if (ret == MM_ERROR_NONE) {
1032                         g_device_connected_cb_table.user_cb = NULL;
1033                         g_device_connected_cb_table.user_data = NULL;
1034                 }
1035         } else {
1036                 ret = MM_ERROR_SOUND_INTERNAL;
1037         }
1038
1039         return __convert_sound_manager_error_code(__func__, ret);
1040 }
1041
1042 int sound_manager_set_device_information_changed_cb (sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1043 {
1044         int ret = MM_ERROR_NONE;
1045         ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data);
1046         if (ret == MM_ERROR_NONE) {
1047                 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1048                 g_device_info_changed_cb_table.user_data = user_data;
1049         }
1050
1051         return __convert_sound_manager_error_code(__func__, ret);
1052 }
1053
1054 int sound_manager_unset_device_information_changed_cb (void)
1055 {
1056         int ret = MM_ERROR_NONE;
1057         if (g_device_info_changed_cb_table.user_cb) {
1058                 ret = mm_sound_remove_device_information_changed_callback();
1059                 if (ret == MM_ERROR_NONE) {
1060                         g_device_info_changed_cb_table.user_cb = NULL;
1061                         g_device_info_changed_cb_table.user_data = NULL;
1062                 }
1063         } else {
1064                 ret = MM_ERROR_SOUND_INTERNAL;
1065         }
1066
1067         return __convert_sound_manager_error_code(__func__, ret);
1068 }
1069
1070 __attribute__ ((destructor))
1071 void __sound_manager_finalize (void)
1072 {
1073         int ret = MM_ERROR_NONE;
1074
1075         if(g_session_interrupt_cb_table.is_registered){
1076                 LOGI("<ENTER>");
1077                 ret = mm_session_finish();
1078                 if (ret != MM_ERROR_NONE) {
1079                         LOGE("[%s] failed to mm_session_finish(), ret(%p)", __func__, ret);
1080                 }
1081                 g_session_interrupt_cb_table.is_registered = 0;
1082                 LOGI("<LEAVE>");
1083         }
1084 }
1085
1086 __attribute__ ((constructor))
1087 void __sound_manager_initialize (void)
1088 {
1089
1090 }