int g_cached_voip_device_id = -1;
int g_cached_voip_device_id2 = -1;
extern sound_stream_info_s *g_voip_stream_info;
+extern sound_stream_info_s *g_voip_ringtone_stream_info;
extern virtual_sound_stream_info_s *g_voip_vstream_h;
+extern virtual_sound_stream_info_s *g_voip_ringtone_vstream_h;
/* These variables will be removed when session features are deprecated. */
extern int g_stream_info_count;
extern pthread_mutex_t g_stream_info_count_mutex;
+pthread_mutex_t g_session_mutex;
pthread_mutex_t g_interrupt_cb_mutex, g_device_info_cb_mutex, g_device_conn_cb_mutex, g_volume_cb_mutex;
int sound_manager_get_max_volume(sound_type_e type, int *max)
break;
}
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+
/* valid session check */
ret = mm_session_get_current_type(&cur_session);
if (ret == MM_ERROR_NONE) {
if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
if (type > SOUND_SESSION_TYPE_MEDIA) {
LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
- return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
+ ret = MM_ERROR_POLICY_INTERNAL;
+ goto LEAVE;
}
}
}
if (new_session == cur_session ||
((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
LOGI("already set type=%d, ret=0x%x", type, ret);
- return SOUND_MANAGER_ERROR_NONE;
+ goto LEAVE;
} else {
ret = mm_session_finish();
if (ret != MM_ERROR_NONE)
- return _convert_sound_manager_error_code(__func__, ret);
+ goto LEAVE;
g_session_interrupt_cb_table.is_registered = 0;
if (cur_session == MM_SESSION_TYPE_VOIP) {
+ /* De-initialize regarding VoIP session */
g_cached_session_mode = -1;
g_cached_voip_device_id = -1;
g_cached_voip_device_id2 = -1;
if (g_voip_vstream_h) {
- _stop_virtual_stream(g_voip_vstream_h);
- _destroy_virtual_stream(g_voip_vstream_h);
+ _stop_progress_virtual_stream(g_voip_vstream_h);
g_voip_vstream_h = NULL;
}
- /*voip stream destruction*/
+ if (g_voip_ringtone_vstream_h) {
+ _stop_progress_virtual_stream(g_voip_ringtone_vstream_h);
+ g_voip_ringtone_vstream_h = NULL;
+ }
if (g_voip_stream_info) {
ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
SM_SAFE_FREE(g_voip_stream_info);
if (ret != MM_ERROR_NONE)
- return _convert_sound_manager_error_code(__func__, ret);
+ goto LEAVE;
+ }
+ if (g_voip_ringtone_stream_info) {
+ ret = _destroy_pa_connection_and_unregister_focus(g_voip_ringtone_stream_info);
+ SM_SAFE_FREE(g_voip_ringtone_stream_info);
+ if (ret != MM_ERROR_NONE)
+ goto LEAVE;
}
}
}
g_session_interrupt_cb_table.is_registered = 1;
LOGI("type=%d", type);
+LEAVE:
+ SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
return _convert_sound_manager_error_code(__func__, ret);
}
if (type == NULL)
return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
+
ret = mm_session_get_current_type(&cur_session);
if (ret != MM_ERROR_NONE) {
LOGW("session hasn't been set, setting default session");
LOGI("type=%d", *type);
+ SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
+
return SOUND_MANAGER_ERROR_NONE;
}
LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
LOGI(">> enter : mode=%d", mode);
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+
ret = mm_session_get_current_information(&session, &session_options);
if (ret != MM_ERROR_NONE)
goto LEAVE;
LOGI("session=%d, mode=%d(0:RINGTONE 1:MIC_RCV 2:MIC_SPK 3:EAR 4:BT)", session, mode);
LEAVE:
+ SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
+
return _convert_sound_manager_error_code(__func__, ret);
}
int session_options = 0;
LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
+
+ SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+
if (mode == NULL) {
LOGE("mode is null");
ret = MM_ERROR_INVALID_ARGUMENT;
LOGI("session=%d, mode=%d", session, *mode);
LEAVE:
+ SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
+
return _convert_sound_manager_error_code(__func__, ret);
}
#define PA_STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS "UpdateFocusStatus"
#define VCONF_PATH_PREFIX_VOLUME "file/private/sound/volume/"
#define VCONF_PATH_MAX 64
+#define EXT_INFO_VOIP_SESSION "for voip session"
#define CHECK_AND_SET_DEVICE(x_dst_device1, x_dst_device2, x_src_device) \
do { \
extern _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
sound_stream_info_s *sound_stream_info_arr[SOUND_STREAM_INFO_ARR_MAX];
sound_stream_info_s *g_voip_stream_info = NULL;
+sound_stream_info_s *g_voip_ringtone_stream_info = NULL;
virtual_sound_stream_info_s *g_voip_vstream_h = NULL;
+virtual_sound_stream_info_s *g_voip_ringtone_vstream_h = NULL;
int g_stream_info_count = 0;
pthread_mutex_t g_stream_info_count_mutex = PTHREAD_MUTEX_INITIALIZER;
if (!(info->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ||
!(info->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING)) {
/* stop virtual stream for rintone-voip or voip */
+ if (g_voip_ringtone_vstream_h) {
+ _stop_progress_virtual_stream(g_voip_ringtone_vstream_h);
+ g_voip_ringtone_vstream_h = NULL;
+ LOGW("internal voip ringtone stream is interrupted by (%d)", reason);
+ }
if (g_voip_vstream_h) {
- /* stop virtual stream handle */
- _stop_virtual_stream(g_voip_vstream_h);
- /* destroy virtual stream handle */
- _destroy_virtual_stream(g_voip_vstream_h);
+ _stop_progress_virtual_stream(g_voip_vstream_h);
g_voip_vstream_h = NULL;
LOGW("internal voip stream is interrupted by (%d)", reason);
}
if (mode == _SESSION_MODE_RINGTONE) {
if (g_voip_vstream_h) {
- /* stop vstream and destroy vstream */
- _stop_virtual_stream(g_voip_vstream_h);
- _destroy_virtual_stream(g_voip_vstream_h);
+ _stop_progress_virtual_stream(g_voip_vstream_h);
g_voip_vstream_h = NULL;
- /* destroy stream info */
- _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
- SM_SAFE_FREE(g_voip_stream_info);
}
- if (!g_voip_stream_info) {
- g_voip_stream_info = malloc(sizeof(sound_stream_info_s));
- if (!g_voip_stream_info) {
+ if (!g_voip_ringtone_stream_info) {
+ g_voip_ringtone_stream_info = malloc(sizeof(sound_stream_info_s));
+ if (!g_voip_ringtone_stream_info) {
ret = MM_ERROR_OUT_OF_MEMORY;
goto ERROR_CASE;
}
- memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s));
- }
- /* create stream info and acquire focus for rintone-voip stream */
- g_voip_stream_info->stream_type = "ringtone-voip";
- if ((ret = _make_pa_connection_and_register_focus(g_voip_stream_info, true, _voip_focus_state_change_callback, NULL))) {
- SM_SAFE_FREE(g_voip_stream_info);
- goto ERROR_CASE;
+ memset(g_voip_ringtone_stream_info, 0, sizeof(sound_stream_info_s));
+ g_voip_ringtone_stream_info->stream_type = "ringtone-voip";
+ if ((ret = _make_pa_connection_and_register_focus(g_voip_ringtone_stream_info, true, _voip_focus_state_change_callback, NULL))) {
+ SM_SAFE_FREE(g_voip_ringtone_stream_info);
+ goto ERROR_CASE;
+ }
}
- /* acquire focus */
- if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, "for voip session")))
- goto ERROR_CASE;
+ if ((ret = mm_sound_acquire_focus(g_voip_ringtone_stream_info->index, FOCUS_FOR_BOTH, EXT_INFO_VOIP_SESSION))) {
+ if (ret != MM_ERROR_SOUND_INVALID_STATE)
+ goto ERROR_CASE;
+ LOGI("already acquired, skip it");
+ ret = MM_ERROR_NONE;
+ }
- g_voip_stream_info->acquired_focus |= FOCUS_FOR_BOTH;
- _update_focus_status(g_voip_stream_info->index, (unsigned int)g_voip_stream_info->acquired_focus);
+ g_voip_ringtone_stream_info->acquired_focus |= FOCUS_FOR_BOTH;
+ _update_focus_status(g_voip_ringtone_stream_info->index, (unsigned int)g_voip_ringtone_stream_info->acquired_focus);
- /* create virtual stream for ringtone-voip */
- if ((ret = _create_virtual_stream(g_voip_stream_info, &g_voip_vstream_h))) {
- ret = MM_ERROR_SOUND_INTERNAL;
- goto ERROR_CASE;
+ /* create and start virtual stream for ringtone-voip */
+ if (!g_voip_ringtone_vstream_h) {
+ if ((ret = _make_progress_virtual_stream(g_voip_ringtone_stream_info, &g_voip_ringtone_vstream_h))) {
+ ret = MM_ERROR_SOUND_INTERNAL;
+ goto ERROR_CASE;
+ }
}
- if ((ret = _start_virtual_stream(g_voip_vstream_h)))
- goto ERROR_CASE;
-
} else {
/* _SESSION_MODE_VOICE_WITH_BUILTIN_RECEIVER: Built-in RCV and Built-in MIC
* _SESSION_MODE_VOICE_WITH_BUILTIN_SPEAKER : Built-in SPK and Built-in MIC
goto ERROR_CASE_NO_DESTROY;
}
- if (g_cached_session_mode == _SESSION_MODE_RINGTONE) {
- /* stop vstream and destroy vstream */
- _stop_virtual_stream(g_voip_vstream_h);
- _destroy_virtual_stream(g_voip_vstream_h);
- g_voip_vstream_h = NULL;
- /* destroy stream info */
- _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
- SM_SAFE_FREE(g_voip_stream_info);
+ if (g_voip_ringtone_vstream_h) {
+ _stop_progress_virtual_stream(g_voip_ringtone_vstream_h);
+ g_voip_ringtone_vstream_h = NULL;
}
- /* create stream info and acquire focus for voip stream */
- if (g_cached_session_mode == -1 || g_cached_session_mode == _SESSION_MODE_RINGTONE) {
+
+ if (!g_voip_stream_info) {
+ g_voip_stream_info = malloc(sizeof(sound_stream_info_s));
if (!g_voip_stream_info) {
- g_voip_stream_info = malloc(sizeof(sound_stream_info_s));
- if (!g_voip_stream_info) {
- LOGE("failed to malloc for g_voip_stream_info");
- goto ERROR_CASE;
- }
- memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s));
- LOGI("g_voip_stream_info(%p) is newly created", g_voip_stream_info);
+ LOGE("failed to malloc for g_voip_stream_info");
+ goto ERROR_CASE;
}
+ memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s));
+ LOGI("g_voip_stream_info(%p) is newly created", g_voip_stream_info);
g_voip_stream_info->stream_type = "voip";
if ((ret = _make_pa_connection_and_register_focus(g_voip_stream_info, true, _voip_focus_state_change_callback, NULL))) {
SM_SAFE_FREE(g_voip_stream_info);
goto ERROR_CASE;
}
+
+ if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, EXT_INFO_VOIP_SESSION))) {
+ if (ret != MM_ERROR_SOUND_INVALID_STATE)
+ goto ERROR_CASE;
+ LOGI("already acquired, skip it");
+ ret = MM_ERROR_NONE;
+ }
+
if (proper_device) {
if ((ret = _add_device_for_stream_routing(g_voip_stream_info, proper_device)))
goto ERROR_CASE;
if ((ret = _apply_stream_routing(g_voip_stream_info)))
goto ERROR_CASE;
- /* acquire focus */
- if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, "for voip session")))
- goto ERROR_CASE;
-
g_voip_stream_info->acquired_focus |= FOCUS_FOR_BOTH;
_update_focus_status(g_voip_stream_info->index, (unsigned int)g_voip_stream_info->acquired_focus);
- /* create virtual stream for voip */
- if ((ret = _create_virtual_stream(g_voip_stream_info, &g_voip_vstream_h)))
- goto ERROR_CASE;
-
- if ((ret = _start_virtual_stream(g_voip_vstream_h)))
- goto ERROR_CASE;
-
} else {
+ if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, EXT_INFO_VOIP_SESSION))) {
+ if (ret != MM_ERROR_SOUND_INVALID_STATE)
+ goto ERROR_CASE_NO_DESTROY;
+ LOGI("already acquired, skip it");
+ ret = MM_ERROR_NONE;
+ }
+
if (prev_device) {
if ((ret = _remove_device_for_stream_routing(g_voip_stream_info, prev_device)))
goto ERROR_CASE_NO_DESTROY;
if ((ret = _apply_stream_routing(g_voip_stream_info)))
goto ERROR_CASE_NO_DESTROY;
}
+
+ if (!g_voip_vstream_h) {
+ if ((ret = _make_progress_virtual_stream(g_voip_stream_info, &g_voip_vstream_h))) {
+ ret = MM_ERROR_SOUND_INTERNAL;
+ goto ERROR_CASE;
+ }
+ }
}
g_cached_session_mode = mode;
- g_cached_voip_device_id = -1;
- g_cached_voip_device_id2 = -1;
+
if (proper_device)
mm_sound_get_device_id(proper_device, &g_cached_voip_device_id);
if (proper_device2)
return ret;
ERROR_CASE:
if (g_voip_vstream_h) {
- /* destroy virtual stream handle */
_destroy_virtual_stream(g_voip_vstream_h);
g_voip_vstream_h = NULL;
}
+ if (g_voip_ringtone_vstream_h) {
+ _destroy_virtual_stream(g_voip_ringtone_vstream_h);
+ g_voip_ringtone_vstream_h = NULL;
+ }
if (g_voip_stream_info) {
- /* destroy stream info */
_destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
SM_SAFE_FREE(g_voip_stream_info);
}
+ if (g_voip_ringtone_stream_info) {
+ _destroy_pa_connection_and_unregister_focus(g_voip_ringtone_stream_info);
+ SM_SAFE_FREE(g_voip_ringtone_stream_info);
+ }
ERROR_CASE_NO_DESTROY:
if (device_list)
mm_sound_free_device_list(device_list);
return ret;
}
+
+int _make_progress_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream)
+{
+ int ret = MM_ERROR_NONE;
+
+ SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
+ SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
+
+ if ((ret = _create_virtual_stream(stream_info, virtual_stream)))
+ LOGE("failed to _create_virtual_stream(), ret(0x%x)", ret);
+ else if ((ret = _start_virtual_stream(*virtual_stream)))
+ LOGE("failed to _start_virtual_stream(), ret(0x%x)", ret);
+
+ return ret;
+}
+
+int _stop_progress_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
+{
+ int ret = MM_ERROR_NONE;
+
+ SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
+
+ if ((ret = _stop_virtual_stream(virtual_stream)))
+ LOGE("failed to _stop_virtual_stream(), ret(0x%x)", ret);
+ else if ((ret = _destroy_virtual_stream(virtual_stream)))
+ LOGE("failed to _destroy_virtual_stream(), ret(0x%x)", ret);
+
+ return ret;
+}