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"
22 _session_interrupt_info_s g_session_interrupt_cb_table = {0, NULL, NULL};
23 _volume_changed_info_s g_volume_changed_cb_table = {NULL, NULL};
24 _focus_watch_info_s g_focus_watch_cb_table = {-1, NULL, NULL};
25 _device_connected_info_s g_device_connected_cb_table = {NULL, NULL};
26 _device_changed_info_s g_device_info_changed_cb_table = {NULL, NULL};
28 sound_session_type_e g_cached_session = -1;
29 _session_mode_e g_cached_session_mode = -1;
31 /* These variables will be removed when session features are deprecated. */
32 extern int g_stream_info_count;
33 extern pthread_mutex_t g_stream_info_count_mutex;
36 /*temporary variable for set/get voip session mode. When 2.4 feature for routing is fully implemented, it will be removed.*/
37 sound_session_voip_mode_e tmp_mode = -1;
40 int sound_manager_get_max_volume (sound_type_e type, int *max)
42 const char *volume_type = NULL;
43 unsigned int max_level = 0;
44 int ret = MM_ERROR_NONE;
47 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
49 if (type >= SOUND_TYPE_NUM || type < 0)
50 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
51 ret = __convert_sound_type (type, &volume_type);
52 if (ret == MM_ERROR_NONE) {
53 ret = __get_volume_max_level("out", volume_type, &max_level);
54 if (ret == MM_ERROR_NONE)
55 *max = (int)max_level -1; // actual volume step can be max step - 1
58 return __convert_sound_manager_error_code(__func__, ret);
61 int sound_manager_set_volume (sound_type_e type, int volume)
63 int ret = MM_ERROR_NONE;
65 if (type >= SOUND_TYPE_NUM || type < 0)
66 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
68 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
70 ret = mm_sound_volume_set_value(type, volume);
71 LOGI("returns : type=%d, volume=%d, ret=%p", type, volume, ret);
73 return __convert_sound_manager_error_code(__func__, ret);
76 int sound_manager_get_volume (sound_type_e type, int *volume)
78 int ret = MM_ERROR_NONE;
81 if (type >= SOUND_TYPE_NUM || type < 0)
82 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
84 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
86 ret = mm_sound_volume_get_value(type, &uvolume);
87 if (ret == MM_ERROR_NONE)
90 LOGI("returns : type=%d, volume=%d, ret=%p", type, *volume, ret);
92 return __convert_sound_manager_error_code(__func__, ret);
95 int sound_manager_set_current_sound_type (sound_type_e type)
97 int ret = MM_ERROR_NONE;
99 if (type >= SOUND_TYPE_NUM || type < 0)
100 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
102 ret = mm_sound_volume_primary_type_set(type);
104 return __convert_sound_manager_error_code(__func__, ret);
107 int sound_manager_get_current_sound_type (sound_type_e *type)
109 int ret = MM_ERROR_NONE;
112 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
113 ret = mm_sound_volume_get_current_playing_type((volume_type_t *)type);
115 LOGI("returns : type=%d, ret=%p", *type, ret);
117 return __convert_sound_manager_error_code(__func__, ret);
120 int sound_manager_unset_current_sound_type (void)
122 int ret = MM_ERROR_NONE;
124 ret = mm_sound_volume_primary_type_clear();
126 return __convert_sound_manager_error_code(__func__, ret);
129 int sound_manager_set_volume_changed_cb (sound_manager_volume_changed_cb callback, void* user_data)
131 int ret = MM_ERROR_NONE;
133 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data);
134 if (ret == MM_ERROR_NONE) {
135 g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
136 g_volume_changed_cb_table.user_data = user_data;
139 return __convert_sound_manager_error_code(__func__, ret);
142 int sound_manager_unset_volume_changed_cb (void)
144 int ret = MM_ERROR_NONE;
146 if (g_volume_changed_cb_table.user_cb) {
147 ret = mm_sound_remove_volume_changed_callback();
148 if (ret == MM_ERROR_NONE) {
149 g_volume_changed_cb_table.user_cb = NULL;
150 g_volume_changed_cb_table.user_data = NULL;
153 ret = MM_ERROR_SOUND_INTERNAL;
156 return __convert_sound_manager_error_code(__func__, ret);
159 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)
161 int ret = MM_ERROR_NONE;
165 SM_NULL_ARG_CHECK(stream_info);
166 SM_NULL_ARG_CHECK(callback);
168 if (g_session_interrupt_cb_table.is_registered)
169 return __convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INTERNAL);
171 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
173 ret = MM_ERROR_OUT_OF_MEMORY;
175 memset(stream_h, 0, sizeof(sound_stream_info_s));
176 ret = __convert_stream_type(stream_type, stream_h->stream_type);
177 if (ret == MM_ERROR_NONE) {
178 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
179 if (ret == MM_ERROR_NONE) {
180 *stream_info = (sound_stream_info_h)stream_h;
181 LOGI("<< leave : stream_h(%p), index(%u), user_cb(%p), cnt(%d), ret(%p)", stream_h, stream_h->index, stream_h->user_cb, g_stream_info_count, ret);
189 return __convert_sound_manager_error_code(__func__, ret);
192 int sound_manager_destroy_stream_information (sound_stream_info_h stream_info)
194 int ret = MM_ERROR_NONE;
195 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
199 SM_INSTANCE_CHECK(stream_h);
201 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
203 LOGI("<< leave : cnt(%d), ret(%p)", g_stream_info_count, ret);
205 return __convert_sound_manager_error_code(__func__, ret);
208 int sound_manager_add_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
210 int ret = MM_ERROR_NONE;
213 bool added_successfully = false;
214 char *device_type_str = NULL;
216 mm_sound_device_type_e device_type;
217 mm_sound_device_io_direction_e device_direction;
218 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
222 SM_INSTANCE_CHECK(stream_h);
223 SM_NULL_ARG_CHECK(device);
225 if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
226 ret = mm_sound_get_device_id(device, &device_id);
228 return __convert_sound_manager_error_code(__func__, ret);
230 ret = mm_sound_get_device_type(device, &device_type);
232 return __convert_sound_manager_error_code(__func__, ret);
234 ret = __convert_device_type(device_type, &device_type_str);
236 return __convert_sound_manager_error_code(__func__, ret);
238 ret = mm_sound_get_device_io_direction(device, &device_direction);
240 return __convert_sound_manager_error_code(__func__, ret);
242 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
243 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
244 if (stream_h->stream_conf_info.avail_in_devices[i]) {
245 if (!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
246 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
247 if (!stream_h->manual_route_info.route_in_devices[j]) {
248 stream_h->manual_route_info.route_in_devices[j] = (unsigned int)device_id;
249 added_successfully = true;
252 if (stream_h->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
253 /* it was already set */
254 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED);
263 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
264 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
265 if (stream_h->stream_conf_info.avail_out_devices[i]) {
266 if (!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
267 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
268 if (!stream_h->manual_route_info.route_out_devices[j]) {
269 stream_h->manual_route_info.route_out_devices[j] = (unsigned int)device_id;
270 added_successfully = true;
273 if (stream_h->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
274 /* it was already set */
275 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED);
286 if (!added_successfully) {
287 ret = MM_ERROR_POLICY_INTERNAL;
290 LOGI("<< leave : ret(%p)", ret);
292 return __convert_sound_manager_error_code(__func__, ret);
295 int sound_manager_remove_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device)
297 int ret = MM_ERROR_NONE;
300 bool removed_successfully = false;
301 char *device_type_str = NULL;
303 mm_sound_device_type_e device_type;
304 mm_sound_device_io_direction_e device_direction;
305 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
309 SM_INSTANCE_CHECK(stream_h);
310 SM_NULL_ARG_CHECK(device);
312 if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
313 ret = mm_sound_get_device_id(device, &device_id);
315 return __convert_sound_manager_error_code(__func__, ret);
317 ret = mm_sound_get_device_type(device, &device_type);
319 return __convert_sound_manager_error_code(__func__, ret);
321 ret = __convert_device_type(device_type, &device_type_str);
322 ret = mm_sound_get_device_io_direction(device, &device_direction);
324 return __convert_sound_manager_error_code(__func__, ret);
326 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
327 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
328 if (stream_h->stream_conf_info.avail_in_devices[i]) {
329 if (!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
330 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
331 if (stream_h->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
332 removed_successfully = true;
333 stream_h->manual_route_info.route_in_devices[j] = 0;
343 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
344 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
345 if (stream_h->stream_conf_info.avail_out_devices[i]) {
346 if (!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
347 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
348 if (stream_h->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
349 removed_successfully = true;
350 stream_h->manual_route_info.route_out_devices[j] = 0;
362 if (!removed_successfully) {
363 ret = MM_ERROR_INVALID_ARGUMENT;
366 LOGI("<< leave : ret(%p)", ret);
368 return __convert_sound_manager_error_code(__func__, ret);
371 int sound_manager_apply_stream_routing (sound_stream_info_h stream_info)
373 int ret = MM_ERROR_NONE;
375 bool need_to_apply = false;
376 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
380 SM_INSTANCE_CHECK(stream_h);
382 if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) {
383 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
384 if (stream_h->manual_route_info.route_in_devices[i]) {
385 need_to_apply = true;
388 if (stream_h->manual_route_info.route_out_devices[i]) {
389 need_to_apply = true;
394 ret = __set_manual_route_info(stream_h->index, &stream_h->manual_route_info);
396 __convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_STATE);
399 ret = MM_ERROR_SOUND_INVALID_STATE;
402 LOGI("<< leave : ret(%p)", ret);
404 return __convert_sound_manager_error_code(__func__, ret);
407 int sound_manager_acquire_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
409 int ret = MM_ERROR_NONE;
410 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
414 SM_INSTANCE_CHECK(stream_h);
416 ret = mm_sound_acquire_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
417 if (ret == MM_ERROR_NONE) {
418 stream_h->acquired_focus |= focus_mask;
421 LOGI("<< leave : ret(%p)", ret);
423 return __convert_sound_manager_error_code(__func__, ret);
426 int sound_manager_release_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info)
428 int ret = MM_ERROR_NONE;
429 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
433 SM_INSTANCE_CHECK(stream_h);
435 ret = mm_sound_release_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
436 if (ret == MM_ERROR_NONE) {
437 stream_h->acquired_focus &= ~focus_mask;
440 LOGI("<< leave : ret(%p)", ret);
442 return __convert_sound_manager_error_code(__func__, ret);
445 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)
447 int ret = MM_ERROR_NONE;
448 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
452 SM_INSTANCE_CHECK(stream_h);
453 if (!state_for_playback && !state_for_recording)
454 ret = MM_ERROR_INVALID_ARGUMENT;
456 if (state_for_playback)
457 *state_for_playback = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
458 if (state_for_recording)
459 *state_for_recording = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
461 LOGI("<< leave : acquired_focus(%p)", stream_h->acquired_focus);
463 return __convert_sound_manager_error_code(__func__, ret);
466 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)
468 int ret = MM_ERROR_NONE;
473 SM_NULL_ARG_CHECK(callback);
474 SM_ENTER_CRITICAL_SECTION_WITH_RETURN( &g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
476 if (!g_focus_watch_cb_table.user_cb) {
477 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
478 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, &id);
479 if (ret == MM_ERROR_NONE) {
480 g_focus_watch_cb_table.index = id;
481 g_focus_watch_cb_table.user_cb = callback;
482 g_focus_watch_cb_table.user_data = user_data;
485 ret = MM_ERROR_SOUND_INTERNAL;
488 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
490 LOGI("<< leave : cnt(%d), ret(%p)", g_stream_info_count, ret);
492 return __convert_sound_manager_error_code(__func__, ret);
495 int sound_manager_unset_focus_state_watch_cb (void)
497 int ret = MM_ERROR_NONE;
501 SM_ENTER_CRITICAL_SECTION_WITH_RETURN( &g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
503 if (g_focus_watch_cb_table.user_cb) {
504 ret = mm_sound_unset_focus_watch_callback(g_focus_watch_cb_table.index);
505 if (ret == MM_ERROR_NONE) {
506 g_focus_watch_cb_table.index = -1;
507 g_focus_watch_cb_table.user_cb = NULL;
508 g_focus_watch_cb_table.user_data = NULL;
509 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret);
511 ret = MM_ERROR_SOUND_INTERNAL;
514 ret = MM_ERROR_SOUND_INTERNAL;
517 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
519 LOGI("<< leave : cnt(%d), ret(%p)", g_stream_info_count, ret);
521 return __convert_sound_manager_error_code(__func__, ret);
524 int sound_manager_set_session_type (sound_session_type_e type)
526 int ret = MM_ERROR_NONE;
527 int cur_session = -1;
528 int new_session = MM_SESSION_TYPE_MEDIA;
530 LOGI(">> enter : type=%d", type);
532 if (type < SOUND_SESSION_TYPE_MEDIA || type > SOUND_SESSION_TYPE_VOIP)
533 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
535 /* it is not supported both session and stream feature at the same time */
536 if (g_stream_info_count)
537 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
540 case SOUND_SESSION_TYPE_MEDIA:
541 new_session = MM_SESSION_TYPE_MEDIA;
543 case SOUND_SESSION_TYPE_ALARM:
544 new_session = MM_SESSION_TYPE_ALARM;
546 case SOUND_SESSION_TYPE_NOTIFICATION:
547 new_session = MM_SESSION_TYPE_NOTIFY;
549 case SOUND_SESSION_TYPE_EMERGENCY:
550 new_session = MM_SESSION_TYPE_EMERGENCY;
552 case SOUND_SESSION_TYPE_VOIP:
553 new_session = MM_SESSION_TYPE_VOIP;
557 /* valid session check */
558 ret = mm_session_get_current_type(&cur_session);
559 if (ret == MM_ERROR_NONE) {
560 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
561 if (type > SOUND_SESSION_TYPE_MEDIA) {
562 LOGE("<< leave : Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
563 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
566 if (cur_session == MM_SESSION_TYPE_VIDEOCALL ||
567 cur_session >= MM_SESSION_TYPE_VOICE_RECOGNITION) {
568 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
572 if (g_session_interrupt_cb_table.is_registered) {
573 if (new_session == cur_session ||
574 ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
575 LOGI("<< leave : already set type=%d, ret=%p", type, ret);
576 return SOUND_MANAGER_ERROR_NONE;
578 ret = mm_session_finish();
579 if (ret != MM_ERROR_NONE) {
580 return __convert_sound_manager_error_code(__func__, ret);
582 g_session_interrupt_cb_table.is_registered = 0;
583 g_cached_session_mode = -1;
586 ret = mm_session_init_ex(new_session , _session_interrupt_cb, NULL);
587 if (ret == MM_ERROR_NONE) {
588 g_session_interrupt_cb_table.is_registered = 1;
590 if (new_session == MM_SESSION_TYPE_VOIP || new_session == MM_SESSION_TYPE_CALL) {
591 /* set default sub-session for voip */
592 ret = mm_session_set_subsession (MM_SUBSESSION_TYPE_RINGTONE, MM_SUBSESSION_OPTION_NONE);
593 if (ret != MM_ERROR_NONE) {
594 return __convert_sound_manager_error_code(__func__, ret);
596 g_cached_session_mode = _SESSION_MODE_RINGTONE;
598 LOGI("<< leave : type=%d, ret=%p", type, ret);
600 return __convert_sound_manager_error_code(__func__, ret);
603 int sound_manager_get_session_type (sound_session_type_e *type)
605 int ret = MM_ERROR_NONE;
609 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
610 ret = mm_session_get_current_type(&cur_session);
612 cur_session = SOUND_SESSION_TYPE_DEFAULT;
613 if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
614 (cur_session != MM_SESSION_TYPE_VOIP)) {
615 if (g_cached_session != -1)
616 cur_session = g_cached_session;
617 else //will be never reach here. just prevent code
618 cur_session = SOUND_SESSION_TYPE_DEFAULT;
621 switch (cur_session) {
622 case MM_SESSION_TYPE_MEDIA:
623 case MM_SESSION_TYPE_MEDIA_RECORD:
624 *type = SOUND_SESSION_TYPE_MEDIA;
626 case MM_SESSION_TYPE_ALARM:
627 *type = SOUND_SESSION_TYPE_ALARM;
629 case MM_SESSION_TYPE_NOTIFY:
630 *type = SOUND_SESSION_TYPE_NOTIFICATION;
632 case MM_SESSION_TYPE_EMERGENCY:
633 *type = SOUND_SESSION_TYPE_EMERGENCY;
635 case MM_SESSION_TYPE_VOIP:
636 *type = SOUND_SESSION_TYPE_VOIP;
643 LOGI("returns : type=%d, ret=%p", *type, ret);
648 int sound_manager_set_media_session_option (sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
650 int ret = MM_ERROR_NONE;
652 int session_option = 0;
655 LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
657 if (s_option < 0 || s_option > SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
658 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
659 if (d_option < 0 || d_option > SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
660 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
662 ret = mm_session_get_current_information(&session, &session_option);
663 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
664 LOGW("need to set session type first");
665 return __convert_sound_manager_error_code(__func__, ret);
666 } else if (ret == MM_ERROR_NONE && session > MM_SESSION_TYPE_MEDIA) {
667 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
668 if (!g_session_interrupt_cb_table.is_registered) {
669 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
670 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
673 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
678 case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
679 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
680 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
682 return __convert_sound_manager_error_code(__func__, ret);
687 case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
688 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
689 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
691 return __convert_sound_manager_error_code(__func__, ret);
699 case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
700 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
701 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
703 return __convert_sound_manager_error_code(__func__, ret);
708 case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
709 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
710 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
712 return __convert_sound_manager_error_code(__func__, ret);
720 LOGI("<< leave : updated");
722 LOGI("<< leave : already set same option(%x), skip it", session_option);
725 return __convert_sound_manager_error_code(__func__, ret);
728 int sound_manager_get_media_session_option (sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
730 int ret = MM_ERROR_NONE;
732 int session_options = 0;
736 if (s_option == NULL || d_option == NULL)
737 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
739 ret = mm_session_get_current_information(&session, &session_options);
741 return __convert_sound_manager_error_code(__func__, ret);
742 } else if (session > SOUND_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);
753 if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS) {
754 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
756 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
758 if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
759 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
761 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
764 LOGI("<< leave : option for starting=%d, for during play=%d", *s_option, *d_option);
766 return SOUND_MANAGER_ERROR_NONE;
769 int sound_manager_set_media_session_resumption_option (sound_session_option_for_resumption_e option)
771 int ret = MM_ERROR_NONE;
773 int session_option = 0;
776 LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
778 if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
779 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
781 ret = mm_session_get_current_information(&session, &session_option);
782 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
783 LOGW("need to set session type first");
784 return __convert_sound_manager_error_code(__func__, ret);
785 } else if (ret == MM_ERROR_NONE && session > MM_SESSION_TYPE_MEDIA) {
786 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
787 if (!g_session_interrupt_cb_table.is_registered) {
788 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
789 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
792 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
797 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
798 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
799 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
801 return __convert_sound_manager_error_code(__func__, ret);
806 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
807 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
808 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
810 return __convert_sound_manager_error_code(__func__, ret);
818 LOGI("<< leave : updated");
820 LOGI("<< leave : already set same option(%x), skip it", session_option);
823 return __convert_sound_manager_error_code(__func__, ret);
826 int sound_manager_get_media_session_resumption_option (sound_session_option_for_resumption_e *option)
828 int ret = MM_ERROR_NONE;
830 int session_options = 0;
835 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
836 ret = mm_session_get_current_information(&session, &session_options);
838 return __convert_sound_manager_error_code(__func__, ret);
839 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
840 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
841 if (!g_session_interrupt_cb_table.is_registered) {
842 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
843 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
846 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
850 if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
851 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
853 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
856 LOGI("<< leave : option for resumption=%d (0:by system, 1:by system or media paused)", *option);
858 return SOUND_MANAGER_ERROR_NONE;
861 int sound_manager_set_voip_session_mode (sound_session_voip_mode_e mode)
863 int ret = MM_ERROR_NONE;
865 int session_options = 0;
867 LOGI(">> enter : mode=%d", mode);
869 ret = mm_session_get_current_information(&session, &session_options);
870 if (ret != MM_ERROR_NONE) {
871 return __convert_sound_manager_error_code(__func__, ret);
872 } else if (session != MM_SESSION_TYPE_VOIP) {
873 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
875 if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
876 ret = MM_ERROR_INVALID_ARGUMENT;
877 return __convert_sound_manager_error_code(__func__, ret);
879 ret = __set_session_mode ((_session_mode_e)mode);
882 /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */
886 LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret);
888 return __convert_sound_manager_error_code(__func__, ret);
891 int sound_manager_get_voip_session_mode (sound_session_voip_mode_e *mode)
893 int ret = MM_ERROR_NONE;
895 int session_options = 0;
897 _session_mode_e _mode = 0;
901 LOGI("mode is null");
902 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
905 ret = mm_session_get_current_information(&session, &session_options);
906 if (ret != MM_ERROR_NONE) {
907 LOGI("session = %d, option = %d", session, session_options);
908 return __convert_sound_manager_error_code(__func__, ret);
909 } else if (session != MM_SESSION_TYPE_VOIP) {
910 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
914 /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */
917 ret = __get_session_mode(&_mode);
918 if (ret == MM_ERROR_NONE)
919 *mode = (sound_session_voip_mode_e)_mode;
922 LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret);
924 return __convert_sound_manager_error_code(__func__, ret);
927 int sound_manager_set_session_interrupted_cb (sound_session_interrupted_cb callback, void *user_data)
929 int ret = MM_ERROR_NONE;
930 if (callback == NULL)
931 return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
933 /* it is not supported both session and stream feature at the same time */
934 if (g_stream_info_count)
935 return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
937 if (g_session_interrupt_cb_table.is_registered == 0) {
938 ret = mm_session_init_ex(SOUND_SESSION_TYPE_DEFAULT /*default*/ , _session_interrupt_cb, NULL);
940 return __convert_sound_manager_error_code(__func__, ret);
941 g_session_interrupt_cb_table.is_registered = 1;
944 g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
945 g_session_interrupt_cb_table.user_data = user_data;
946 return SOUND_MANAGER_ERROR_NONE;
949 int sound_manager_unset_session_interrupted_cb (void)
951 int ret = MM_ERROR_NONE;
952 if (g_session_interrupt_cb_table.user_cb) {
953 g_session_interrupt_cb_table.user_cb = NULL;
954 g_session_interrupt_cb_table.user_data = NULL;
956 ret = MM_ERROR_SOUND_INTERNAL;
958 return __convert_sound_manager_error_code(__func__, ret);
961 int sound_manager_get_current_device_list (sound_device_mask_e device_mask, sound_device_list_h *device_list)
963 int ret = MM_ERROR_NONE;
964 ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
966 return __convert_sound_manager_error_code(__func__, ret);
969 int sound_manager_get_next_device (sound_device_list_h device_list, sound_device_h *device)
971 int ret = MM_ERROR_NONE;
972 ret = mm_sound_get_next_device(device_list, device);
974 return __convert_sound_manager_error_code(__func__, ret);
977 int sound_manager_get_prev_device (sound_device_list_h device_list, sound_device_h *device)
979 int ret = MM_ERROR_NONE;
980 ret = mm_sound_get_prev_device(device_list, device);
982 return __convert_sound_manager_error_code(__func__, ret);
985 int sound_manager_get_device_type (sound_device_h device, sound_device_type_e *type)
987 int ret = MM_ERROR_NONE;
988 ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)type);
990 return __convert_sound_manager_error_code(__func__, ret);
993 int sound_manager_get_device_io_direction (sound_device_h device, sound_device_io_direction_e *io_direction)
995 int ret = MM_ERROR_NONE;
996 mm_sound_device_io_direction_e mm_sound_io_direction;
997 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
998 if (ret == MM_ERROR_NONE) {
999 ret = __convert_device_io_direction(mm_sound_io_direction, io_direction);
1002 return __convert_sound_manager_error_code(__func__, ret);
1005 int sound_manager_get_device_id (sound_device_h device, int *id)
1007 int ret = MM_ERROR_NONE;
1008 ret = mm_sound_get_device_id(device, id);
1010 return __convert_sound_manager_error_code(__func__, ret);
1013 int sound_manager_get_device_name (sound_device_h device, char **name)
1015 int ret = MM_ERROR_NONE;
1016 ret = mm_sound_get_device_name(device, name);
1018 return __convert_sound_manager_error_code(__func__, ret);
1021 int sound_manager_get_device_state (sound_device_h device, sound_device_state_e *state)
1023 int ret = MM_ERROR_NONE;
1024 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1026 return __convert_sound_manager_error_code(__func__, ret);
1029 int sound_manager_set_device_connected_cb (sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1031 int ret = MM_ERROR_NONE;
1032 ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data);
1033 if (ret == MM_ERROR_NONE) {
1034 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1035 g_device_connected_cb_table.user_data = user_data;
1038 return __convert_sound_manager_error_code(__func__, ret);
1041 int sound_manager_unset_device_connected_cb (void)
1043 int ret = MM_ERROR_NONE;
1044 if (g_device_connected_cb_table.user_cb) {
1045 ret = mm_sound_remove_device_connected_callback();
1046 if (ret == MM_ERROR_NONE) {
1047 g_device_connected_cb_table.user_cb = NULL;
1048 g_device_connected_cb_table.user_data = NULL;
1051 ret = MM_ERROR_SOUND_INTERNAL;
1054 return __convert_sound_manager_error_code(__func__, ret);
1057 int sound_manager_set_device_information_changed_cb (sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1059 int ret = MM_ERROR_NONE;
1060 ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data);
1061 if (ret == MM_ERROR_NONE) {
1062 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1063 g_device_info_changed_cb_table.user_data = user_data;
1066 return __convert_sound_manager_error_code(__func__, ret);
1069 int sound_manager_unset_device_information_changed_cb (void)
1071 int ret = MM_ERROR_NONE;
1072 if (g_device_info_changed_cb_table.user_cb) {
1073 ret = mm_sound_remove_device_information_changed_callback();
1074 if (ret == MM_ERROR_NONE) {
1075 g_device_info_changed_cb_table.user_cb = NULL;
1076 g_device_info_changed_cb_table.user_data = NULL;
1079 ret = MM_ERROR_SOUND_INTERNAL;
1082 return __convert_sound_manager_error_code(__func__, ret);
1085 __attribute__ ((destructor))
1086 void __sound_manager_finalize (void)
1088 int ret = MM_ERROR_NONE;
1090 if (g_session_interrupt_cb_table.is_registered) {
1092 ret = mm_session_finish();
1093 if (ret != MM_ERROR_NONE) {
1094 LOGE("[%s] failed to mm_session_finish(), ret(%p)", __func__, ret);
1096 g_session_interrupt_cb_table.is_registered = 0;
1101 __attribute__ ((constructor))
1102 void __sound_manager_initialize (void)