2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "sound_manager.h"
18 #include "sound_manager_private.h"
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};
26 sound_session_type_e g_cached_session = -1;
27 _session_mode_e g_cached_session_mode = -1;
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;
34 int sound_manager_get_max_volume (sound_type_e type, int *max)
36 const char *volume_type = NULL;
37 unsigned int max_level = 0;
38 int ret = MM_ERROR_NONE;
40 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
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);
46 ret = __get_volume_max_level("out", volume_type, &max_level);
49 *max = (int)max_level -1; // actual volume step can be max step - 1
51 return __convert_sound_manager_error_code(__func__, ret);
54 int sound_manager_set_volume (sound_type_e type, int volume)
56 if(type >= SOUND_TYPE_NUM || type < 0)
57 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
59 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
61 int ret = mm_sound_volume_set_value(type, volume);
62 LOGI("returns : type=%d, volume=%d, ret=%p", type, volume, ret);
64 return __convert_sound_manager_error_code(__func__, ret);
67 int sound_manager_get_volume (sound_type_e type, int *volume)
70 if(type >= SOUND_TYPE_NUM || type < 0)
71 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
73 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
74 int ret = mm_sound_volume_get_value(type, &uvolume);
79 LOGI("returns : type=%d, volume=%d, ret=%p", type, *volume, ret);
81 return __convert_sound_manager_error_code(__func__, ret);
84 int sound_manager_set_current_sound_type (sound_type_e type)
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);
90 ret = mm_sound_volume_primary_type_set(type);
92 return __convert_sound_manager_error_code(__func__, ret);
95 int sound_manager_get_current_sound_type (sound_type_e *type)
97 int ret = MM_ERROR_NONE;
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);
102 LOGI("returns : type=%d, ret=%p", *type, ret);
104 return __convert_sound_manager_error_code(__func__, ret);
107 int sound_manager_unset_current_sound_type (void)
109 int ret = MM_ERROR_NONE;
110 ret = mm_sound_volume_primary_type_clear();
112 return __convert_sound_manager_error_code(__func__, ret);
115 int sound_manager_set_volume_changed_cb (sound_manager_volume_changed_cb callback, void* user_data)
117 int ret = MM_ERROR_NONE;
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;
125 return __convert_sound_manager_error_code(__func__, ret);
128 int sound_manager_unset_volume_changed_cb (void)
130 int ret = MM_ERROR_NONE;
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;
139 ret = MM_ERROR_SOUND_INTERNAL;
142 return __convert_sound_manager_error_code(__func__, ret);
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)
147 int ret = MM_ERROR_NONE;
151 SM_NULL_ARG_CHECK(stream_info);
152 SM_NULL_ARG_CHECK(callback);
154 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
156 ret = MM_ERROR_OUT_OF_MEMORY;
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);
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);
169 return __convert_sound_manager_error_code(__func__, ret);
172 int sound_manager_destroy_stream_information (sound_stream_info_h stream_info)
174 int ret = MM_ERROR_NONE;
175 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
179 SM_INSTANCE_CHECK(stream_h);
181 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
183 LOGI("<< leave : ret(%p)", ret);
185 return __convert_sound_manager_error_code(__func__, ret);
188 int sound_manager_add_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
190 int ret = MM_ERROR_NONE;
193 bool added_successfully = false;
194 char *device_type_str = NULL;
196 mm_sound_device_io_direction_e device_direction;
197 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
201 SM_INSTANCE_CHECK(stream_h);
202 SM_NULL_ARG_CHECK(device);
204 if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
205 ret = mm_sound_get_device_id(device, &device_id);
207 return __convert_sound_manager_error_code(__func__, ret);
209 ret = mm_sound_get_device_type(device, &device_type_str);
211 return __convert_sound_manager_error_code(__func__, ret);
213 ret = mm_sound_get_device_io_direction(device, &device_direction);
215 return __convert_sound_manager_error_code(__func__, ret);
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;
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);
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;
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);
261 if (!added_successfully) {
262 ret = MM_ERROR_POLICY_INTERNAL;
265 LOGI("<< leave : ret(%p)", ret);
267 return __convert_sound_manager_error_code(__func__, ret);
270 int sound_manager_remove_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
272 int ret = MM_ERROR_NONE;
275 bool removed_successfully = false;
276 char *device_type_str = NULL;
278 mm_sound_device_io_direction_e device_direction;
279 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
283 SM_INSTANCE_CHECK(stream_h);
284 SM_NULL_ARG_CHECK(device);
286 if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
287 ret = mm_sound_get_device_id(device, &device_id);
289 return __convert_sound_manager_error_code(__func__, ret);
291 ret = mm_sound_get_device_type(device, &device_type_str);
293 return __convert_sound_manager_error_code(__func__, ret);
295 ret = mm_sound_get_device_io_direction(device, &device_direction);
297 return __convert_sound_manager_error_code(__func__, ret);
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;
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;
335 if (!removed_successfully) {
336 ret = MM_ERROR_INVALID_ARGUMENT;
339 LOGI("<< leave : ret(%p)", ret);
341 return __convert_sound_manager_error_code(__func__, ret);
344 int sound_manager_apply_stream_routing (sound_stream_info_h stream_info)
346 int ret = MM_ERROR_NONE;
348 bool need_to_apply = false;
349 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
353 SM_INSTANCE_CHECK(stream_h);
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;
361 if (stream_h->manual_route_info.route_out_devices[i]) {
362 need_to_apply = true;
367 ret = __set_manual_route_info(stream_h->index, &stream_h->manual_route_info);
369 __convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_STATE);
372 ret = MM_ERROR_SOUND_INVALID_STATE;
375 LOGI("<< leave : ret(%p)", ret);
377 return __convert_sound_manager_error_code(__func__, ret);
380 int sound_manager_acquire_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
382 int ret = MM_ERROR_NONE;
383 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
387 SM_INSTANCE_CHECK(stream_h);
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;
394 LOGI("<< leave : ret(%p)", ret);
396 return __convert_sound_manager_error_code(__func__, ret);
399 int sound_manager_release_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
401 int ret = MM_ERROR_NONE;
402 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
406 SM_INSTANCE_CHECK(stream_h);
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;
413 LOGI("<< leave : ret(%p)", ret);
415 return __convert_sound_manager_error_code(__func__, ret);
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)
420 int ret = MM_ERROR_NONE;
421 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
425 SM_INSTANCE_CHECK(stream_h);
426 if (!state_for_playback && !state_for_recording)
427 ret = MM_ERROR_INVALID_ARGUMENT;
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;
434 LOGI("<< leave : acquired_focus(%p)", stream_h->acquired_focus);
436 return __convert_sound_manager_error_code(__func__, ret);
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)
441 int ret = MM_ERROR_NONE;
445 SM_NULL_ARG_CHECK(callback);
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;
454 ret = MM_ERROR_SOUND_INTERNAL;
457 LOGI("<< leave : ret(%p)", ret);
459 return __convert_sound_manager_error_code(__func__, ret);
462 int sound_manager_unset_focus_state_watch_cb (void)
464 int ret = MM_ERROR_NONE;
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;
474 ret = MM_ERROR_SOUND_INTERNAL;
477 ret = MM_ERROR_SOUND_INTERNAL;
480 LOGI("<< leave : ret(%p)", ret);
482 return __convert_sound_manager_error_code(__func__, ret);
485 int sound_manager_set_session_type (sound_session_type_e type)
487 int ret = MM_ERROR_NONE;
488 int cur_session = -1;
489 int new_session = MM_SESSION_TYPE_MEDIA;
491 LOGI(">> enter : type=%d", type);
493 if(type < SOUND_SESSION_TYPE_MEDIA || type > SOUND_SESSION_TYPE_VOIP)
494 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
497 case SOUND_SESSION_TYPE_MEDIA:
498 new_session = MM_SESSION_TYPE_MEDIA;
500 case SOUND_SESSION_TYPE_ALARM:
501 new_session = MM_SESSION_TYPE_ALARM;
503 case SOUND_SESSION_TYPE_NOTIFICATION:
504 new_session = MM_SESSION_TYPE_NOTIFY;
506 case SOUND_SESSION_TYPE_EMERGENCY:
507 new_session = MM_SESSION_TYPE_EMERGENCY;
509 case SOUND_SESSION_TYPE_VOIP:
510 new_session = MM_SESSION_TYPE_VOIP;
514 /* valid session check */
515 ret = mm_session_get_current_type(&cur_session);
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);
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);
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;
535 ret = mm_session_finish();
536 if (ret != MM_ERROR_NONE) {
537 return __convert_sound_manager_error_code(__func__, ret);
539 g_session_interrupt_cb_table.is_registered = 0;
540 g_cached_session_mode = -1;
543 ret = mm_session_init_ex(new_session , _session_interrupt_cb, NULL);
545 g_session_interrupt_cb_table.is_registered = 1;
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);
553 g_cached_session_mode = _SESSION_MODE_RINGTONE;
555 LOGI("<< leave : type=%d, ret=%p", type, ret);
557 return __convert_sound_manager_error_code(__func__, ret);
560 int sound_manager_get_session_type (sound_session_type_e *type)
562 int ret = MM_ERROR_NONE;
566 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
567 ret = mm_session_get_current_type(&cur_session);
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;
578 switch(cur_session) {
579 case MM_SESSION_TYPE_MEDIA:
580 case MM_SESSION_TYPE_MEDIA_RECORD:
581 *type = SOUND_SESSION_TYPE_MEDIA;
583 case MM_SESSION_TYPE_ALARM:
584 *type = SOUND_SESSION_TYPE_ALARM;
586 case MM_SESSION_TYPE_NOTIFY:
587 *type = SOUND_SESSION_TYPE_NOTIFICATION;
589 case MM_SESSION_TYPE_EMERGENCY:
590 *type = SOUND_SESSION_TYPE_EMERGENCY;
592 case MM_SESSION_TYPE_VOIP:
593 *type = SOUND_SESSION_TYPE_VOIP;
600 LOGI("returns : type=%d, ret=%p", *type, ret);
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)
607 int ret = MM_ERROR_NONE;
609 int session_option = 0;
612 LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
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);
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);
630 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
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);
639 return __convert_sound_manager_error_code(__func__, ret);
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);
648 return __convert_sound_manager_error_code(__func__, ret);
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);
660 return __convert_sound_manager_error_code(__func__, ret);
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);
669 return __convert_sound_manager_error_code(__func__, ret);
677 LOGI("<< leave : updated");
679 LOGI("<< leave : already set same option(%x), skip it", session_option);
682 return __convert_sound_manager_error_code(__func__, ret);
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)
687 int ret = MM_ERROR_NONE;
689 int session_options = 0;
693 if( s_option == NULL || d_option == NULL )
694 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
696 ret = mm_session_get_current_information(&session, &session_options);
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);
706 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
710 if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS) {
711 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
713 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
715 if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
716 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
718 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
721 LOGI("<< leave : option for starting=%d, for during play=%d", *s_option, *d_option);
723 return SOUND_MANAGER_ERROR_NONE;
726 int sound_manager_set_media_session_resumption_option (sound_session_option_for_resumption_e option)
728 int ret = MM_ERROR_NONE;
730 int session_option = 0;
733 LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
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);
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);
749 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
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);
758 return __convert_sound_manager_error_code(__func__, ret);
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);
767 return __convert_sound_manager_error_code(__func__, ret);
775 LOGI("<< leave : updated");
777 LOGI("<< leave : already set same option(%x), skip it", session_option);
780 return __convert_sound_manager_error_code(__func__, ret);
783 int sound_manager_get_media_session_resumption_option (sound_session_option_for_resumption_e *option)
785 int ret = MM_ERROR_NONE;
787 int session_options = 0;
792 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
793 ret = mm_session_get_current_information(&session, &session_options);
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);
803 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
807 if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
808 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
810 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
813 LOGI("<< leave : option for resumption=%d (0:by system, 1:by system or media paused)", *option);
815 return SOUND_MANAGER_ERROR_NONE;
818 int sound_manager_set_voip_session_mode (sound_session_voip_mode_e mode)
820 int ret = MM_ERROR_NONE;
822 int session_options = 0;
824 LOGI(">> enter : mode=%d", mode);
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);
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);
836 ret = __set_session_mode ((_session_mode_e)mode);
839 /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */
843 LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret);
845 return __convert_sound_manager_error_code(__func__, ret);
848 int sound_manager_get_voip_session_mode (sound_session_voip_mode_e *mode)
850 int ret = MM_ERROR_NONE;
852 int session_options = 0;
853 _session_mode_e _mode = 0;
856 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
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);
865 ret = __get_session_mode(&_mode);
866 if (ret == MM_ERROR_NONE)
867 *mode = (sound_session_voip_mode_e)_mode;
870 /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */
874 LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret);
876 return __convert_sound_manager_error_code(__func__, ret);
879 int sound_manager_set_session_interrupted_cb (sound_session_interrupted_cb callback, void *user_data)
881 int ret = MM_ERROR_NONE;
883 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
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);
888 return __convert_sound_manager_error_code(__func__, ret);
889 g_session_interrupt_cb_table.is_registered = 1;
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;
897 int sound_manager_unset_session_interrupted_cb (void)
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;
904 ret = MM_ERROR_SOUND_INTERNAL;
906 return __convert_sound_manager_error_code(__func__, ret);
909 int sound_manager_get_current_device_list (sound_device_mask_e device_mask, sound_device_list_h *device_list)
911 int ret = MM_ERROR_NONE;
912 ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
914 return __convert_sound_manager_error_code(__func__, ret);
917 int sound_manager_get_next_device (sound_device_list_h device_list, sound_device_h *device)
919 int ret = MM_ERROR_NONE;
920 ret = mm_sound_get_next_device(device_list, device);
922 return __convert_sound_manager_error_code(__func__, ret);
925 int sound_manager_get_prev_device (sound_device_list_h device_list, sound_device_h *device)
927 int ret = MM_ERROR_NONE;
928 ret = mm_sound_get_prev_device(device_list, device);
930 return __convert_sound_manager_error_code(__func__, ret);
933 int sound_manager_get_device_type (sound_device_h device, sound_device_type_e *type)
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);
942 return __convert_sound_manager_error_code(__func__, ret);
945 int sound_manager_get_device_io_direction (sound_device_h device, sound_device_io_direction_e *io_direction)
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);
954 return __convert_sound_manager_error_code(__func__, ret);
957 int sound_manager_get_device_id (sound_device_h device, int *id)
959 int ret = MM_ERROR_NONE;
960 ret = mm_sound_get_device_id(device, id);
962 return __convert_sound_manager_error_code(__func__, ret);
965 int sound_manager_get_device_name (sound_device_h device, char **name)
967 int ret = MM_ERROR_NONE;
968 ret = mm_sound_get_device_name(device, name);
970 return __convert_sound_manager_error_code(__func__, ret);
973 int sound_manager_get_device_state (sound_device_h device, sound_device_state_e *state)
975 int ret = MM_ERROR_NONE;
976 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
978 return __convert_sound_manager_error_code(__func__, ret);
981 int sound_manager_set_device_connected_cb (sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
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;
990 return __convert_sound_manager_error_code(__func__, ret);
993 int sound_manager_unset_device_connected_cb (void)
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;
1003 ret = MM_ERROR_SOUND_INTERNAL;
1006 return __convert_sound_manager_error_code(__func__, ret);
1009 int sound_manager_set_device_information_changed_cb (sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
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;
1018 return __convert_sound_manager_error_code(__func__, ret);
1021 int sound_manager_unset_device_information_changed_cb (void)
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;
1031 ret = MM_ERROR_SOUND_INTERNAL;
1034 return __convert_sound_manager_error_code(__func__, ret);
1037 __attribute__ ((destructor))
1038 void __sound_manager_finalize (void)
1040 int ret = MM_ERROR_NONE;
1042 if(g_session_interrupt_cb_table.is_registered){
1044 ret = mm_session_finish();
1045 if (ret != MM_ERROR_NONE) {
1046 LOGE("[%s] failed to mm_session_finish(), ret(%p)", __func__, ret);
1048 g_session_interrupt_cb_table.is_registered = 0;
1053 __attribute__ ((constructor))
1054 void __sound_manager_initialize (void)