From: Sangchul Lee Date: Thu, 27 Aug 2015 09:22:55 +0000 (+0900) Subject: Apply the virtual stream feature to voip session APIs internally X-Git-Tag: submit/tizen/20150828.064758^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F92%2F46992%2F3;p=platform%2Fcore%2Fapi%2Fsound-manager.git Apply the virtual stream feature to voip session APIs internally Change prefix of private functions [Version] Release 0.3.19 [profile] Common [Issue Type] Fix bug and code clean-up Change-Id: I7e14f466416c8ec13a85e4c8f09792acdf9b6f23 Signed-off-by: Sangchul Lee --- diff --git a/include/sound_manager_private.h b/include/sound_manager_private.h index a0b3ecb..7ed7e8a 100644 --- a/include/sound_manager_private.h +++ b/include/sound_manager_private.h @@ -145,7 +145,6 @@ typedef struct _sound_stream_info_s { void *user_data; manual_route_info_s manual_route_info; } sound_stream_info_s; -sound_stream_info_s *sound_stream_info_arr[SOUND_STREAM_INFO_ARR_MAX]; typedef enum { _VSTREAM_STATE_READY, @@ -203,58 +202,68 @@ typedef struct { void _focus_session_interrupt_cb (mm_sound_focus_state_e state, const char *reason_for_change, bool is_wcb, void *user_data); +void _voip_focus_state_change_callback (sound_stream_info_h stream_info, sound_stream_focus_change_reason_e reason_for_change, const char *additional_info, void *user_data); + void _device_connected_cb(sound_device_h device, bool is_connected, void *user_data); void _focus_state_change_callback (int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data); void _focus_watch_callback (int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data); -int __convert_sound_manager_error_code (const char *func, int code); - -int __find_empty_slot (int *index); +int _convert_sound_manager_error_code (const char *func, int code); -int __convert_stream_type (sound_stream_type_e enum_type, char **stream_type); +int _convert_stream_type (sound_stream_type_e enum_type, char **stream_type); -int __convert_stream_type_for_internal (sound_stream_type_internal_e stream_type_enum, char **stream_type); +int _convert_stream_type_for_internal (sound_stream_type_internal_e stream_type_enum, char **stream_type); -int __convert_stream_type_to_change_reason (const char *stream_type, sound_stream_focus_change_reason_e *change_reason); +int _convert_stream_type_to_change_reason (const char *stream_type, sound_stream_focus_change_reason_e *change_reason); -int __convert_device_type (sound_device_type_e device_type_enum, char **device_type); +int _convert_device_type (sound_device_type_e device_type_enum, char **device_type); -int __convert_device_io_direction (mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction); +int _convert_device_io_direction (mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction); -const char* __convert_api_name (native_api_e api_name); +const char* _convert_api_name (native_api_e api_name); -int __get_stream_conf_info (const char *stream_type, stream_conf_info_s *info); +int _get_stream_conf_info (const char *stream_type, stream_conf_info_s *info); -int __set_manual_route_info (unsigned int index, manual_route_info_s *info); +int _set_manual_route_info (unsigned int index, manual_route_info_s *info); -int __set_route_option (unsigned int index, const char *key, int value); +int _set_route_option (unsigned int index, const char *key, int value); -int __convert_sound_type (sound_type_e sound_type, const char **volume_type); +int _convert_sound_type (sound_type_e sound_type, const char **volume_type); -int __convert_sound_type_to_enum (char *sound_type, sound_type_e *sound_type_enum); +int _convert_sound_type_to_enum (char *sound_type, sound_type_e *sound_type_enum); -int __get_volume_max_level (const char *direction, const char *volume_type, unsigned int *max_level); +int _get_volume_max_level (const char *direction, const char *volume_type, unsigned int *max_level); -int __get_current_volume_type (const char *direction, char **volume_type); +int _get_current_volume_type (const char *direction, char **volume_type); -void __update_focus_status (unsigned int index, unsigned int acquired_focus_status); +void _update_focus_status (unsigned int index, unsigned int acquired_focus_status); void _pa_context_state_cb (pa_context *c, void *userdata); void _pa_stream_state_cb (pa_stream *s, void * userdata); -void __session_interrupt_cb (session_msg_t msg, session_event_t event, void *user_data); - -int __set_session_mode (_session_mode_e mode); - -int __get_session_mode (_session_mode_e *mode); +int _set_session_mode (_session_mode_e mode); int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_stream_focus_state_changed_cb callback, void *user_data); int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h); +int _add_device_for_stream_routing (sound_stream_info_s *stream_info, sound_device_h device); + +int _remove_device_for_stream_routing (sound_stream_info_s *stream_info, sound_device_h device); + +int _apply_stream_routing (sound_stream_info_s *stream_info); + +int _create_virtual_stream (sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream); + +int _destroy_virtual_stream (virtual_sound_stream_info_s *virtual_stream); + +int _start_virtual_stream (virtual_sound_stream_info_s *virtual_stream); + +int _stop_virtual_stream (virtual_sound_stream_info_s *virtual_stream); + #ifdef __cplusplus } #endif diff --git a/packaging/capi-media-sound-manager.spec b/packaging/capi-media-sound-manager.spec index 07fce0b..919b0d4 100755 --- a/packaging/capi-media-sound-manager.spec +++ b/packaging/capi-media-sound-manager.spec @@ -1,6 +1,6 @@ Name: capi-media-sound-manager Summary: Sound Manager library -Version: 0.3.18 +Version: 0.3.19 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/sound_manager.c b/src/sound_manager.c index 8c8bcb7..44a3a71 100644 --- a/src/sound_manager.c +++ b/src/sound_manager.c @@ -17,7 +17,6 @@ #include "sound_manager.h" #include "sound_manager_private.h" -#define TMP_CODE _session_interrupt_info_s g_session_interrupt_cb_table = {0, 0, NULL, NULL}; _volume_changed_info_s g_volume_changed_cb_table = {0, NULL, NULL}; @@ -27,17 +26,15 @@ _device_changed_info_s g_device_info_changed_cb_table = {0, NULL, NULL}; sound_session_type_e g_cached_session = -1; _session_mode_e g_cached_session_mode = -1; +int g_cached_voip_device_id = -1; +extern sound_stream_info_s *g_voip_stream_info; +extern virtual_sound_stream_info_s *g_voip_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_interrupt_cb_mutex, g_device_info_cb_mutex, g_device_conn_cb_mutex, g_volume_cb_mutex; -#ifdef TMP_CODE -/*temporary variable for set/get voip session mode. When 2.4 feature for routing is fully implemented, it will be removed.*/ -sound_session_voip_mode_e tmp_mode = -1; -#endif - int sound_manager_get_max_volume (sound_type_e type, int *max) { const char *volume_type = NULL; @@ -45,18 +42,18 @@ int sound_manager_get_max_volume (sound_type_e type, int *max) int ret = MM_ERROR_NONE; if (max == NULL) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); if (type >= SOUND_TYPE_NUM || type < 0) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); - ret = __convert_sound_type (type, &volume_type); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + ret = _convert_sound_type (type, &volume_type); if (ret == MM_ERROR_NONE) { - ret = __get_volume_max_level("out", volume_type, &max_level); + ret = _get_volume_max_level("out", volume_type, &max_level); if (ret == MM_ERROR_NONE) *max = (int)max_level -1; // actual volume step can be max step - 1 } - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_volume (sound_type_e type, int volume) @@ -64,14 +61,14 @@ int sound_manager_set_volume (sound_type_e type, int volume) int ret = MM_ERROR_NONE; if (type >= SOUND_TYPE_NUM || type < 0) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); if (volume < 0) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_sound_volume_set_value(type, volume); LOGI("returns : type=%d, volume=%d, ret=%p", type, volume, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_volume (sound_type_e type, int *volume) @@ -80,9 +77,9 @@ int sound_manager_get_volume (sound_type_e type, int *volume) unsigned int uvolume; if (type >= SOUND_TYPE_NUM || type < 0) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); if (volume == NULL) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_sound_volume_get_value(type, &uvolume); if (ret == MM_ERROR_NONE) @@ -90,7 +87,7 @@ int sound_manager_get_volume (sound_type_e type, int *volume) LOGI("returns : type=%d, volume=%d, ret=%p", type, *volume, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_current_sound_type (sound_type_e type) @@ -98,11 +95,11 @@ int sound_manager_set_current_sound_type (sound_type_e type) int ret = MM_ERROR_NONE; if (type >= SOUND_TYPE_NUM || type < 0) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_sound_volume_primary_type_set(type); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_current_sound_type (sound_type_e *type) @@ -112,15 +109,15 @@ int sound_manager_get_current_sound_type (sound_type_e *type) char *volume_type = NULL; if (type == NULL) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_sound_volume_primary_type_get(&mm_sound_vol_type); if (ret == MM_ERROR_NONE) { if (mm_sound_vol_type == VOLUME_TYPE_UNKNOWN) { /* get the volume type of the current playing stream */ - ret = __get_current_volume_type ("out", &volume_type); + ret = _get_current_volume_type ("out", &volume_type); if (ret == MM_ERROR_NONE) { - ret = __convert_sound_type_to_enum (volume_type, type); + ret = _convert_sound_type_to_enum (volume_type, type); free(volume_type); } } else { @@ -129,7 +126,7 @@ int sound_manager_get_current_sound_type (sound_type_e *type) } LOGI("returns : type=%d, ret=%p", *type, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_unset_current_sound_type (void) @@ -138,7 +135,7 @@ int sound_manager_unset_current_sound_type (void) ret = mm_sound_volume_primary_type_set(VOLUME_TYPE_UNKNOWN); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_volume_changed_cb (sound_manager_volume_changed_cb callback, void* user_data) @@ -157,7 +154,7 @@ int sound_manager_set_volume_changed_cb (sound_manager_volume_changed_cb callbac SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_unset_volume_changed_cb (void) @@ -179,7 +176,7 @@ int sound_manager_unset_volume_changed_cb (void) SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } 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) @@ -192,27 +189,30 @@ int sound_manager_create_stream_information (sound_stream_type_e stream_type, so SM_NULL_ARG_CHECK(callback); if (g_session_interrupt_cb_table.is_registered) - return __convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INTERNAL); sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s)); if (!stream_h) { ret = MM_ERROR_OUT_OF_MEMORY; } else { memset(stream_h, 0, sizeof(sound_stream_info_s)); - ret = __convert_stream_type(stream_type, &stream_h->stream_type); + ret = _convert_stream_type(stream_type, &stream_h->stream_type); if (ret == MM_ERROR_NONE) { + SM_ENTER_CRITICAL_SECTION_WITH_RETURN( &g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL); ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data); if (ret == MM_ERROR_NONE) { *stream_info = (sound_stream_info_h)stream_h; + SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret); 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); } + SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex); } if (ret) { free(stream_h); } } - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_destroy_stream_information (sound_stream_info_h stream_info) @@ -224,210 +224,58 @@ int sound_manager_destroy_stream_information (sound_stream_info_h stream_info) SM_INSTANCE_CHECK(stream_h); + SM_ENTER_CRITICAL_SECTION_WITH_RETURN( &g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL); ret = _destroy_pa_connection_and_unregister_focus(stream_h); + free(stream_h); + stream_h = NULL; + SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret); + SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex); LOGI("<< leave : cnt(%d), ret(%p)", g_stream_info_count, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_add_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device) { int ret = MM_ERROR_NONE; - int i = 0; - int j = 0; - bool added_successfully = false; - char *device_type_str = NULL; - int device_id = 0; - mm_sound_device_type_e device_type; - mm_sound_device_io_direction_e device_direction; sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info; LOGI(">> enter"); - SM_INSTANCE_CHECK(stream_h); - SM_NULL_ARG_CHECK(device); - - if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { - ret = mm_sound_get_device_id(device, &device_id); - if (ret) { - return __convert_sound_manager_error_code(__func__, ret); - } - ret = mm_sound_get_device_type(device, &device_type); - if (ret) { - return __convert_sound_manager_error_code(__func__, ret); - } - ret = __convert_device_type(device_type, &device_type_str); - if (ret) { - return __convert_sound_manager_error_code(__func__, ret); - } - ret = mm_sound_get_device_io_direction(device, &device_direction); - if (ret) { - return __convert_sound_manager_error_code(__func__, ret); - } - if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { - for (i = 0; i < AVAIL_DEVICES_MAX; i++) { - if (stream_h->stream_conf_info.avail_in_devices[i]) { - if (!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { - for (j = 0; j < AVAIL_DEVICES_MAX; j++) { - if (!stream_h->manual_route_info.route_in_devices[j]) { - stream_h->manual_route_info.route_in_devices[j] = (unsigned int)device_id; - added_successfully = true; - break; - } - if (stream_h->manual_route_info.route_in_devices[j] == (unsigned int)device_id) { - /* it was already set */ - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED); - } - } - } - } else { - break; - } - } - } - if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { - for (i = 0; i < AVAIL_DEVICES_MAX; i++) { - if (stream_h->stream_conf_info.avail_out_devices[i]) { - if (!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { - for (j = 0; j < AVAIL_DEVICES_MAX; j++) { - if (!stream_h->manual_route_info.route_out_devices[j]) { - stream_h->manual_route_info.route_out_devices[j] = (unsigned int)device_id; - added_successfully = true; - break; - } - if (stream_h->manual_route_info.route_out_devices[j] == (unsigned int)device_id) { - /* it was already set */ - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED); - } - } - } - } else { - break; - } - } - } - } - - if (!added_successfully) { - ret = MM_ERROR_POLICY_INTERNAL; - } + ret = _add_device_for_stream_routing(stream_h, device); LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_remove_device_for_stream_routing (sound_stream_info_h stream_info, sound_device_h device) { int ret = MM_ERROR_NONE; - int i = 0; - int j = 0; - bool removed_successfully = false; - char *device_type_str = NULL; - int device_id = 0; - mm_sound_device_type_e device_type; - mm_sound_device_io_direction_e device_direction; sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info; LOGI(">> enter"); - SM_INSTANCE_CHECK(stream_h); - SM_NULL_ARG_CHECK(device); - - if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { - ret = mm_sound_get_device_id(device, &device_id); - if (ret) { - return __convert_sound_manager_error_code(__func__, ret); - } - ret = mm_sound_get_device_type(device, &device_type); - if (ret) { - return __convert_sound_manager_error_code(__func__, ret); - } - ret = __convert_device_type(device_type, &device_type_str); - ret = mm_sound_get_device_io_direction(device, &device_direction); - if (ret) { - return __convert_sound_manager_error_code(__func__, ret); - } - if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { - for (i = 0; i < AVAIL_DEVICES_MAX; i++) { - if (stream_h->stream_conf_info.avail_in_devices[i]) { - if (!strncmp(stream_h->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { - for (j = 0; j < AVAIL_DEVICES_MAX; j++) { - if (stream_h->manual_route_info.route_in_devices[j] == (unsigned int)device_id) { - removed_successfully = true; - stream_h->manual_route_info.route_in_devices[j] = 0; - break; - } - } - } - } else { - break; - } - } - } - if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { - for (i = 0; i < AVAIL_DEVICES_MAX; i++) { - if (stream_h->stream_conf_info.avail_out_devices[i]) { - if (!strncmp(stream_h->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { - for (j = 0; j < AVAIL_DEVICES_MAX; j++) { - if (stream_h->manual_route_info.route_out_devices[j] == (unsigned int)device_id) { - removed_successfully = true; - stream_h->manual_route_info.route_out_devices[j] = 0; - break; - } - } - } - } else { - break; - } - } - } - } - - if (!removed_successfully) { - ret = MM_ERROR_INVALID_ARGUMENT; - } + ret = _remove_device_for_stream_routing(stream_h, device); LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_apply_stream_routing (sound_stream_info_h stream_info) { int ret = MM_ERROR_NONE; - int i = 0; - bool need_to_apply = false; sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info; LOGI(">> enter"); - SM_INSTANCE_CHECK(stream_h); - - if (stream_h->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { - for (i = 0; i < AVAIL_DEVICES_MAX; i++) { - if (stream_h->manual_route_info.route_in_devices[i]) { - need_to_apply = true; - break; - } - if (stream_h->manual_route_info.route_out_devices[i]) { - need_to_apply = true; - break; - } - } - if (need_to_apply) { - ret = __set_manual_route_info(stream_h->index, &stream_h->manual_route_info); - } else { - __convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_STATE); - } - } else { - ret = MM_ERROR_SOUND_INVALID_STATE; - } + ret = _apply_stream_routing(stream_h); LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_acquire_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info) @@ -442,12 +290,12 @@ int sound_manager_acquire_focus (sound_stream_info_h stream_info, sound_stream_f ret = mm_sound_acquire_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info); if (ret == MM_ERROR_NONE) { stream_h->acquired_focus |= focus_mask; - __update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus); + _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus); } LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_release_focus (sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *additional_info) @@ -462,12 +310,12 @@ int sound_manager_release_focus (sound_stream_info_h stream_info, sound_stream_f ret = mm_sound_release_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info); if (ret == MM_ERROR_NONE) { stream_h->acquired_focus &= ~focus_mask; - __update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus); + _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus); } LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } 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) @@ -488,7 +336,7 @@ int sound_manager_get_focus_state (sound_stream_info_h stream_info, sound_stream LOGI("<< leave : acquired_focus(%p)", stream_h->acquired_focus); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } 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) @@ -517,7 +365,7 @@ int sound_manager_set_focus_state_watch_cb (sound_stream_focus_mask_e focus_mask LOGI("<< leave : cnt(%d), ret(%p)", g_stream_info_count, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_unset_focus_state_watch_cb (void) @@ -546,7 +394,7 @@ int sound_manager_unset_focus_state_watch_cb (void) LOGI("<< leave : cnt(%d), ret(%p)", g_stream_info_count, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_session_type (sound_session_type_e type) @@ -558,11 +406,13 @@ int sound_manager_set_session_type (sound_session_type_e type) LOGI(">> enter : type=%d", type); if (type < SOUND_SESSION_TYPE_MEDIA || type > SOUND_SESSION_TYPE_VOIP) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); /* it is not supported both session and stream feature at the same time */ - if (g_stream_info_count) - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + if (g_stream_info_count) { + LOGE("Could not set this type(%d) because of being used stream feature", type); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + } switch (type) { case SOUND_SESSION_TYPE_MEDIA: @@ -588,13 +438,9 @@ int sound_manager_set_session_type (sound_session_type_e type) if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) { if (type > SOUND_SESSION_TYPE_MEDIA) { LOGE("<< leave : 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); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } - if (cur_session == MM_SESSION_TYPE_VIDEOCALL || - cur_session >= MM_SESSION_TYPE_VOICE_RECOGNITION) { - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); - } } if (g_session_interrupt_cb_table.is_registered) { @@ -605,27 +451,37 @@ int sound_manager_set_session_type (sound_session_type_e type) } else { ret = mm_session_finish(); if (ret != MM_ERROR_NONE) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } g_session_interrupt_cb_table.is_registered = 0; - g_cached_session_mode = -1; + if (cur_session == MM_SESSION_TYPE_VOIP) { + g_cached_session_mode = -1; + g_cached_voip_device_id = -1; + if (g_voip_vstream_h) { + _stop_virtual_stream (g_voip_vstream_h); + _destroy_virtual_stream (g_voip_vstream_h); + g_voip_vstream_h = NULL; + } + /*voip stream destruction*/ + if (g_voip_stream_info) { + ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info); + free(g_voip_stream_info); + g_voip_stream_info = NULL; + if (ret != MM_ERROR_NONE) { + return _convert_sound_manager_error_code(__func__, ret); + } + } + } } } - ret = mm_session_init_ex(new_session , __session_interrupt_cb, NULL); + ret = mm_session_init(new_session); if (ret == MM_ERROR_NONE) { g_session_interrupt_cb_table.is_registered = 1; } - if (new_session == MM_SESSION_TYPE_VOIP || new_session == MM_SESSION_TYPE_CALL) { - /* set default sub-session for voip */ - ret = mm_session_set_subsession (MM_SUBSESSION_TYPE_RINGTONE, MM_SUBSESSION_OPTION_NONE); - if (ret != MM_ERROR_NONE) { - return __convert_sound_manager_error_code(__func__, ret); - } - g_cached_session_mode = _SESSION_MODE_RINGTONE; - } + LOGI("<< leave : type=%d, ret=%p", type, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_session_type (sound_session_type_e *type) @@ -634,12 +490,12 @@ int sound_manager_get_session_type (sound_session_type_e *type) int cur_session; if (type == NULL) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_session_get_current_type(&cur_session); if (ret != 0) { LOGW("session hasn't been set, setting default session"); cur_session = SOUND_SESSION_TYPE_DEFAULT; - ret = mm_session_init_ex(cur_session, __session_interrupt_cb, NULL); + ret = mm_session_init(cur_session); if (ret == 0) { g_session_interrupt_cb_table.is_registered = 1; } @@ -689,14 +545,14 @@ int sound_manager_set_media_session_option (sound_session_option_for_starting_e LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option); if (s_option < 0 || s_option > SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); if (d_option < 0 || d_option > SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_session_get_current_information(&session, &session_option); if (ret != 0 || !g_session_interrupt_cb_table.is_registered) { LOGW("session hasn't been set, setting default session"); - ret = mm_session_init_ex(MM_SESSION_TYPE_MEDIA, __session_interrupt_cb, NULL); + ret = mm_session_init(MM_SESSION_TYPE_MEDIA); if (ret == 0) { g_session_interrupt_cb_table.is_registered = 1; } @@ -704,10 +560,10 @@ int sound_manager_set_media_session_option (sound_session_option_for_starting_e if (session == MM_SESSION_TYPE_MEDIA_RECORD) { if (!g_session_interrupt_cb_table.is_registered) { LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first"); - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } else { - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } @@ -716,7 +572,7 @@ int sound_manager_set_media_session_option (sound_session_option_for_starting_e if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) { ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS); if (ret) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } updated = 1; } @@ -725,7 +581,7 @@ int sound_manager_set_media_session_option (sound_session_option_for_starting_e if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) { ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS); if (ret) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } updated = 1; } @@ -737,7 +593,7 @@ int sound_manager_set_media_session_option (sound_session_option_for_starting_e if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) { ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE); if (ret) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } updated = 1; } @@ -746,7 +602,7 @@ int sound_manager_set_media_session_option (sound_session_option_for_starting_e if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) { ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE); if (ret) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } updated = 1; } @@ -759,7 +615,7 @@ int sound_manager_set_media_session_option (sound_session_option_for_starting_e LOGI("<< leave : already set same option(%x), skip it", session_option); } - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_media_session_option (sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option) @@ -771,11 +627,11 @@ int sound_manager_get_media_session_option (sound_session_option_for_starting_e LOGI(">> enter"); if (s_option == NULL || d_option == NULL) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_session_get_current_information(&session, &session_options); if (ret != 0) { - ret = mm_session_init_ex(MM_SESSION_TYPE_MEDIA, __session_interrupt_cb, NULL); + ret = mm_session_init(MM_SESSION_TYPE_MEDIA); if (ret == 0) { g_session_interrupt_cb_table.is_registered = 1; } @@ -783,10 +639,10 @@ int sound_manager_get_media_session_option (sound_session_option_for_starting_e if (session == MM_SESSION_TYPE_MEDIA_RECORD) { if (!g_session_interrupt_cb_table.is_registered) { LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first"); - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } else { - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } /* get option */ @@ -816,12 +672,12 @@ int sound_manager_set_media_session_resumption_option (sound_session_option_for_ LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option); if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_session_get_current_information(&session, &session_option); if (ret != 0 || !g_session_interrupt_cb_table.is_registered) { LOGW("session hasn't been set, setting default session"); - ret = mm_session_init_ex(MM_SESSION_TYPE_MEDIA, __session_interrupt_cb, NULL); + ret = mm_session_init(MM_SESSION_TYPE_MEDIA); if (ret == 0) { g_session_interrupt_cb_table.is_registered = 1; } @@ -829,10 +685,10 @@ int sound_manager_set_media_session_resumption_option (sound_session_option_for_ if (session == MM_SESSION_TYPE_MEDIA_RECORD) { if (!g_session_interrupt_cb_table.is_registered) { LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first"); - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } else { - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } @@ -841,7 +697,7 @@ int sound_manager_set_media_session_resumption_option (sound_session_option_for_ if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) { ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED); if (ret) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } updated = 1; } @@ -850,7 +706,7 @@ int sound_manager_set_media_session_resumption_option (sound_session_option_for_ if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) { ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED); if (ret) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } updated = 1; } @@ -863,7 +719,7 @@ int sound_manager_set_media_session_resumption_option (sound_session_option_for_ LOGI("<< leave : already set same option(%x), skip it", session_option); } - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_media_session_resumption_option (sound_session_option_for_resumption_e *option) @@ -875,11 +731,11 @@ int sound_manager_get_media_session_resumption_option (sound_session_option_for_ LOGI(">> enter"); if (option == NULL) - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); ret = mm_session_get_current_information(&session, &session_options); if (ret != 0) { LOGW("session hasn't been set, setting default session"); - ret = mm_session_init_ex(MM_SESSION_TYPE_MEDIA, __session_interrupt_cb, NULL); + ret = mm_session_init(MM_SESSION_TYPE_MEDIA); if (ret == 0) { g_session_interrupt_cb_table.is_registered = 1; } @@ -887,10 +743,10 @@ int sound_manager_get_media_session_resumption_option (sound_session_option_for_ if (session == MM_SESSION_TYPE_MEDIA_RECORD) { if (!g_session_interrupt_cb_table.is_registered) { LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first"); - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } else { - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } } /* get option */ @@ -915,24 +771,19 @@ int sound_manager_set_voip_session_mode (sound_session_voip_mode_e mode) ret = mm_session_get_current_information(&session, &session_options); if (ret != MM_ERROR_NONE) { - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } else if (session != MM_SESSION_TYPE_VOIP) { - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) { ret = MM_ERROR_INVALID_ARGUMENT; - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } - ret = __set_session_mode ((_session_mode_e)mode); - -#ifdef TMP_CODE - /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */ - tmp_mode = mode; -#endif + ret = _set_session_mode ((_session_mode_e)mode); LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_voip_session_mode (sound_session_voip_mode_e *mode) @@ -940,35 +791,25 @@ int sound_manager_get_voip_session_mode (sound_session_voip_mode_e *mode) int ret = MM_ERROR_NONE; int session = 0; int session_options = 0; -#ifndef TMP_CODE - _session_mode_e _mode = 0; -#endif if (mode == NULL) { LOGI("mode is null"); - return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); + return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT); } ret = mm_session_get_current_information(&session, &session_options); if (ret != MM_ERROR_NONE) { LOGI("session = %d, option = %d", session, session_options); - return __convert_sound_manager_error_code(__func__, ret); - } else if (session != MM_SESSION_TYPE_VOIP) { - return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); + return _convert_sound_manager_error_code(__func__, ret); + } else if (session != MM_SESSION_TYPE_VOIP || g_cached_session_mode == -1) { + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL); } -#ifdef TMP_CODE - /* temporary code. When 2.4 feature for routing is fully implemented, it will be removed. */ - *mode = tmp_mode; -#else - ret = __get_session_mode(&_mode); - if (ret == MM_ERROR_NONE) - *mode = (sound_session_voip_mode_e)_mode; -#endif + *mode = (sound_session_voip_mode_e)g_cached_session_mode; LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_session_interrupted_cb (sound_session_interrupted_cb callback, void *user_data) @@ -989,7 +830,7 @@ int sound_manager_set_session_interrupted_cb (sound_session_interrupted_cb callb goto finish; } - if (g_session_interrupt_cb_table.is_registered == 0) { + if (g_session_interrupt_cb_table.user_cb == NULL) { ret = mm_sound_add_device_connected_callback(SOUND_DEVICE_ALL_MASK, (mm_sound_device_connected_cb)_device_connected_cb, NULL, &subs_id); if (ret) goto finish; @@ -999,16 +840,14 @@ int sound_manager_set_session_interrupted_cb (sound_session_interrupted_cb callb LOGW("mm_sound_remove_device_connected_callback failed"); goto finish; } - g_session_interrupt_cb_table.is_registered = 1; g_session_interrupt_cb_table.subs_id = subs_id; } - g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback; g_session_interrupt_cb_table.user_data = user_data; finish: SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_unset_session_interrupted_cb (void) @@ -1030,14 +869,13 @@ int sound_manager_unset_session_interrupted_cb (void) g_session_interrupt_cb_table.subs_id = 0; g_session_interrupt_cb_table.user_cb = NULL; g_session_interrupt_cb_table.user_data = NULL; - g_session_interrupt_cb_table.is_registered = 0; } else { ret = MM_ERROR_SOUND_INTERNAL; } finish: SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_current_device_list (sound_device_mask_e device_mask, sound_device_list_h *device_list) @@ -1045,7 +883,7 @@ int sound_manager_get_current_device_list (sound_device_mask_e device_mask, soun int ret = MM_ERROR_NONE; ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_next_device (sound_device_list_h device_list, sound_device_h *device) @@ -1053,7 +891,7 @@ int sound_manager_get_next_device (sound_device_list_h device_list, sound_device int ret = MM_ERROR_NONE; ret = mm_sound_get_next_device(device_list, device); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_prev_device (sound_device_list_h device_list, sound_device_h *device) @@ -1061,7 +899,7 @@ int sound_manager_get_prev_device (sound_device_list_h device_list, sound_device int ret = MM_ERROR_NONE; ret = mm_sound_get_prev_device(device_list, device); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_device_type (sound_device_h device, sound_device_type_e *type) @@ -1069,7 +907,7 @@ int sound_manager_get_device_type (sound_device_h device, sound_device_type_e *t int ret = MM_ERROR_NONE; ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)type); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_device_io_direction (sound_device_h device, sound_device_io_direction_e *io_direction) @@ -1078,10 +916,10 @@ int sound_manager_get_device_io_direction (sound_device_h device, sound_device_i mm_sound_device_io_direction_e mm_sound_io_direction; ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction); if (ret == MM_ERROR_NONE) { - ret = __convert_device_io_direction(mm_sound_io_direction, io_direction); + ret = _convert_device_io_direction(mm_sound_io_direction, io_direction); } - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_device_id (sound_device_h device, int *id) @@ -1089,7 +927,7 @@ int sound_manager_get_device_id (sound_device_h device, int *id) int ret = MM_ERROR_NONE; ret = mm_sound_get_device_id(device, id); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_device_name (sound_device_h device, char **name) @@ -1097,7 +935,7 @@ int sound_manager_get_device_name (sound_device_h device, char **name) int ret = MM_ERROR_NONE; ret = mm_sound_get_device_name(device, name); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_device_state (sound_device_h device, sound_device_state_e *state) @@ -1105,7 +943,7 @@ int sound_manager_get_device_state (sound_device_h device, sound_device_state_e int ret = MM_ERROR_NONE; ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_device_connected_cb (sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data) @@ -1124,7 +962,7 @@ int sound_manager_set_device_connected_cb (sound_device_mask_e device_mask, soun SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_unset_device_connected_cb (void) @@ -1146,7 +984,7 @@ int sound_manager_unset_device_connected_cb (void) SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_device_information_changed_cb (sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data) @@ -1165,7 +1003,7 @@ int sound_manager_set_device_information_changed_cb (sound_device_mask_e device_ SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_unset_device_information_changed_cb (void) @@ -1187,7 +1025,7 @@ int sound_manager_unset_device_information_changed_cb (void) SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } __attribute__ ((destructor)) diff --git a/src/sound_manager_internal.c b/src/sound_manager_internal.c index 0939b9d..ce113a9 100644 --- a/src/sound_manager_internal.c +++ b/src/sound_manager_internal.c @@ -33,7 +33,7 @@ int sound_manager_create_stream_information_internal (sound_stream_type_internal ret = MM_ERROR_OUT_OF_MEMORY; } else { memset(stream_h, 0, sizeof(sound_stream_info_s)); - ret = __convert_stream_type_for_internal(stream_type, &stream_h->stream_type); + ret = _convert_stream_type_for_internal(stream_type, &stream_h->stream_type); if (ret == MM_ERROR_NONE) { ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data); if (!ret) { @@ -43,7 +43,7 @@ int sound_manager_create_stream_information_internal (sound_stream_type_internal } } - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_set_stream_routing_option (sound_stream_info_h stream_info, const char *name, int value) @@ -56,11 +56,11 @@ int sound_manager_set_stream_routing_option (sound_stream_info_h stream_info, co SM_INSTANCE_CHECK(stream_h); SM_NULL_ARG_CHECK(name); - ret = __set_route_option(stream_h->index, name, value); + ret = _set_route_option(stream_h->index, name, value); LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_is_available_stream_information (sound_stream_info_h stream_info, native_api_e api_name, bool *is_available) @@ -74,7 +74,7 @@ int sound_manager_is_available_stream_information (sound_stream_info_h stream_in SM_NULL_ARG_CHECK(is_available); *is_available = false; - name = __convert_api_name(api_name); + name = _convert_api_name(api_name); for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++) { if (stream_h->stream_conf_info.avail_frameworks[i] && !strncmp(stream_h->stream_conf_info.avail_frameworks[i], name, strlen(name))) { *is_available = true; @@ -82,7 +82,7 @@ int sound_manager_is_available_stream_information (sound_stream_info_h stream_in } } LOGI("stream_type[%s], native api[%s], is_available[%d]", stream_h->stream_type, name, *is_available); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_type_from_stream_information (sound_stream_info_h stream_info, char **type) @@ -96,7 +96,7 @@ int sound_manager_get_type_from_stream_information (sound_stream_info_h stream_i *type = stream_h->stream_type; LOGI("stream_type[%s]", *type); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_get_index_from_stream_information (sound_stream_info_h stream_info, int *index) { @@ -108,46 +108,24 @@ int sound_manager_get_index_from_stream_information (sound_stream_info_h stream_ *index = stream_h->index; LOGI("stream_index[%d]", stream_h->index); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_create_virtual_stream (sound_stream_info_h stream_info, virtual_sound_stream_h *virtual_stream) { int ret = MM_ERROR_NONE; - bool result = false; virtual_sound_stream_info_s *vstream_h = NULL; sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info; LOGI(">> enter"); - SM_INSTANCE_CHECK(virtual_stream); - SM_INSTANCE_CHECK(stream_h); - - /* check if this stream_info is available for virtual stream */ - ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_SOUND_MANAGER, &result); - if (ret == MM_ERROR_NONE && result == true) { - vstream_h = malloc(sizeof(virtual_sound_stream_info_s)); - if(!vstream_h) { - ret = MM_ERROR_OUT_OF_MEMORY; - } else { - memset(vstream_h, 0, sizeof(virtual_sound_stream_info_s)); - vstream_h->stream_type = stream_h->stream_type; - vstream_h->pa_mainloop = stream_h->pa_mainloop; - vstream_h->pa_context = stream_h->pa_context; - vstream_h->pa_proplist = pa_proplist_new(); - pa_proplist_sets(vstream_h->pa_proplist, PA_PROP_MEDIA_ROLE, vstream_h->stream_type); - pa_proplist_setf(vstream_h->pa_proplist, PA_PROP_MEDIA_PARENT_ID, "%u", stream_h->index); - vstream_h->state = _VSTREAM_STATE_READY; - vstream_h->stream_info = stream_h; - *virtual_stream = (virtual_sound_stream_h)vstream_h; - } - } else { - ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION; - } + ret = _create_virtual_stream(stream_h, &vstream_h); + if (ret == MM_ERROR_NONE) + *virtual_stream = (virtual_sound_stream_h)vstream_h; LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_destroy_virtual_stream (virtual_sound_stream_h virtual_stream) @@ -157,167 +135,37 @@ int sound_manager_destroy_virtual_stream (virtual_sound_stream_h virtual_stream) LOGI(">> enter"); - SM_INSTANCE_CHECK(vstream_h); - SM_STATE_CHECK(vstream_h, _VSTREAM_STATE_READY); - - vstream_h->pa_mainloop = NULL; - vstream_h->pa_context = NULL; - if (vstream_h->pa_proplist) - pa_proplist_free(vstream_h->pa_proplist); - - free(vstream_h); + ret = _destroy_virtual_stream(vstream_h); LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_start_virtual_stream (virtual_sound_stream_h virtual_stream) { int ret = MM_ERROR_NONE; - int pa_ret = PA_OK; - int i = 0; - int io_direction = 0; - pa_sample_spec ss; - pa_channel_map maps; - virtual_sound_stream_info_s *vstream_h = (virtual_sound_stream_info_s*)virtual_stream; LOGI(">> enter"); - SM_INSTANCE_CHECK(vstream_h); - SM_STATE_CHECK(vstream_h, _VSTREAM_STATE_READY); - - if (vstream_h->stream_info->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { - /* check if the manual route info. is set when it comes to the manual route type */ - if (vstream_h->stream_info->manual_route_info.is_set == false) { - ret = MM_ERROR_SOUND_INVALID_STATE; - goto ERROR; - } - } - - /* fill up with default value */ - ss.channels = 2; - ss.rate = 44100; - ss.format = PA_SAMPLE_S16LE; - pa_channel_map_init_auto(&maps, ss.channels, PA_CHANNEL_MAP_ALSA); - - /* check direction of this stream */ - if (vstream_h->stream_info->stream_conf_info.avail_in_devices[0] != NULL) - io_direction |= SOUND_STREAM_DIRECTION_INPUT; - if (vstream_h->stream_info->stream_conf_info.avail_out_devices[0] != NULL) - io_direction |= SOUND_STREAM_DIRECTION_OUTPUT; - - /* LOCK the pa_threaded_mainloop */ - pa_threaded_mainloop_lock(vstream_h->pa_mainloop); - - for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { - if (io_direction & (i + 1)) { - vstream_h->pa_stream[i] = pa_stream_new_with_proplist(vstream_h->pa_context, "VIRTUAL_STREAM", &ss, &maps, vstream_h->pa_proplist); - if(vstream_h->pa_stream[i] == NULL) { - LOGE("failed to pa_stream_new_with_proplist()"); - pa_ret = pa_context_errno(vstream_h->pa_context); - ret = MM_ERROR_SOUND_INTERNAL; - goto ERROR_WITH_UNLOCK; - } - pa_stream_set_state_callback(vstream_h->pa_stream[i], _pa_stream_state_cb, vstream_h); - - if ((i + 1) == SOUND_STREAM_DIRECTION_OUTPUT) { - pa_ret = pa_stream_connect_playback(vstream_h->pa_stream[i], NULL, NULL, 0, NULL, NULL); - if (pa_ret < 0) { - LOGE("failed to pa_stream_connect_playback()"); - pa_ret = pa_context_errno(vstream_h->pa_context); - ret = MM_ERROR_SOUND_INTERNAL; - goto ERROR_WITH_UNLOCK; - } - } else if ((i + 1) == SOUND_STREAM_DIRECTION_INPUT) { - pa_ret = pa_stream_connect_record(vstream_h->pa_stream[i], NULL, NULL, 0); - if (pa_ret < 0) { - LOGE("failed to pa_stream_connect_record()"); - pa_ret = pa_context_errno(vstream_h->pa_context); - ret = MM_ERROR_SOUND_INTERNAL; - goto ERROR_WITH_UNLOCK; - } - } - - /* wait for ready state of the stream */ - for (;;) { - pa_stream_state_t state; - state = pa_stream_get_state(vstream_h->pa_stream[i]); - if (state == PA_STREAM_READY) { - break; - } - if (!PA_STREAM_IS_GOOD(state)) { - pa_ret = pa_context_errno(vstream_h->pa_context); - } - pa_threaded_mainloop_wait(vstream_h->pa_mainloop); - } - } - } - vstream_h->state = _VSTREAM_STATE_RUNNING; - - /* UNLOCK the pa_threaded_mainloop */ - pa_threaded_mainloop_unlock(vstream_h->pa_mainloop); + ret = _start_virtual_stream(vstream_h); LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); - -ERROR_WITH_UNLOCK: - /* UNLOCK the pa_threaded_mainloop */ - pa_threaded_mainloop_unlock(vstream_h->pa_mainloop); - - for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { - if (vstream_h->pa_stream[i]) { - pa_stream_unref(vstream_h->pa_stream[i]); - vstream_h->pa_stream[i] = NULL; - } - } - LOGE("pa_ret(%d)", pa_ret); - -ERROR: - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } int sound_manager_stop_virtual_stream (virtual_sound_stream_h virtual_stream) { int ret = MM_ERROR_NONE; - int i = 0; virtual_sound_stream_info_s *vstream_h = (virtual_sound_stream_info_s*)virtual_stream; LOGI(">> enter"); - SM_INSTANCE_CHECK(vstream_h); - SM_STATE_CHECK(vstream_h, _VSTREAM_STATE_RUNNING); - - /* LOCK the pa_threaded_mainloop */ - pa_threaded_mainloop_lock(vstream_h->pa_mainloop); - - for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { - if (vstream_h->pa_stream[i]) { - pa_stream_disconnect(vstream_h->pa_stream[i]); - - /* wait for terminated state of the stream */ - for (;;) { - pa_stream_state_t state; - state = pa_stream_get_state(vstream_h->pa_stream[i]); - if (state == PA_STREAM_TERMINATED) { - break; - } - pa_threaded_mainloop_wait(vstream_h->pa_mainloop); - } - - pa_stream_unref(vstream_h->pa_stream[i]); - vstream_h->pa_stream[i] = NULL; - } - } - - /* UNLOCK the pa_threaded_mainloop */ - pa_threaded_mainloop_unlock(vstream_h->pa_mainloop); - - vstream_h->state = _VSTREAM_STATE_READY; + ret = _stop_virtual_stream(vstream_h); LOGI("<< leave : ret(%p)", ret); - return __convert_sound_manager_error_code(__func__, ret); + return _convert_sound_manager_error_code(__func__, ret); } diff --git a/src/sound_manager_private.c b/src/sound_manager_private.c index c931887..6124556 100644 --- a/src/sound_manager_private.c +++ b/src/sound_manager_private.c @@ -30,12 +30,15 @@ extern _session_interrupt_info_s g_session_interrupt_cb_table; extern _session_mode_e g_cached_session_mode; +extern int g_cached_voip_device_id; extern _focus_watch_info_s g_focus_watch_cb_table; -extern sound_stream_info_s* sound_stream_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; +virtual_sound_stream_info_s *g_voip_vstream_h = NULL; int g_stream_info_count = 0; pthread_mutex_t g_stream_info_count_mutex = PTHREAD_MUTEX_INITIALIZER; -int __convert_sound_manager_error_code (const char *func, int code) { +int _convert_sound_manager_error_code (const char *func, int code) { int ret = SOUND_MANAGER_ERROR_NONE; char *errorstr = NULL; @@ -96,7 +99,7 @@ int __convert_sound_manager_error_code (const char *func, int code) { return ret; } -int __convert_stream_type (sound_stream_type_e stream_type_enum, char **stream_type) +int _convert_stream_type (sound_stream_type_e stream_type_enum, char **stream_type) { int ret = MM_ERROR_NONE; @@ -142,7 +145,7 @@ int __convert_stream_type (sound_stream_type_e stream_type_enum, char **stream_t return ret; } -int __convert_stream_type_for_internal (sound_stream_type_internal_e stream_type_enum, char **stream_type) +int _convert_stream_type_for_internal (sound_stream_type_internal_e stream_type_enum, char **stream_type) { int ret = MM_ERROR_NONE; @@ -176,7 +179,7 @@ int __convert_stream_type_for_internal (sound_stream_type_internal_e stream_type return ret; } -int __convert_stream_type_to_change_reason (const char *stream_type, sound_stream_focus_change_reason_e *change_reason) +int _convert_stream_type_to_change_reason (const char *stream_type, sound_stream_focus_change_reason_e *change_reason) { int ret = MM_ERROR_NONE; @@ -223,7 +226,7 @@ int __convert_stream_type_to_change_reason (const char *stream_type, sound_strea return ret; } -static int __convert_stream_type_to_interrupt_reason (const char *stream_type, sound_session_interrupted_code_e *change_reason) +static int _convert_stream_type_to_interrupt_reason (const char *stream_type, sound_session_interrupted_code_e *change_reason) { int ret = MM_ERROR_NONE; @@ -261,7 +264,7 @@ static int __convert_stream_type_to_interrupt_reason (const char *stream_type, s return ret; } -int __convert_sound_type (sound_type_e sound_type, const char **volume_type) +int _convert_sound_type (sound_type_e sound_type, const char **volume_type) { int ret = MM_ERROR_NONE; @@ -298,7 +301,7 @@ int __convert_sound_type (sound_type_e sound_type, const char **volume_type) return ret; } -int __convert_sound_type_to_enum (char *sound_type, sound_type_e *sound_type_enum) +int _convert_sound_type_to_enum (char *sound_type, sound_type_e *sound_type_enum) { int ret = MM_ERROR_NONE; @@ -329,7 +332,7 @@ int __convert_sound_type_to_enum (char *sound_type, sound_type_e *sound_type_enu return ret; } -int __convert_device_type (sound_device_type_e device_type_enum, char **device_type) +int _convert_device_type (sound_device_type_e device_type_enum, char **device_type) { int ret = MM_ERROR_NONE; @@ -370,7 +373,7 @@ int __convert_device_type (sound_device_type_e device_type_enum, char **device_t return ret; } -int __convert_device_io_direction (mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction) +int _convert_device_io_direction (mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction) { int ret = MM_ERROR_NONE; @@ -390,7 +393,7 @@ int __convert_device_io_direction (mm_sound_device_io_direction_e io_direction, return ret; } -const char* __convert_api_name (native_api_e api_name) +const char* _convert_api_name (native_api_e api_name) { const char* name = NULL; switch (api_name) { @@ -421,9 +424,9 @@ void _focus_state_change_callback (int index, mm_sound_focus_type_e focus_type, LOGI(">> enter"); sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA; - ret = __convert_stream_type_to_change_reason(reason_for_change, &change_reason); + ret = _convert_stream_type_to_change_reason(reason_for_change, &change_reason); if (ret) { - LOGE("failed to __convert_stream_type_to_enum(), reason_for_change(%s), err(0x%08x)", reason_for_change, ret); + LOGE("failed to _convert_stream_type_to_enum(), reason_for_change(%s), err(0x%08x)", reason_for_change, ret); } else { for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++) { if (sound_stream_info_arr[i] && sound_stream_info_arr[i]->index == index) { @@ -452,9 +455,9 @@ void _focus_watch_callback (int index, mm_sound_focus_type_e focus_type, mm_soun { int ret = MM_ERROR_NONE; sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA; - ret = __convert_stream_type_to_change_reason(reason_for_change, &change_reason); + ret = _convert_stream_type_to_change_reason(reason_for_change, &change_reason); if (ret) - LOGE("failed to __convert_stream_type_to_enum(), reason_for_change(%s), err(0x%08x)", reason_for_change, ret); + LOGE("failed to _convert_stream_type_to_enum(), reason_for_change(%s), err(0x%08x)", reason_for_change, ret); if (g_focus_watch_cb_table.user_cb) g_focus_watch_cb_table.user_cb(focus_type, state, change_reason, additional_info, g_focus_watch_cb_table.user_data); return; @@ -503,7 +506,7 @@ void _pa_stream_state_cb (pa_stream *s, void * userdata) } } -int __get_stream_conf_info (const char *stream_type, stream_conf_info_s *info) +int _get_stream_conf_info (const char *stream_type, stream_conf_info_s *info) { int ret = MM_ERROR_NONE; GVariant *result = NULL; @@ -623,7 +626,7 @@ int __get_stream_conf_info (const char *stream_type, stream_conf_info_s *info) return ret; } -int __set_manual_route_info (unsigned int index, manual_route_info_s *info) +int _set_manual_route_info (unsigned int index, manual_route_info_s *info) { int ret = MM_ERROR_NONE; int i = 0; @@ -693,7 +696,7 @@ int __set_manual_route_info (unsigned int index, manual_route_info_s *info) return ret; } -int __set_route_option (unsigned int index, const char *name, int value) +int _set_route_option (unsigned int index, const char *name, int value) { int ret = MM_ERROR_NONE; @@ -743,7 +746,7 @@ int __set_route_option (unsigned int index, const char *name, int value) return ret; } -int __get_volume_max_level (const char *direction, const char *volume_type, unsigned int *max_level) +int _get_volume_max_level (const char *direction, const char *volume_type, unsigned int *max_level) { int ret = MM_ERROR_NONE; @@ -790,7 +793,7 @@ int __get_volume_max_level (const char *direction, const char *volume_type, unsi return ret; } -int __get_current_volume_type (const char *direction, char **volume_type) +int _get_current_volume_type (const char *direction, char **volume_type) { int ret = MM_ERROR_NONE; @@ -842,7 +845,7 @@ int __get_current_volume_type (const char *direction, char **volume_type) return ret; } -void __update_focus_status (unsigned int index, unsigned int acquired_focus_status) +void _update_focus_status (unsigned int index, unsigned int acquired_focus_status) { GVariant *result = NULL; GDBusConnection *conn = NULL; @@ -881,43 +884,6 @@ void __update_focus_status (unsigned int index, unsigned int acquired_focus_stat return; } -void __session_interrupt_cb (session_msg_t msg, session_event_t event, void *user_data){ - if( g_session_interrupt_cb_table.user_cb ){ - sound_session_interrupted_code_e e = SOUND_SESSION_INTERRUPTED_COMPLETED; - if( msg == MM_SESSION_MSG_RESUME ) - e = SOUND_SESSION_INTERRUPTED_COMPLETED; - else{ - switch(event){ - case MM_SESSION_EVENT_MEDIA : - e = SOUND_SESSION_INTERRUPTED_BY_MEDIA; - break; - case MM_SESSION_EVENT_CALL : - e = SOUND_SESSION_INTERRUPTED_BY_CALL; - break; - case MM_SESSION_EVENT_ALARM : - e = SOUND_SESSION_INTERRUPTED_BY_ALARM; - break; - case MM_SESSION_EVENT_EARJACK_UNPLUG: - e = SOUND_SESSION_INTERRUPTED_BY_EARJACK_UNPLUG; - break; - case MM_SESSION_EVENT_RESOURCE_CONFLICT: - e = SOUND_SESSION_INTERRUPTED_BY_RESOURCE_CONFLICT; - break; - case MM_SESSION_EVENT_EMERGENCY: - e = SOUND_SESSION_INTERRUPTED_BY_EMERGENCY; - break; - case MM_SESSION_EVENT_NOTIFICATION : - e = SOUND_SESSION_INTERRUPTED_BY_NOTIFICATION; - break; - default : - e = SOUND_SESSION_INTERRUPTED_BY_MEDIA; - break; - } - } - g_session_interrupt_cb_table.user_cb(e, g_session_interrupt_cb_table.user_data); - } -} - void _focus_session_interrupt_cb (mm_sound_focus_state_e state, const char *reason_for_change, bool is_wcb, void *user_data) { sound_session_interrupted_code_e e; @@ -927,13 +893,13 @@ void _focus_session_interrupt_cb (mm_sound_focus_state_e state, const char *reas if (state == FOCUS_IS_RELEASED) { e = SOUND_SESSION_INTERRUPTED_COMPLETED; } else { - __convert_stream_type_to_interrupt_reason(reason_for_change, &e); + _convert_stream_type_to_interrupt_reason(reason_for_change, &e); } } else { if (state == FOCUS_IS_ACQUIRED) { e = SOUND_SESSION_INTERRUPTED_COMPLETED; } else { - __convert_stream_type_to_interrupt_reason(reason_for_change, &e); + _convert_stream_type_to_interrupt_reason(reason_for_change, &e); } } g_session_interrupt_cb_table.user_cb(e, g_session_interrupt_cb_table.user_data); @@ -942,16 +908,16 @@ void _focus_session_interrupt_cb (mm_sound_focus_state_e state, const char *reas void _device_connected_cb(sound_device_h device, bool is_connected, void *user_data) { - sound_device_type_e type; - if (sound_manager_get_device_type (device, &type) != MM_ERROR_NONE) { + mm_sound_device_type_e type; + if (mm_sound_get_device_type (device, &type) != MM_ERROR_NONE) { LOGE("getting device type failed"); } else { switch (type) { - case SOUND_DEVICE_AUDIO_JACK: - case SOUND_DEVICE_BLUETOOTH: - case SOUND_DEVICE_HDMI: - case SOUND_DEVICE_MIRRORING: - case SOUND_DEVICE_USB_AUDIO: + case MM_SOUND_DEVICE_TYPE_AUDIOJACK: + case MM_SOUND_DEVICE_TYPE_BLUETOOTH: + case MM_SOUND_DEVICE_TYPE_HDMI: + case MM_SOUND_DEVICE_TYPE_MIRRORING: + case MM_SOUND_DEVICE_TYPE_USB_AUDIO: if (!is_connected) { LOGI("sound device unplugged"); g_session_interrupt_cb_table.user_cb(SOUND_SESSION_INTERRUPTED_BY_EARJACK_UNPLUG, g_session_interrupt_cb_table.user_data); @@ -963,173 +929,258 @@ void _device_connected_cb(sound_device_h device, bool is_connected, void *user_d } } -int __set_session_mode (_session_mode_e mode) +/* This is an internal callback for the VOIP SESSION */ +void _voip_focus_state_change_callback (sound_stream_info_h stream_info, sound_stream_focus_change_reason_e reason_for_change, const char *additional_info, void *user_data) +{ + sound_stream_info_s *info = (sound_stream_info_s *)stream_info; + LOGI(">> enter, stream_info(%p), change_reason(%d), additional_info(%s)", stream_info, reason_for_change, additional_info); + + if (!info) { + LOGE("stream info is null"); + return; + } + + 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_vstream_h) { + /* stop virtual stream handle */ + _stop_virtual_stream(g_voip_vstream_h); + /* destroy virtual stream handle */ + _destroy_virtual_stream(g_voip_vstream_h); + g_voip_vstream_h = NULL; + LOGW("internal voip stream is interrupted by (%d)", reason_for_change); + } + } + + LOGI("<< leave"); + + return; +} + +int _set_session_mode (_session_mode_e mode) { int ret = MM_ERROR_NONE; - mm_sound_route route = MM_SOUND_ROUTE_IN_MIC_OUT_SPEAKER; - bool need_to_check_device = false; - bool do_subsession = true; + int w_ret = MM_ERROR_NONE; + int i_ret = SOUND_MANAGER_ERROR_NONE; + bool is_found = false; + MMSoundDeviceList_t device_list; + MMSoundDevice_t tmp_device = NULL; + MMSoundDevice_t proper_device = NULL; + MMSoundDevice_t prev_device = NULL; + mm_sound_device_type_e type; + int id = -1; + + if (g_cached_session_mode == mode) { + LOGW("session_mode(%d) is same as before", mode); + return ret; + } switch (mode) { case _SESSION_MODE_RINGTONE: - if (g_cached_session_mode != mode) { - /* sub-session */ - ret = mm_session_set_subsession (MM_SUBSESSION_TYPE_RINGTONE, MM_SUBSESSION_OPTION_NONE); - if (ret != MM_ERROR_NONE) { + if (g_voip_vstream_h) { + /* 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); + free(g_voip_stream_info); + g_voip_stream_info = NULL; + } + if (!g_voip_stream_info) { + g_voip_stream_info = malloc(sizeof(sound_stream_info_s)); + if (!g_voip_stream_info) { + ret = MM_ERROR_OUT_OF_MEMORY; goto ERROR_CASE; } + memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s)); } - g_cached_session_mode = mode; - do_subsession = false; - break; - case _SESSION_MODE_VOICE_WITH_BUILTIN_RECEIVER: - route = MM_SOUND_ROUTE_IN_MIC_OUT_RECEIVER; - break; - case _SESSION_MODE_VOICE_WITH_BUILTIN_SPEAKER: - route = MM_SOUND_ROUTE_IN_MIC_OUT_SPEAKER; - break; - case _SESSION_MODE_VOICE_WITH_AUDIO_JACK: - route = MM_SOUND_ROUTE_IN_MIC_OUT_HEADPHONE; - need_to_check_device = true; - break; - case _SESSION_MODE_VOICE_WITH_BLUETOOTH: - route = MM_SOUND_ROUTE_INOUT_BLUETOOTH; - need_to_check_device = true; - break; - } - - if (need_to_check_device) { - int w_ret = MM_ERROR_NONE; - MMSoundDeviceList_t device_list; - MMSoundDevice_t device; - do_subsession = false; - - ret = mm_sound_get_current_device_list(MM_SOUND_DEVICE_ALL_FLAG, &device_list); - if (ret != MM_ERROR_NONE) { - goto ERROR_CASE; - } else { - while ((w_ret = mm_sound_get_next_device(device_list, &device)) == MM_ERROR_NONE) { - mm_sound_device_type_e type; - ret = mm_sound_get_device_type(device, &type); - if (ret != MM_ERROR_NONE) + /* create stream info and acquire focus for rintone-voip stream */ + g_voip_stream_info->stream_type = "ringtone-voip"; + ret = _make_pa_connection_and_register_focus(g_voip_stream_info, _voip_focus_state_change_callback, NULL); + if (ret != MM_ERROR_NONE) { + free(g_voip_stream_info); + g_voip_stream_info = NULL; + goto ERROR_CASE; + } else { + /* acquire focus */ + ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, "for voip session"); + if (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); + } else { goto ERROR_CASE; - - switch (mode) { - case _SESSION_MODE_VOICE_WITH_AUDIO_JACK: - if (type == MM_SOUND_DEVICE_TYPE_AUDIOJACK) { - mm_sound_device_io_direction_e io_direction; - ret = mm_sound_get_device_io_direction(device, &io_direction); - if (ret != MM_ERROR_NONE) - goto ERROR_CASE; - if (io_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) - route = MM_SOUND_ROUTE_INOUT_HEADSET; - else if (io_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT) - route = MM_SOUND_ROUTE_IN_MIC_OUT_HEADPHONE; - do_subsession = true; + } + } + /* create virtual stream for ringtone-voip */ + i_ret = _create_virtual_stream (g_voip_stream_info, &g_voip_vstream_h); + if (i_ret == SOUND_MANAGER_ERROR_NONE) { + i_ret = _start_virtual_stream (g_voip_vstream_h); + if (i_ret != SOUND_MANAGER_ERROR_NONE) { + goto ERROR_CASE; + } + } else { + ret = MM_ERROR_SOUND_INTERNAL; + goto ERROR_CASE; + } + break; + case _SESSION_MODE_VOICE_WITH_BUILTIN_RECEIVER: /* Built-in RCV and Built-in MIC */ + case _SESSION_MODE_VOICE_WITH_BUILTIN_SPEAKER: /* Built-in SPK and Built-in MIC */ + case _SESSION_MODE_VOICE_WITH_AUDIO_JACK: /* Earphone spk & mic */ + case _SESSION_MODE_VOICE_WITH_BLUETOOTH: /* Bluetooth spk & mic */ + /* check if the device is available now */ + ret = mm_sound_get_current_device_list(MM_SOUND_DEVICE_ALL_FLAG, &device_list); + if (ret != MM_ERROR_NONE) { + LOGE("failed to get current device list"); + goto ERROR_CASE; + } else { + while (!is_found && ((w_ret = mm_sound_get_next_device(device_list, &tmp_device)) == MM_ERROR_NONE)) { + ret = mm_sound_get_device_type(tmp_device, &type); + if (ret != MM_ERROR_NONE) { + goto ERROR_CASE; + } + ret = mm_sound_get_device_id(tmp_device, &id); + if (ret != MM_ERROR_NONE) { + goto ERROR_CASE; + } else { + if (g_cached_voip_device_id != -1 && g_cached_voip_device_id == id) { + prev_device = tmp_device; } - break; - case _SESSION_MODE_VOICE_WITH_BLUETOOTH: - if (type == MM_SOUND_DEVICE_TYPE_BLUETOOTH) { - mm_sound_device_io_direction_e io_direction; - ret = mm_sound_get_device_io_direction(device, &io_direction); - if (ret != MM_ERROR_NONE) - goto ERROR_CASE; - if (io_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { - route = MM_SOUND_ROUTE_INOUT_BLUETOOTH; - do_subsession = true; + } + switch (mode) { + case _SESSION_MODE_VOICE_WITH_BUILTIN_RECEIVER: + if (type == MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER) { + is_found = true; + proper_device = tmp_device; + break; + } + case _SESSION_MODE_VOICE_WITH_BUILTIN_SPEAKER: + if (type == MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER) { + is_found = true; + proper_device = tmp_device; + break; + } + case _SESSION_MODE_VOICE_WITH_AUDIO_JACK: + if (type == MM_SOUND_DEVICE_TYPE_AUDIOJACK) { + is_found = true; + proper_device = tmp_device; + break; + } + break; + case _SESSION_MODE_VOICE_WITH_BLUETOOTH: + if (type == MM_SOUND_DEVICE_TYPE_BLUETOOTH) { + is_found = true; + proper_device = tmp_device; + break; } + default: + break; + } + } + if (!is_found) { + LOGE("could not found a proper connected device for this mode(%d)", mode); + ret = MM_ERROR_SOUND_INTERNAL; + goto ERROR_CASE_NO_DESTROY; + } + } + /* if ok for the device, go below */ + 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); + free(g_voip_stream_info); + g_voip_stream_info = 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) { + ret = MM_ERROR_OUT_OF_MEMORY; + goto ERROR_CASE; + } + memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s)); + } + g_voip_stream_info->stream_type = "voip"; + ret = _make_pa_connection_and_register_focus(g_voip_stream_info, _voip_focus_state_change_callback, NULL); + if (ret != MM_ERROR_NONE) { + free(g_voip_stream_info); + g_voip_stream_info = NULL; + goto ERROR_CASE; + } + /* set device for routing to the device */ + i_ret = _add_device_for_stream_routing(g_voip_stream_info, proper_device); + if (i_ret == SOUND_MANAGER_ERROR_NONE) { + i_ret = _apply_stream_routing(g_voip_stream_info); + if (i_ret != SOUND_MANAGER_ERROR_NONE) { + goto ERROR_CASE; + } + } else { + goto ERROR_CASE; + } + /* acquire focus */ + ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, "for voip session"); + if (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); + } else { + goto ERROR_CASE; + } + /* create virtual stream for voip */ + i_ret = _create_virtual_stream(g_voip_stream_info, &g_voip_vstream_h); + if (i_ret == SOUND_MANAGER_ERROR_NONE) { + i_ret = _start_virtual_stream(g_voip_vstream_h); + if (i_ret != SOUND_MANAGER_ERROR_NONE) { + goto ERROR_CASE; + } + } else { + goto ERROR_CASE; + } + } else { + if (g_cached_voip_device_id != -1 && prev_device) { + /* remove cached device */ + i_ret = _remove_device_for_stream_routing(g_voip_stream_info, prev_device); + if (i_ret != SOUND_MANAGER_ERROR_NONE) { + goto ERROR_CASE; + } + /* set device for routing to the device */ + i_ret = _add_device_for_stream_routing(g_voip_stream_info, proper_device); + if (i_ret == SOUND_MANAGER_ERROR_NONE) { + i_ret = _apply_stream_routing(g_voip_stream_info); + if (i_ret != SOUND_MANAGER_ERROR_NONE) { + goto ERROR_CASE; } - break; - default: - break; + } else { + goto ERROR_CASE; + } + } else { + goto ERROR_CASE; } } - } + break; } - /* sub-session */ - if (do_subsession && (g_cached_session_mode != mode)) { - ret = mm_session_set_subsession (MM_SUBSESSION_TYPE_VOICE, MM_SUBSESSION_OPTION_NONE); - if (ret != MM_ERROR_NONE) { - goto ERROR_CASE; - } - /* route */ + g_cached_session_mode = mode; + g_cached_voip_device_id = id; -#ifdef TMP_CODE - mm_sound_set_active_route(route); //not getting return value temporarily. when 2.4 feature for routing is fully implemented, it will be recoverd. -#else - ret = mm_sound_set_active_route(route); -#endif - - if (ret != MM_ERROR_NONE) { - goto ERROR_CASE; - } - g_cached_session_mode = mode; - } else { - if (!do_subsession && mode != _SESSION_MODE_RINGTONE) { - ret = MM_ERROR_SOUND_INTERNAL; - } - } -ERROR_CASE: return ret; -} - -int __get_session_mode (_session_mode_e *mode) -{ - int ret = MM_ERROR_NONE; - int subsession = 0; - ret = mm_session_get_subsession ((mm_subsession_t *)&subsession); - if(ret != MM_ERROR_NONE) { - goto ERROR_CASE; - } - switch (subsession) { - case MM_SUBSESSION_TYPE_VOICE: - { - int w_ret = MM_ERROR_NONE; - bool need_to_out = false; - MMSoundDeviceList_t device_list; - MMSoundDevice_t device; - ret = mm_sound_get_current_device_list(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG, &device_list); - if (ret != MM_ERROR_NONE) { - goto ERROR_CASE; - } else { - while ((w_ret = mm_sound_get_next_device(device_list, &device)) == MM_ERROR_NONE) { - mm_sound_device_type_e type; - ret = mm_sound_get_device_type(device, &type); - if (ret != MM_ERROR_NONE) - goto ERROR_CASE; - switch (type) { - case MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER: - *mode = _SESSION_MODE_VOICE_WITH_BUILTIN_SPEAKER; - need_to_out = true; - break; - case MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER: - *mode = _SESSION_MODE_VOICE_WITH_BUILTIN_RECEIVER; - need_to_out = true; - break; - case MM_SOUND_DEVICE_TYPE_AUDIOJACK: - *mode = _SESSION_MODE_VOICE_WITH_AUDIO_JACK; - need_to_out = true; - break; - case MM_SOUND_DEVICE_TYPE_BLUETOOTH: - *mode = _SESSION_MODE_VOICE_WITH_BLUETOOTH; - need_to_out = true; - break; - default: - break; - } - if (need_to_out) - break; - } - } +ERROR_CASE: + if (g_voip_vstream_h) { + /* destroy virtual stream handle */ + _destroy_virtual_stream(g_voip_vstream_h); + g_voip_vstream_h = NULL; + ret = MM_ERROR_SOUND_INTERNAL; } - break; - case MM_SUBSESSION_TYPE_RINGTONE: - *mode = _SESSION_MODE_RINGTONE; - break; - default: - break; + if (g_voip_stream_info) { + /* destroy stream info */ + _destroy_pa_connection_and_unregister_focus(g_voip_stream_info); + free(g_voip_stream_info); + g_voip_stream_info = NULL; } -ERROR_CASE: +ERROR_CASE_NO_DESTROY: return ret; } @@ -1139,8 +1190,6 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_ int pa_ret = PA_OK; int i = 0; - SM_ENTER_CRITICAL_SECTION_WITH_RETURN( &g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL); - if (!(stream_h->pa_mainloop = pa_threaded_mainloop_new())) goto PA_ERROR; @@ -1176,7 +1225,7 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_ stream_h->index = pa_context_get_index(stream_h->pa_context); /* get configuration information of this stream type */ - ret = __get_stream_conf_info(stream_h->stream_type, &stream_h->stream_conf_info); + ret = _get_stream_conf_info(stream_h->stream_type, &stream_h->stream_conf_info); if (ret) { goto PA_ERROR_WITH_UNLOCK; } else { @@ -1185,8 +1234,6 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_ pa_threaded_mainloop_unlock(stream_h->pa_mainloop); - SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret); - /* register focus */ ret = mm_sound_register_focus(stream_h->index, stream_h->stream_type, _focus_state_change_callback, user_data); if (ret == MM_ERROR_NONE) { @@ -1202,12 +1249,10 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_ if (i == SOUND_STREAM_INFO_ARR_MAX) { LOGE("client sound stream info array is full"); ret = mm_sound_unregister_focus(stream_h->index); - SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret); goto PA_ERROR; } } else { LOGE("failed to register focus, ret(0x%x)", ret); - SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret); /* disconnect */ goto PA_ERROR; } @@ -1250,8 +1295,6 @@ PA_ERROR: LOGE("pa_ret(%d), ret(%p)", pa_ret, ret); SUCCESS: - SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex); - return ret; } @@ -1260,8 +1303,6 @@ int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h) int i = 0; int ret = MM_ERROR_NONE; - SM_ENTER_CRITICAL_SECTION_WITH_RETURN( &g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL); - if (stream_h->pa_context) { pa_context_disconnect(stream_h->pa_context); pa_context_unref(stream_h->pa_context); @@ -1298,11 +1339,387 @@ int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h) break; } } - free(stream_h); - SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret); + return ret; +} + +int _add_device_for_stream_routing (sound_stream_info_s *stream_info, sound_device_h device) +{ + int ret = MM_ERROR_NONE; + int i = 0; + int j = 0; + bool added_successfully = false; + char *device_type_str = NULL; + int device_id = 0; + mm_sound_device_type_e device_type; + mm_sound_device_io_direction_e device_direction; + + SM_INSTANCE_CHECK(stream_info); + SM_NULL_ARG_CHECK(device); + + if (stream_info->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { + ret = mm_sound_get_device_id(device, &device_id); + if (ret) { + return _convert_sound_manager_error_code(__func__, ret); + } + ret = mm_sound_get_device_type(device, &device_type); + if (ret) { + return _convert_sound_manager_error_code(__func__, ret); + } + ret = _convert_device_type(device_type, &device_type_str); + if (ret) { + return _convert_sound_manager_error_code(__func__, ret); + } + ret = mm_sound_get_device_io_direction(device, &device_direction); + if (ret) { + return _convert_sound_manager_error_code(__func__, ret); + } + if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { + for (i = 0; i < AVAIL_DEVICES_MAX; i++) { + if (stream_info->stream_conf_info.avail_in_devices[i]) { + if (!strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { + for (j = 0; j < AVAIL_DEVICES_MAX; j++) { + if (!stream_info->manual_route_info.route_in_devices[j]) { + stream_info->manual_route_info.route_in_devices[j] = (unsigned int)device_id; + added_successfully = true; + break; + } + if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) { + /* it was already set */ + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED); + } + } + } + } else { + break; + } + } + } + if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { + for (i = 0; i < AVAIL_DEVICES_MAX; i++) { + if (stream_info->stream_conf_info.avail_out_devices[i]) { + if (!strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { + for (j = 0; j < AVAIL_DEVICES_MAX; j++) { + if (!stream_info->manual_route_info.route_out_devices[j]) { + stream_info->manual_route_info.route_out_devices[j] = (unsigned int)device_id; + added_successfully = true; + break; + } + if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) { + /* it was already set */ + return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED); + } + } + } + } else { + break; + } + } + } + } + + if (!added_successfully) { + ret = MM_ERROR_POLICY_INTERNAL; + } + + return ret; +} + +int _remove_device_for_stream_routing (sound_stream_info_s *stream_info, sound_device_h device) +{ + int ret = MM_ERROR_NONE; + int i = 0; + int j = 0; + bool removed_successfully = false; + char *device_type_str = NULL; + int device_id = 0; + mm_sound_device_type_e device_type; + mm_sound_device_io_direction_e device_direction; + + SM_INSTANCE_CHECK(stream_info); + SM_NULL_ARG_CHECK(device); + + if (stream_info->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { + ret = mm_sound_get_device_id(device, &device_id); + if (ret) { + return _convert_sound_manager_error_code(__func__, ret); + } + ret = mm_sound_get_device_type(device, &device_type); + if (ret) { + return _convert_sound_manager_error_code(__func__, ret); + } + ret = _convert_device_type(device_type, &device_type_str); + ret = mm_sound_get_device_io_direction(device, &device_direction); + if (ret) { + return _convert_sound_manager_error_code(__func__, ret); + } + if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { + for (i = 0; i < AVAIL_DEVICES_MAX; i++) { + if (stream_info->stream_conf_info.avail_in_devices[i]) { + if (!strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { + for (j = 0; j < AVAIL_DEVICES_MAX; j++) { + if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) { + removed_successfully = true; + stream_info->manual_route_info.route_in_devices[j] = 0; + break; + } + } + } + } else { + break; + } + } + } + if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) { + for (i = 0; i < AVAIL_DEVICES_MAX; i++) { + if (stream_info->stream_conf_info.avail_out_devices[i]) { + if (!strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN)) { + for (j = 0; j < AVAIL_DEVICES_MAX; j++) { + if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) { + removed_successfully = true; + stream_info->manual_route_info.route_out_devices[j] = 0; + break; + } + } + } + } else { + break; + } + } + } + } + + if (!removed_successfully) { + ret = MM_ERROR_INVALID_ARGUMENT; + } + + return ret; +} + +int _apply_stream_routing (sound_stream_info_s *stream_info) +{ + int ret = MM_ERROR_NONE; + int i = 0; + bool need_to_apply = false; + + SM_INSTANCE_CHECK(stream_info); + + if (stream_info->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { + for (i = 0; i < AVAIL_DEVICES_MAX; i++) { + if (stream_info->manual_route_info.route_in_devices[i]) { + need_to_apply = true; + break; + } + if (stream_info->manual_route_info.route_out_devices[i]) { + need_to_apply = true; + break; + } + } + if (need_to_apply) { + ret = _set_manual_route_info(stream_info->index, &stream_info->manual_route_info); + } else { + _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_STATE); + } + } else { + ret = MM_ERROR_SOUND_INVALID_STATE; + } + + return ret; +} + +int _create_virtual_stream (sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream) +{ + int ret = MM_ERROR_NONE; + bool result = false; + const char *name = NULL; + int i = 0; + + SM_INSTANCE_CHECK(virtual_stream); + SM_INSTANCE_CHECK(stream_info); + + /* check if this stream_info is available for virtual stream */ + name = _convert_api_name(NATIVE_API_SOUND_MANAGER); + for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++) { + if (stream_info->stream_conf_info.avail_frameworks[i] && !strncmp(stream_info->stream_conf_info.avail_frameworks[i], name, strlen(name))) { + result = true; + break; + } + } + LOGI("stream_type[%s], native api[%s], is_available[%d]", stream_info->stream_type, name, result); + if (result == true) { + (*virtual_stream) = malloc(sizeof(virtual_sound_stream_info_s)); + if(!(*virtual_stream)) { + ret = MM_ERROR_OUT_OF_MEMORY; + } else { + memset((*virtual_stream), 0, sizeof(virtual_sound_stream_info_s)); + (*virtual_stream)->stream_type = stream_info->stream_type; + (*virtual_stream)->pa_mainloop = stream_info->pa_mainloop; + (*virtual_stream)->pa_context = stream_info->pa_context; + (*virtual_stream)->pa_proplist = pa_proplist_new(); + pa_proplist_sets((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_ROLE, (*virtual_stream)->stream_type); + pa_proplist_setf((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_PARENT_ID, "%u", stream_info->index); + (*virtual_stream)->state = _VSTREAM_STATE_READY; + (*virtual_stream)->stream_info = stream_info; + } + } else { + ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION; + } + return ret; +} + +int _destroy_virtual_stream (virtual_sound_stream_info_s *virtual_stream) +{ + int ret = MM_ERROR_NONE; + + SM_INSTANCE_CHECK(virtual_stream); + SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_READY); + + virtual_stream->pa_mainloop = NULL; + virtual_stream->pa_context = NULL; + if (virtual_stream->pa_proplist) + pa_proplist_free(virtual_stream->pa_proplist); + + free(virtual_stream); + virtual_stream = NULL; + + return ret; +} + +int _start_virtual_stream (virtual_sound_stream_info_s *virtual_stream) +{ + int ret = MM_ERROR_NONE; + int pa_ret = PA_OK; + int i = 0; + int io_direction = 0; + pa_sample_spec ss; + pa_channel_map maps; + + SM_INSTANCE_CHECK(virtual_stream); + SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_READY); + + if (virtual_stream->stream_info->stream_conf_info.route_type == STREAM_ROUTE_TYPE_MANUAL) { + /* check if the manual route info. is set when it comes to the manual route type */ + if (virtual_stream->stream_info->manual_route_info.is_set == false) { + ret = MM_ERROR_SOUND_INVALID_STATE; + goto ERROR; + } + } + + /* fill up with default value */ + ss.channels = 2; + ss.rate = 44100; + ss.format = PA_SAMPLE_S16LE; + pa_channel_map_init_auto(&maps, ss.channels, PA_CHANNEL_MAP_ALSA); + + /* check direction of this stream */ + if (virtual_stream->stream_info->stream_conf_info.avail_in_devices[0] != NULL) + io_direction |= SOUND_STREAM_DIRECTION_INPUT; + if (virtual_stream->stream_info->stream_conf_info.avail_out_devices[0] != NULL) + io_direction |= SOUND_STREAM_DIRECTION_OUTPUT; + + /* LOCK the pa_threaded_mainloop */ + pa_threaded_mainloop_lock(virtual_stream->pa_mainloop); + + for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { + if (io_direction & (i + 1)) { + virtual_stream->pa_stream[i] = pa_stream_new_with_proplist(virtual_stream->pa_context, "VIRTUAL_STREAM", &ss, &maps, virtual_stream->pa_proplist); + if(virtual_stream->pa_stream[i] == NULL) { + LOGE("failed to pa_stream_new_with_proplist()"); + pa_ret = pa_context_errno(virtual_stream->pa_context); + ret = MM_ERROR_SOUND_INTERNAL; + goto ERROR_WITH_UNLOCK; + } + pa_stream_set_state_callback(virtual_stream->pa_stream[i], _pa_stream_state_cb, virtual_stream); + + if ((i + 1) == SOUND_STREAM_DIRECTION_OUTPUT) { + pa_ret = pa_stream_connect_playback(virtual_stream->pa_stream[i], NULL, NULL, 0, NULL, NULL); + if (pa_ret < 0) { + LOGE("failed to pa_stream_connect_playback()"); + pa_ret = pa_context_errno(virtual_stream->pa_context); + ret = MM_ERROR_SOUND_INTERNAL; + goto ERROR_WITH_UNLOCK; + } + } else if ((i + 1) == SOUND_STREAM_DIRECTION_INPUT) { + pa_ret = pa_stream_connect_record(virtual_stream->pa_stream[i], NULL, NULL, 0); + if (pa_ret < 0) { + LOGE("failed to pa_stream_connect_record()"); + pa_ret = pa_context_errno(virtual_stream->pa_context); + ret = MM_ERROR_SOUND_INTERNAL; + goto ERROR_WITH_UNLOCK; + } + } + + /* wait for ready state of the stream */ + for (;;) { + pa_stream_state_t state; + state = pa_stream_get_state(virtual_stream->pa_stream[i]); + if (state == PA_STREAM_READY) { + break; + } + if (!PA_STREAM_IS_GOOD(state)) { + pa_ret = pa_context_errno(virtual_stream->pa_context); + } + pa_threaded_mainloop_wait(virtual_stream->pa_mainloop); + } + } + } + virtual_stream->state = _VSTREAM_STATE_RUNNING; + + /* UNLOCK the pa_threaded_mainloop */ + pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop); + + return ret; + +ERROR_WITH_UNLOCK: + /* UNLOCK the pa_threaded_mainloop */ + pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop); + + for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { + if (virtual_stream->pa_stream[i]) { + pa_stream_unref(virtual_stream->pa_stream[i]); + virtual_stream->pa_stream[i] = NULL; + } + } + LOGE("pa_ret(%d)", pa_ret); + +ERROR: + return ret; +} + +int _stop_virtual_stream (virtual_sound_stream_info_s *virtual_stream) +{ + int ret = MM_ERROR_NONE; + int i = 0; + + SM_INSTANCE_CHECK(virtual_stream); + SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_RUNNING); + + /* LOCK the pa_threaded_mainloop */ + pa_threaded_mainloop_lock(virtual_stream->pa_mainloop); + + for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) { + if (virtual_stream->pa_stream[i]) { + pa_stream_disconnect(virtual_stream->pa_stream[i]); + + /* wait for terminated state of the stream */ + for (;;) { + pa_stream_state_t state; + state = pa_stream_get_state(virtual_stream->pa_stream[i]); + if (state == PA_STREAM_TERMINATED) { + break; + } + pa_threaded_mainloop_wait(virtual_stream->pa_mainloop); + } + + pa_stream_unref(virtual_stream->pa_stream[i]); + virtual_stream->pa_stream[i] = NULL; + } + } + + /* UNLOCK the pa_threaded_mainloop */ + pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop); - SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex); + virtual_stream->state = _VSTREAM_STATE_READY; return ret; } diff --git a/test/sound_manager_test.c b/test/sound_manager_test.c index 0beacb7..0a1c3b8 100644 --- a/test/sound_manager_test.c +++ b/test/sound_manager_test.c @@ -499,7 +499,7 @@ static void displaymenu() } else if (g_menu_state == CURRENT_STATUS_CREATE_STREAM_INFO) { - g_print("*** input stream type to create stream information (0:media, 1:alarm, 2:notification, 3:ringtone-call, 4:voice-call)\n"); + g_print("*** input stream type to create stream information (0:media, 1:alarm, 2:notification, 3:ringtone-call, 4:voice-call, 5:voip)\n"); } else if (g_menu_state == CURRENT_STATUS_ADD_DEVICE_FOR_STREAM_ROUTING) { @@ -1187,6 +1187,9 @@ static void interpret (char *cmd) case 4: /* voice call */ type = SOUND_STREAM_TYPE_VOICE_CALL; break; + case 5: /* voip */ + type = SOUND_STREAM_TYPE_VOIP; + break; default: type = SOUND_STREAM_TYPE_MEDIA; break;