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"
21 _session_interrupt_info_s g_session_interrupt_cb_table = {0, 0, NULL, NULL};
22 _volume_changed_info_s g_volume_changed_cb_table = {0, NULL, NULL};
23 _device_connected_info_s g_device_connected_cb_table = {0, NULL, NULL};
24 _device_changed_info_s g_device_info_changed_cb_table = {0, NULL, NULL};
25 _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
27 sound_session_type_e g_cached_session = -1;
28 _session_mode_e g_cached_session_mode = -1;
29 int g_cached_voip_device_id = -1;
30 extern sound_stream_info_s *g_voip_stream_info;
31 extern virtual_sound_stream_info_s *g_voip_vstream_h;
33 /* These variables will be removed when session features are deprecated. */
34 extern int g_stream_info_count;
35 extern pthread_mutex_t g_stream_info_count_mutex;
36 pthread_mutex_t g_interrupt_cb_mutex, g_device_info_cb_mutex, g_device_conn_cb_mutex, g_volume_cb_mutex;
38 int sound_manager_get_max_volume(sound_type_e type, int *max)
40 const char *volume_type = NULL;
41 unsigned int max_level = 0;
42 int ret = MM_ERROR_NONE;
44 SM_NULL_ARG_CHECK(max);
45 if (type >= SOUND_TYPE_NUM || type < 0)
46 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
48 ret = _convert_sound_type(type, &volume_type);
49 if (ret == MM_ERROR_NONE) {
50 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
51 if (ret == MM_ERROR_NONE)
52 *max = (int)max_level -1; /* actual volume step can be max step - 1 */
55 return _convert_sound_manager_error_code(__func__, ret);
58 int sound_manager_set_volume(sound_type_e type, int volume)
60 int ret = MM_ERROR_NONE;
62 if (type >= SOUND_TYPE_NUM || type < 0)
63 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
65 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
67 ret = mm_sound_volume_set_value(type, volume);
68 LOGI("type=%d, volume=%d", type, volume);
70 return _convert_sound_manager_error_code(__func__, ret);
73 int sound_manager_get_volume(sound_type_e type, int *volume)
75 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);
81 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
83 ret = mm_sound_volume_get_value(type, &uvolume);
84 if (ret == MM_ERROR_NONE)
87 LOGI("type=%d, volume=%d", type, *volume);
89 return _convert_sound_manager_error_code(__func__, ret);
92 int sound_manager_set_current_sound_type(sound_type_e type)
94 int ret = MM_ERROR_NONE;
96 if (type >= SOUND_TYPE_NUM || type < 0)
97 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
99 ret = mm_sound_volume_primary_type_set(type);
101 return _convert_sound_manager_error_code(__func__, ret);
104 int sound_manager_get_current_sound_type(sound_type_e *type)
106 int ret = MM_ERROR_NONE;
107 volume_type_t mm_sound_vol_type = VOLUME_TYPE_UNKNOWN;
108 char *volume_type = NULL;
111 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
113 ret = mm_sound_volume_primary_type_get(&mm_sound_vol_type);
114 if (ret == MM_ERROR_NONE) {
115 if (mm_sound_vol_type == VOLUME_TYPE_UNKNOWN) {
116 /* get the volume type of the current playing stream */
117 ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
118 if (ret == MM_ERROR_NONE)
119 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
121 *type = mm_sound_vol_type;
124 LOGI("type=%d", *type);
126 return _convert_sound_manager_error_code(__func__, ret);
129 int sound_manager_unset_current_sound_type(void)
131 int ret = MM_ERROR_NONE;
133 ret = mm_sound_volume_primary_type_set(VOLUME_TYPE_UNKNOWN);
135 return _convert_sound_manager_error_code(__func__, ret);
138 int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback, void* user_data)
140 int ret = MM_ERROR_NONE;
141 unsigned int subs_id = 0;
143 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
145 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, &subs_id);
146 if (ret == MM_ERROR_NONE) {
147 g_volume_changed_cb_table.subs_id = subs_id;
148 g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
149 g_volume_changed_cb_table.user_data = user_data;
152 SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
154 return _convert_sound_manager_error_code(__func__, ret);
157 int sound_manager_unset_volume_changed_cb(void)
159 int ret = MM_ERROR_NONE;
161 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
163 if (g_volume_changed_cb_table.subs_id > 0) {
164 ret = mm_sound_remove_volume_changed_callback(g_volume_changed_cb_table.subs_id);
165 if (ret == MM_ERROR_NONE) {
166 g_volume_changed_cb_table.subs_id = 0;
167 g_volume_changed_cb_table.user_cb = NULL;
168 g_volume_changed_cb_table.user_data = NULL;
171 ret = MM_ERROR_SOUND_INTERNAL;
174 SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
176 return _convert_sound_manager_error_code(__func__, ret);
179 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)
181 int ret = MM_ERROR_NONE;
185 SM_NULL_ARG_CHECK(stream_info);
186 SM_NULL_ARG_CHECK(callback);
188 if (g_session_interrupt_cb_table.is_registered)
189 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INTERNAL);
191 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
193 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
195 ret = MM_ERROR_OUT_OF_MEMORY;
199 memset(stream_h, 0, sizeof(sound_stream_info_s));
200 ret = _convert_stream_type(stream_type, &stream_h->stream_type);
201 if (ret == MM_ERROR_NONE) {
202 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
203 if (ret == MM_ERROR_NONE) {
204 *stream_info = (sound_stream_info_h)stream_h;
205 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
206 LOGI("stream_h(%p), index(%u), user_cb(%p), cnt(%d), ret(0x%x)", stream_h, stream_h->index, stream_h->user_cb, g_stream_info_count, ret);
214 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
216 return _convert_sound_manager_error_code(__func__, ret);
219 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
221 int ret = MM_ERROR_NONE;
222 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
226 SM_INSTANCE_CHECK(stream_h);
228 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
229 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
230 if (ret == MM_ERROR_NONE) {
233 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
235 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
237 LOGD("cnt(%d)", g_stream_info_count);
239 return _convert_sound_manager_error_code(__func__, ret);
242 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
244 int ret = MM_ERROR_NONE;
245 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
249 ret = _add_device_for_stream_routing(stream_h, device);
251 return _convert_sound_manager_error_code(__func__, ret);
254 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
256 int ret = MM_ERROR_NONE;
257 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
261 ret = _remove_device_for_stream_routing(stream_h, device);
263 return _convert_sound_manager_error_code(__func__, ret);
266 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
268 int ret = MM_ERROR_NONE;
269 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
273 ret = _apply_stream_routing(stream_h);
275 return _convert_sound_manager_error_code(__func__, ret);
278 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
280 int ret = MM_ERROR_NONE;
281 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
285 SM_INSTANCE_CHECK(stream_h);
287 ret = mm_sound_set_focus_reacquisition(stream_h->index, enable);
289 return _convert_sound_manager_error_code(__func__, ret);
292 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
294 int ret = MM_ERROR_NONE;
295 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
299 SM_INSTANCE_CHECK(stream_h);
300 SM_NULL_ARG_CHECK(enabled);
302 ret = mm_sound_get_focus_reacquisition(stream_h->index, enabled);
304 return _convert_sound_manager_error_code(__func__, ret);
307 int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *extra_info)
309 int ret = MM_ERROR_NONE;
310 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
314 SM_INSTANCE_CHECK(stream_h);
316 if (stream_h->is_focus_unavailable)
317 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
319 ret = mm_sound_acquire_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, extra_info);
320 if (ret == MM_ERROR_NONE) {
321 stream_h->acquired_focus |= focus_mask;
322 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
325 return _convert_sound_manager_error_code(__func__, ret);
328 int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *extra_info)
330 int ret = MM_ERROR_NONE;
331 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
335 SM_INSTANCE_CHECK(stream_h);
337 ret = mm_sound_release_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, extra_info);
338 if (ret == MM_ERROR_NONE) {
339 stream_h->acquired_focus &= ~focus_mask;
340 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
343 return _convert_sound_manager_error_code(__func__, ret);
346 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)
348 int ret = MM_ERROR_NONE;
349 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
353 SM_INSTANCE_CHECK(stream_h);
354 if (!state_for_playback && !state_for_recording) {
355 ret = MM_ERROR_INVALID_ARGUMENT;
359 if (state_for_playback)
360 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
361 if (state_for_recording)
362 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
364 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
367 return _convert_sound_manager_error_code(__func__, ret);
370 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
372 int ret = MM_ERROR_NONE;
373 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
377 SM_INSTANCE_CHECK(stream_h);
378 SM_NULL_ARG_CHECK(sound_type);
380 if (stream_h->stream_conf_info.volume_type == NULL) {
381 ret = MM_ERROR_SOUND_NO_DATA;
385 ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
386 LOGI("sound type(%d)", *sound_type);
389 return _convert_sound_manager_error_code(__func__, ret);
392 int sound_manager_add_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_watch_cb callback, void *user_data, int *id)
394 int ret = MM_ERROR_NONE;
399 SM_NULL_ARG_CHECK(callback);
400 SM_NULL_ARG_CHECK(id);
401 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
403 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
404 if (focus_watch_info_arr[i].id == 0)
406 if (i == SOUND_STREAM_INFO_ARR_MAX) {
407 LOGE("focus watch info array is full");
408 ret = MM_ERROR_SOUND_INTERNAL;
412 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, id);
413 if (ret == MM_ERROR_NONE) {
414 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
415 focus_watch_info_arr[i].id = *id;
416 focus_watch_info_arr[i].user_data = user_data;
417 focus_watch_info_arr[i].user_cb = callback;
421 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
423 LOGD("cnt(%d), id(%d)", g_stream_info_count, *id);
425 return _convert_sound_manager_error_code(__func__, ret);
428 int sound_manager_remove_focus_state_watch_cb(int id)
430 int ret = MM_ERROR_NONE;
435 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
437 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
438 if (focus_watch_info_arr[i].id == id)
440 if (i == SOUND_STREAM_INFO_ARR_MAX) {
441 LOGE("cound not find item in focus watch info array for this id(%d)", id);
442 ret = MM_ERROR_SOUND_INTERNAL;
446 ret = mm_sound_unset_focus_watch_callback(id);
447 if (ret == MM_ERROR_NONE) {
448 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
449 focus_watch_info_arr[i].id = 0;
450 focus_watch_info_arr[i].user_data = NULL;
451 focus_watch_info_arr[i].user_cb = NULL;
455 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
457 LOGD("cnt(%d)", g_stream_info_count);
459 return _convert_sound_manager_error_code(__func__, ret);
462 int sound_manager_set_session_type(sound_session_type_e type)
464 int ret = MM_ERROR_NONE;
465 int cur_session = -1;
466 int new_session = MM_SESSION_TYPE_MEDIA;
468 LOGI(">> enter : type=%d", type);
470 if (type < SOUND_SESSION_TYPE_MEDIA || type > SOUND_SESSION_TYPE_VOIP)
471 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
473 /* it is not supported both session and stream feature at the same time */
474 if (g_stream_info_count) {
475 LOGE("Could not set this type(%d) because of being used stream feature", type);
476 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
480 case SOUND_SESSION_TYPE_MEDIA:
481 new_session = MM_SESSION_TYPE_MEDIA;
483 case SOUND_SESSION_TYPE_ALARM:
484 new_session = MM_SESSION_TYPE_ALARM;
486 case SOUND_SESSION_TYPE_NOTIFICATION:
487 new_session = MM_SESSION_TYPE_NOTIFY;
489 case SOUND_SESSION_TYPE_EMERGENCY:
490 new_session = MM_SESSION_TYPE_EMERGENCY;
492 case SOUND_SESSION_TYPE_VOIP:
493 new_session = MM_SESSION_TYPE_VOIP;
497 /* valid session check */
498 ret = mm_session_get_current_type(&cur_session);
499 if (ret == MM_ERROR_NONE) {
500 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
501 if (type > SOUND_SESSION_TYPE_MEDIA) {
502 LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
503 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
508 if (g_session_interrupt_cb_table.is_registered) {
509 if (new_session == cur_session ||
510 ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
511 LOGI("already set type=%d, ret=0x%x", type, ret);
512 return SOUND_MANAGER_ERROR_NONE;
514 ret = mm_session_finish();
515 if (ret != MM_ERROR_NONE)
516 return _convert_sound_manager_error_code(__func__, ret);
518 g_session_interrupt_cb_table.is_registered = 0;
519 if (cur_session == MM_SESSION_TYPE_VOIP) {
520 g_cached_session_mode = -1;
521 g_cached_voip_device_id = -1;
522 if (g_voip_vstream_h) {
523 _stop_virtual_stream(g_voip_vstream_h);
524 _destroy_virtual_stream(g_voip_vstream_h);
525 g_voip_vstream_h = NULL;
527 /*voip stream destruction*/
528 if (g_voip_stream_info) {
529 ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
530 free(g_voip_stream_info);
531 g_voip_stream_info = NULL;
532 if (ret != MM_ERROR_NONE)
533 return _convert_sound_manager_error_code(__func__, ret);
538 ret = mm_session_init(new_session);
539 if (ret == MM_ERROR_NONE)
540 g_session_interrupt_cb_table.is_registered = 1;
542 LOGI("type=%d", type);
544 return _convert_sound_manager_error_code(__func__, ret);
547 int sound_manager_get_session_type(sound_session_type_e *type)
549 int ret = MM_ERROR_NONE;
553 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
555 ret = mm_session_get_current_type(&cur_session);
556 if (ret != MM_ERROR_NONE) {
557 LOGW("session hasn't been set, setting default session");
558 cur_session = SOUND_SESSION_TYPE_DEFAULT;
559 ret = mm_session_init(cur_session);
560 if (ret == MM_ERROR_NONE)
561 g_session_interrupt_cb_table.is_registered = 1;
563 if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
564 (cur_session != MM_SESSION_TYPE_VOIP)) {
565 if (g_cached_session != -1)
566 cur_session = g_cached_session;
567 else /* will be never reached here. just prevent code */
568 cur_session = SOUND_SESSION_TYPE_DEFAULT;
571 switch (cur_session) {
572 case MM_SESSION_TYPE_MEDIA:
573 case MM_SESSION_TYPE_MEDIA_RECORD:
574 *type = SOUND_SESSION_TYPE_MEDIA;
576 case MM_SESSION_TYPE_ALARM:
577 *type = SOUND_SESSION_TYPE_ALARM;
579 case MM_SESSION_TYPE_NOTIFY:
580 *type = SOUND_SESSION_TYPE_NOTIFICATION;
582 case MM_SESSION_TYPE_EMERGENCY:
583 *type = SOUND_SESSION_TYPE_EMERGENCY;
585 case MM_SESSION_TYPE_VOIP:
586 *type = SOUND_SESSION_TYPE_VOIP;
593 LOGI("type=%d", *type);
595 return SOUND_MANAGER_ERROR_NONE;
598 int sound_manager_set_media_session_option(sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
600 int ret = MM_ERROR_NONE;
602 int session_option = 0;
605 LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
607 if (s_option < 0 || s_option > SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
608 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
609 if (d_option < 0 || d_option > SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
610 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
612 ret = mm_session_get_current_information(&session, &session_option);
613 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
614 LOGW("session hasn't been set, setting default session");
615 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
617 g_session_interrupt_cb_table.is_registered = 1;
619 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
620 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
621 if (!g_session_interrupt_cb_table.is_registered) {
622 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
623 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
626 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
631 case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
632 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
633 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
635 return _convert_sound_manager_error_code(__func__, ret);
640 case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
641 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
642 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
644 return _convert_sound_manager_error_code(__func__, ret);
652 case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
653 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
654 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
656 return _convert_sound_manager_error_code(__func__, ret);
661 case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
662 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
663 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
665 return _convert_sound_manager_error_code(__func__, ret);
675 LOGI("already set same option(%x), skip it", session_option);
677 return _convert_sound_manager_error_code(__func__, ret);
680 int sound_manager_get_media_session_option(sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
682 int ret = MM_ERROR_NONE;
684 int session_options = 0;
688 if (s_option == NULL || d_option == NULL)
689 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
691 ret = mm_session_get_current_information(&session, &session_options);
693 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
695 g_session_interrupt_cb_table.is_registered = 1;
697 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
698 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
699 if (!g_session_interrupt_cb_table.is_registered) {
700 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
701 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
704 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
707 if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS)
708 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
710 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
712 if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
713 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
715 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
717 LOGI(" option for starting=%d, for during play=%d", *s_option, *d_option);
719 return SOUND_MANAGER_ERROR_NONE;
722 int sound_manager_set_media_session_resumption_option(sound_session_option_for_resumption_e option)
724 int ret = MM_ERROR_NONE;
726 int session_option = 0;
729 LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
731 if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
732 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
734 ret = mm_session_get_current_information(&session, &session_option);
735 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
736 LOGW("session hasn't been set, setting default session");
737 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
739 g_session_interrupt_cb_table.is_registered = 1;
741 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
742 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
743 if (!g_session_interrupt_cb_table.is_registered) {
744 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
745 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
748 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
753 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
754 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
755 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
757 return _convert_sound_manager_error_code(__func__, ret);
762 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
763 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
764 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
766 return _convert_sound_manager_error_code(__func__, ret);
776 LOGI("already set same option(0x%x), skip it", session_option);
778 return _convert_sound_manager_error_code(__func__, ret);
781 int sound_manager_get_media_session_resumption_option(sound_session_option_for_resumption_e *option)
783 int ret = MM_ERROR_NONE;
785 int session_options = 0;
790 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
792 ret = mm_session_get_current_information(&session, &session_options);
794 LOGW("session hasn't been set, setting default session");
795 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
797 g_session_interrupt_cb_table.is_registered = 1;
799 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
800 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
801 if (!g_session_interrupt_cb_table.is_registered) {
802 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
803 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
806 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
809 if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)
810 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
812 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
814 LOGI("option for resumption=%d (0:by system, 1:by system or media paused)", *option);
816 return SOUND_MANAGER_ERROR_NONE;
819 int sound_manager_set_voip_session_mode(sound_session_voip_mode_e mode)
821 int ret = MM_ERROR_NONE;
823 int session_options = 0;
825 LOGI(">> enter : mode=%d", mode);
827 ret = mm_session_get_current_information(&session, &session_options);
828 if (ret != MM_ERROR_NONE)
831 if (session != MM_SESSION_TYPE_VOIP) {
832 ret = MM_ERROR_POLICY_INTERNAL;
836 if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
837 ret = MM_ERROR_INVALID_ARGUMENT;
841 ret = _set_session_mode((_session_mode_e)mode);
843 LOGI("session=%d, mode=%d", session, mode);
846 return _convert_sound_manager_error_code(__func__, ret);
849 int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
851 int ret = MM_ERROR_NONE;
853 int session_options = 0;
856 LOGE("mode is null");
857 ret = MM_ERROR_INVALID_ARGUMENT;
861 ret = mm_session_get_current_information(&session, &session_options);
862 if (ret != MM_ERROR_NONE) {
863 LOGI("session = %d, option = %d", session, session_options);
867 if (session != MM_SESSION_TYPE_VOIP || g_cached_session_mode == -1) {
868 ret = MM_ERROR_POLICY_INTERNAL;
872 *mode = (sound_session_voip_mode_e)g_cached_session_mode;
874 LOGI("session=%d, mode=%d", session, *mode);
877 return _convert_sound_manager_error_code(__func__, ret);
880 int sound_manager_set_session_interrupted_cb(sound_session_interrupted_cb callback, void *user_data)
882 int ret = MM_ERROR_NONE;
883 unsigned int subs_id = 0;
885 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
887 if (callback == NULL) {
888 ret = MM_ERROR_INVALID_ARGUMENT;
892 /* it is not supported both session and stream feature at the same time */
893 if (g_stream_info_count) {
894 ret = MM_ERROR_POLICY_INTERNAL;
898 if (g_session_interrupt_cb_table.user_cb == NULL) {
899 ret = mm_sound_add_device_connected_callback(SOUND_DEVICE_ALL_MASK, (mm_sound_device_connected_cb)_device_connected_cb, NULL, &subs_id);
902 ret = mm_sound_focus_set_session_interrupt_callback((mm_sound_focus_session_interrupt_cb)_focus_session_interrupt_cb, NULL);
904 if (mm_sound_remove_device_connected_callback(subs_id) != MM_ERROR_NONE)
905 LOGW("mm_sound_remove_device_connected_callback failed");
908 g_session_interrupt_cb_table.subs_id = subs_id;
910 g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
911 g_session_interrupt_cb_table.user_data = user_data;
914 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
916 return _convert_sound_manager_error_code(__func__, ret);
919 int sound_manager_unset_session_interrupted_cb(void)
921 int ret = MM_ERROR_NONE;
923 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
925 if (!g_session_interrupt_cb_table.user_cb) {
926 ret = MM_ERROR_SOUND_INTERNAL;
930 ret = mm_sound_focus_unset_session_interrupt_callback();
932 if (mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id) != MM_ERROR_NONE)
933 LOGW("mm_sound_remove_device_connected_callback failed");
937 ret = mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id);
941 g_session_interrupt_cb_table.subs_id = 0;
942 g_session_interrupt_cb_table.user_cb = NULL;
943 g_session_interrupt_cb_table.user_data = NULL;
946 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
948 return _convert_sound_manager_error_code(__func__, ret);
951 int sound_manager_get_current_device_list(sound_device_mask_e device_mask, sound_device_list_h *device_list)
953 int ret = MM_ERROR_NONE;
955 ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
957 return _convert_sound_manager_error_code(__func__, ret);
960 int sound_manager_free_device_list(sound_device_list_h device_list)
962 int ret = MM_ERROR_NONE;
964 ret = mm_sound_free_device_list(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;
973 ret = mm_sound_get_next_device(device_list, device);
975 return _convert_sound_manager_error_code(__func__, ret);
978 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
980 int ret = MM_ERROR_NONE;
982 ret = mm_sound_get_prev_device(device_list, device);
984 return _convert_sound_manager_error_code(__func__, ret);
987 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
989 int ret = MM_ERROR_NONE;
991 ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)type);
993 return _convert_sound_manager_error_code(__func__, ret);
996 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
998 int ret = MM_ERROR_NONE;
999 mm_sound_device_io_direction_e mm_sound_io_direction;
1001 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
1002 if (ret == MM_ERROR_NONE)
1003 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
1005 return _convert_sound_manager_error_code(__func__, ret);
1008 int sound_manager_get_device_id(sound_device_h device, int *id)
1010 int ret = MM_ERROR_NONE;
1012 ret = mm_sound_get_device_id(device, id);
1014 return _convert_sound_manager_error_code(__func__, ret);
1017 int sound_manager_get_device_name(sound_device_h device, char **name)
1019 int ret = MM_ERROR_NONE;
1021 ret = mm_sound_get_device_name(device, name);
1023 return _convert_sound_manager_error_code(__func__, ret);
1026 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
1028 int ret = MM_ERROR_NONE;
1030 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1032 return _convert_sound_manager_error_code(__func__, ret);
1035 int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1037 int ret = MM_ERROR_NONE;
1038 unsigned int subs_id = 0;
1040 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1042 ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, &subs_id);
1043 if (ret == MM_ERROR_NONE) {
1044 g_device_connected_cb_table.subs_id = subs_id;
1045 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1046 g_device_connected_cb_table.user_data = user_data;
1049 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1051 return _convert_sound_manager_error_code(__func__, ret);
1054 int sound_manager_unset_device_connected_cb(void)
1056 int ret = MM_ERROR_NONE;
1058 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1060 if (g_device_connected_cb_table.subs_id == 0) {
1061 ret = MM_ERROR_SOUND_INTERNAL;
1065 ret = mm_sound_remove_device_connected_callback(g_device_connected_cb_table.subs_id);
1066 if (ret == MM_ERROR_NONE) {
1067 g_device_connected_cb_table.subs_id = 0;
1068 g_device_connected_cb_table.user_cb = NULL;
1069 g_device_connected_cb_table.user_data = NULL;
1073 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1075 return _convert_sound_manager_error_code(__func__, ret);
1078 int sound_manager_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1080 int ret = MM_ERROR_NONE;
1081 unsigned int subs_id = 0;
1083 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1085 ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data, &subs_id);
1086 if (ret == MM_ERROR_NONE) {
1087 g_device_info_changed_cb_table.subs_id = subs_id;
1088 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1089 g_device_info_changed_cb_table.user_data = user_data;
1092 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1094 return _convert_sound_manager_error_code(__func__, ret);
1097 int sound_manager_unset_device_information_changed_cb(void)
1099 int ret = MM_ERROR_NONE;
1101 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1103 if (g_device_info_changed_cb_table.subs_id == 0) {
1104 ret = MM_ERROR_SOUND_INTERNAL;
1108 ret = mm_sound_remove_device_information_changed_callback(g_device_info_changed_cb_table.subs_id);
1109 if (ret == MM_ERROR_NONE) {
1110 g_device_info_changed_cb_table.subs_id = 0;
1111 g_device_info_changed_cb_table.user_cb = NULL;
1112 g_device_info_changed_cb_table.user_data = NULL;
1116 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1118 return _convert_sound_manager_error_code(__func__, ret);
1121 __attribute__ ((destructor))
1122 void __sound_manager_finalize(void)
1124 int ret = MM_ERROR_NONE;
1126 if (g_session_interrupt_cb_table.is_registered) {
1128 ret = mm_session_finish();
1129 if (ret != MM_ERROR_NONE)
1130 LOGE("[%s] failed to mm_session_finish(), ret(0x%x)", __func__, ret);
1132 g_session_interrupt_cb_table.is_registered = 0;
1137 __attribute__ ((constructor))
1138 void __sound_manager_initialize(void)