Remove unused destructor/constructor block
[platform/core/api/sound-manager.git] / src / sound_manager.c
index f7126da..eabfbc5 100644 (file)
 #include "sound_manager.h"
 #include "sound_manager_private.h"
 
-_session_interrupt_info_s g_session_interrupt_cb_table = {0, NULL, NULL};
-_volume_changed_info_s g_volume_changed_cb_table = {NULL, NULL};
-_focus_watch_info_s g_focus_watch_cb_table = {NULL, NULL};
-_device_connected_info_s g_device_connected_cb_table = {NULL, NULL};
-_device_changed_info_s g_device_info_changed_cb_table = {NULL, NULL};
+_focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
 
-sound_session_type_e g_cached_session = -1;
-_session_mode_e g_cached_session_mode = -1;
-
-int sound_manager_get_max_volume (sound_type_e type, int *max)
+int sound_manager_get_max_volume(sound_type_e type, int *max)
 {
-       int volume;
-       if(max == NULL)
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+       const char *volume_type = NULL;
+       unsigned int max_level = 0;
+       int ret = MM_ERROR_NONE;
 
-       if(type >= SOUND_TYPE_NUM || type < 0)
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-       int ret = mm_sound_volume_get_step(type, &volume);
+       SM_NULL_ARG_CHECK(max);
+       if (type >= SOUND_TYPE_NUM)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
 
-       if(ret == 0)
-               *max = volume -1;       // actual volume step can be max step - 1
+       ret = _convert_sound_type(type, &volume_type);
+       if (ret == MM_ERROR_NONE) {
+               ret = _get_volume_max_level(DIRECTION_OUT_STR, 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)
+int sound_manager_set_volume(sound_type_e type, int volume)
 {
-       if(type >= SOUND_TYPE_NUM || type < 0)
-               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);
+       int ret = MM_ERROR_NONE;
+
+       if (type >= SOUND_TYPE_NUM)
+               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);
 
-       int ret = mm_sound_volume_set_value(type, volume);
-       LOGI("returns : type=%d, volume=%d, ret=%p", type, volume, ret);
+       ret = mm_sound_volume_set_value(type, volume);
+       LOGI("type=%d, volume=%d", type, volume);
 
-       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)
+int sound_manager_get_volume(sound_type_e type, int *volume)
 {
+       int ret = MM_ERROR_NONE;
        unsigned int uvolume;
-       if(type >= SOUND_TYPE_NUM || type < 0)
-               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);
-       int ret = mm_sound_volume_get_value(type, &uvolume);
 
-       if(ret == 0)
+       if (type >= SOUND_TYPE_NUM)
+               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);
+
+       ret = mm_sound_volume_get_value(type, &uvolume);
+       if (ret == MM_ERROR_NONE)
                *volume = uvolume;
 
-       LOGI("returns : type=%d, volume=%d, ret=%p", type, *volume, ret);
+       LOGI("type=%d, volume=%d", type, *volume);
 
-       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)
+int sound_manager_get_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);
+       char *volume_type = NULL;
 
-       ret = mm_sound_volume_primary_type_set(type);
+       if (type == NULL)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+
+       /* get the volume type of the current playing stream */
+       ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
+       if (ret == MM_ERROR_NONE) {
+               ret = _convert_sound_type_to_enum((const char*)volume_type, type);
+               LOGI("type=%d", *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)
+int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
-       if(type == NULL)
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-       ret = mm_sound_volume_get_current_playing_type((volume_type_t *)type);
 
-       LOGI("returns : type=%d, ret=%p", *type, ret);
+       if (!callback || !id)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, (unsigned int*)id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_unset_current_sound_type (void)
+int sound_manager_remove_volume_changed_cb(int id)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_volume_primary_type_clear();
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       if (id < 0)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+
+       ret = mm_sound_remove_volume_changed_callback(id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_set_volume_changed_cb (sound_manager_volume_changed_cb callback, void* user_data)
+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)
 {
        int ret = MM_ERROR_NONE;
 
-       ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data);
+       LOGI(">> enter");
+
+       SM_NULL_ARG_CHECK(stream_info);
+
+       sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
+       if (!stream_h) {
+               ret = MM_ERROR_OUT_OF_MEMORY;
+               goto LEAVE;
+       }
+
+       memset(stream_h, 0, sizeof(sound_stream_info_s));
+       ret = _convert_stream_type(stream_type, &stream_h->stream_type);
        if (ret == MM_ERROR_NONE) {
-               g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
-               g_volume_changed_cb_table.user_data = user_data;
+               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;
+                       LOGI("stream_h(%p), pa_index(%u), focus_id(%d), user_cb(%p), ret(0x%x)",
+                               stream_h, stream_h->pa_index, stream_h->focus_id, stream_h->user_cb, ret);
+               }
        }
 
-       return __convert_sound_manager_error_code(__func__, ret);
+LEAVE:
+       if (ret)
+               SM_SAFE_FREE(stream_h);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_unset_volume_changed_cb (void)
+int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
 {
        int ret = MM_ERROR_NONE;
+       sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
-       if (g_volume_changed_cb_table.user_cb) {
-               ret = mm_sound_remove_volume_changed_callback();
-               if (ret == MM_ERROR_NONE) {
-                       g_volume_changed_cb_table.user_cb = NULL;
-                       g_volume_changed_cb_table.user_data = NULL;
-               }
-       } else {
-               ret = MM_ERROR_SOUND_INTERNAL;
+       LOGI(">> enter");
+
+       SM_INSTANCE_CHECK(stream_h);
+
+       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+       ret = _destroy_pa_connection_and_unregister_focus(stream_h);
+       SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+       if (ret == MM_ERROR_NONE) {
+               SM_SAFE_FREE(stream_h);
        }
 
-       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)
+int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
 {
        int ret = MM_ERROR_NONE;
+       sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
-       SM_NULL_ARG_CHECK(stream_info);
-       SM_NULL_ARG_CHECK(callback);
+       SM_INSTANCE_CHECK(stream_h);
+       SM_NULL_ARG_CHECK(sound_type);
 
-       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);
-               if (ret == MM_ERROR_NONE) {
-                       ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
-                       if (!ret) {
-                               *stream_info = (sound_stream_info_h)stream_h;
-                               LOGI("<< leave : stream_h(%p), index(%u), user_cb(%p), ret(%p)", stream_h, stream_h->index, stream_h->user_cb, ret);
-                       }
-               }
+       if (stream_h->stream_conf_info.volume_type == NULL) {
+               ret = MM_ERROR_SOUND_NO_DATA;
+               goto LEAVE;
        }
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
+       LOGI("sound type(%d)", *sound_type);
+
+LEAVE:
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_destroy_stream_information (sound_stream_info_h stream_info)
+int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
 {
        int ret = MM_ERROR_NONE;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
-       SM_INSTANCE_CHECK(stream_h);
+       ret = _add_device_for_stream_routing(stream_h, device);
 
-       ret = _destroy_pa_connection_and_unregister_focus(stream_h);
+       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;
+       sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
+
+       LOGI(">> enter");
 
-       LOGI("<< leave : ret(%p)", ret);
+       ret = _remove_device_for_stream_routing(stream_h, device);
 
-       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 sound_manager_remove_all_devices_for_stream_routing(sound_stream_info_h stream_info)
+{
+       int ret = MM_ERROR_NONE;
+       sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
+
+       LOGI(">> enter");
+
+       ret = _remove_all_devices_for_stream_routing(stream_h);
+
+       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;
+       sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
+
+       LOGI(">> enter");
+
+       ret = _apply_stream_routing(stream_h);
+
+       return _convert_sound_manager_error_code(__func__, ret);
+}
+
+int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
 {
        int ret = MM_ERROR_NONE;
-       int i = 0;
-       int j = 0;
-       bool added_successfully = false;
-       char device_type_str[SOUND_DEVICE_TYPE_LEN] = {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_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] = strdup(device_type_str);
-                                                               added_successfully = true;
-                                                               break;
-                                                       }
-                                                       if (!strncmp(stream_h->manual_route_info.route_in_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
-                                                               /* 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] = strdup(device_type_str);
-                                                               added_successfully = true;
-                                                               break;
-                                                       }
-                                                       if (!strncmp(stream_h->manual_route_info.route_out_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
-                                                               /* it was already set */
-                                                               return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_DUPLICATED);
-                                                       }
-                                               }
-                                       }
-                               } else {
-                                       break;
-                               }
-                       }
-               }
-       }
+       ret = mm_sound_set_focus_reacquisition(stream_h->focus_id, enable);
 
-       if (!added_successfully) {
-               ret = MM_ERROR_POLICY_INTERNAL;
-       }
+       LOGI("enable(%d)", enable);
 
-       LOGI("<< leave : ret(%p)", ret);
+       return _convert_sound_manager_error_code(__func__, ret);
+}
+
+int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
+{
+       int ret = MM_ERROR_NONE;
+       sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       LOGI(">> enter");
+
+       SM_INSTANCE_CHECK(stream_h);
+       SM_NULL_ARG_CHECK(enabled);
+
+       ret = mm_sound_get_focus_reacquisition(stream_h->focus_id, enabled);
+
+       LOGI("enabled(%d)", *enabled);
+
+       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 sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, int sound_behavior, const char *extra_info)
 {
        int ret = MM_ERROR_NONE;
-       int i = 0;
-       int j = 0;
-       bool removed_successfully = false;
-       char device_type_str[SOUND_DEVICE_TYPE_LEN] = {0,};
-       mm_sound_device_type_e device_type;
-       mm_sound_device_io_direction_e device_direction;
+       bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = false;
        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_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 (!strncmp(stream_h->manual_route_info.route_in_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
-                                                               removed_successfully = true;
-                                                               free(stream_h->manual_route_info.route_in_devices[j]);
-                                                               stream_h->manual_route_info.route_in_devices[j] = NULL;
-                                                               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 (!strncmp(stream_h->manual_route_info.route_out_devices[j], device_type_str, SOUND_DEVICE_TYPE_LEN)) {
-                                                               removed_successfully = true;
-                                                               free(stream_h->manual_route_info.route_out_devices[j]);
-                                                               stream_h->manual_route_info.route_out_devices[j] = NULL;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               } else {
-                                       break;
-                               }
-                       }
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
+               return _convert_sound_manager_error_code(__func__, ret);
+
+       if (stream_h->is_focus_unavailable) {
+               LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
+       }
+
+       if (stream_h->user_cb == NULL) {
+               LOGE("focus state changed callback should be set before acquiring focus");
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
+       }
+
+       if (!is_focus_cb_thread) {
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+               SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+       } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
                }
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
        }
 
-       if (!removed_successfully) {
-               ret = MM_ERROR_INVALID_ARGUMENT;
+       if (stream_h->acquired_focus & focus_mask) {
+               LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
+               ret = MM_ERROR_SOUND_INVALID_STATE;
+               goto LEAVE;
+       }
+
+       if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & ~stream_h->acquired_focus) & focus_mask)) {
+               LOGE("just lost focus in this callback, it is not allowed to acquire the focus[0x%x] again. acquired_focus[0x%x], prev[0x%x]",
+                       focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
+               ret = MM_ERROR_POLICY_INTERNAL;
+               goto LEAVE;
        }
 
-       LOGI("<< leave : ret(%p)", ret);
+       stream_h->is_requesting = true;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
+       if (ret == MM_ERROR_NONE) {
+               stream_h->acquired_focus |= focus_mask;
+               stream_h->prev_acquired_focus |= focus_mask;
+               _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
+       }
+
+       LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
+
+LEAVE:
+       stream_h->is_requesting = false;
+       SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+       if (!is_focus_cb_thread)
+               SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_apply_stream_routing (sound_stream_info_h stream_info)
+int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, int sound_behavior, const char *extra_info)
 {
        int ret = MM_ERROR_NONE;
-       int i = 0;
-       bool need_to_apply = false;
+       bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = 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);
-               }
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
+               return _convert_sound_manager_error_code(__func__, ret);
+
+       if (!is_focus_cb_thread) {
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+               SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
        } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
+               }
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+       }
+
+       if (!(stream_h->acquired_focus & focus_mask)) {
+               LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
+               ret = MM_ERROR_SOUND_INVALID_STATE;
+               goto LEAVE;
+       }
+
+       if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & stream_h->acquired_focus) != focus_mask)) {
+               LOGE("just acquired focus in this callback, it is not allowed to release the focus[0x%x] again. acquired_focus[0x%x], prev[0x%x]",
+                       focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
                ret = MM_ERROR_SOUND_INVALID_STATE;
+               goto LEAVE;
        }
 
-       LOGI("<< leave : ret(%p)", ret);
+       stream_h->is_requesting = true;
+
+       ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
+       if (ret == MM_ERROR_NONE) {
+               stream_h->acquired_focus &= ~focus_mask;
+               stream_h->prev_acquired_focus &= ~focus_mask;
+               _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
+       }
+
+       LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
+
+LEAVE:
+       stream_h->is_requesting = false;
+       SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+       if (!is_focus_cb_thread)
+               SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
 
-       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)
+int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
 {
        int ret = MM_ERROR_NONE;
+       int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
+       bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = false;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
        SM_INSTANCE_CHECK(stream_h);
 
-       ret = mm_sound_acquire_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
+               return _convert_sound_manager_error_code(__func__, ret);
+
+       if (stream_h->is_focus_unavailable) {
+               LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
+       }
+
+       if (stream_h->user_cb == NULL) {
+               LOGE("focus state changed callback should be set before acquiring focus");
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
+       }
+
+       if (!is_focus_cb_thread) {
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+               SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+       } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
+               }
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+       }
+
+       if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
+               LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
+                       stream_h->acquired_focus, stream_h->prev_acquired_focus);
+               ret = MM_ERROR_POLICY_INTERNAL;
+               goto LEAVE;
+       }
+
+       focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH & ~(stream_h->acquired_focus);
+       if (!focus_mask) {
+               LOGI("PLAYBACK/RECORDING focuses have already been ACQUIRED");
+               ret = MM_ERROR_NONE;
+               goto LEAVE;
+       }
+
+       stream_h->is_requesting = true;
+
+       ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
        if (ret == MM_ERROR_NONE) {
                stream_h->acquired_focus |= focus_mask;
+               stream_h->prev_acquired_focus |= focus_mask;
+               _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
        }
 
-       LOGI("<< leave : ret(%p)", ret);
+LEAVE:
+       stream_h->is_requesting = false;
+       SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+       if (!is_focus_cb_thread)
+               SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
 
-       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)
+int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
 {
        int ret = MM_ERROR_NONE;
+       bool is_focus_cb_thread = false;
+       bool is_focus_watch_cb_thread = false;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
        SM_INSTANCE_CHECK(stream_h);
 
-       ret = mm_sound_release_focus(stream_h->index, (mm_sound_focus_type_e)focus_mask, additional_info);
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
+               return _convert_sound_manager_error_code(__func__, ret);
+
+       if (!is_focus_cb_thread) {
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+               SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
+       } else {
+               /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
+                * the focus state mutex could be still locked. Therefore, it returns error here. */
+               if (is_focus_watch_cb_thread && stream_h->is_requesting) {
+                       LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
+                       return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
+               }
+               SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
+       }
+
+       if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
+               LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
+                       stream_h->acquired_focus, stream_h->prev_acquired_focus);
+               ret = MM_ERROR_POLICY_INTERNAL;
+               goto LEAVE;
+       }
+
+       if (!stream_h->acquired_focus) {
+               LOGI("PLAYBACK/RECORDING focuses have already been RELEASED");
+               ret = MM_ERROR_NONE;
+               goto LEAVE;
+       }
+
+       stream_h->is_requesting = true;
+
+       ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
        if (ret == MM_ERROR_NONE) {
-               stream_h->acquired_focus &= ~focus_mask;
+               stream_h->acquired_focus = 0;
+               stream_h->prev_acquired_focus = 0;
+               _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
        }
 
-       LOGI("<< leave : ret(%p)", ret);
+LEAVE:
+       stream_h->is_requesting = false;
+       SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+       if (!is_focus_cb_thread)
+               SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
 
-       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)
+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)
 {
        int ret = MM_ERROR_NONE;
        sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
@@ -417,674 +536,582 @@ int sound_manager_get_focus_state (sound_stream_info_h stream_info, sound_stream
 
        SM_INSTANCE_CHECK(stream_h);
        if (!state_for_playback && !state_for_recording)
-               ret = MM_ERROR_INVALID_ARGUMENT;
+               return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
+
+       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
 
        if (state_for_playback)
-               *state_for_playback = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
+               *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
        if (state_for_recording)
-               *state_for_recording = (stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING)?SOUND_STREAM_FOCUS_STATE_ACQUIRED:SOUND_STREAM_FOCUS_STATE_RELEASED;
+               *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
 
-       LOGI("<< leave : acquired_focus(%p)", stream_h->acquired_focus);
+       LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
+
+       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)
+int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
 {
        int ret = MM_ERROR_NONE;
+       sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
+       sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
+       bool is_focus_cb_thread = false;
 
        LOGI(">> enter");
 
-       SM_NULL_ARG_CHECK(callback);
+       SM_INSTANCE_CHECK(src_stream_h);
+       SM_INSTANCE_CHECK(dst_stream_h);
 
-       if (!g_focus_watch_cb_table.user_cb) {
-               ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data);
-               if (ret == MM_ERROR_NONE) {
-                       g_focus_watch_cb_table.user_cb = callback;
-                       g_focus_watch_cb_table.user_data = user_data;
-               }
-       } else {
-               ret = MM_ERROR_SOUND_INTERNAL;
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
+               return _convert_sound_manager_error_code(__func__, ret);
+
+       if (is_focus_cb_thread) {
+               LOGE("not allowed calling this function in focus(watch) callback");
+               return SOUND_MANAGER_ERROR_INVALID_OPERATION;
+       }
+
+       if (src_stream_h->focus_id == dst_stream_h->focus_id) {
+               LOGE("not allowed because both handles have same id(%u)", src_stream_h->focus_id);
+               return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
+       }
+
+       if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
+               LOGE("focus is unavailable for source(%d)/destination(%d)",
+                       src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
+               return SOUND_MANAGER_ERROR_POLICY;
        }
 
-       LOGI("<< leave : ret(%p)", ret);
+       if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
+               LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
+                       focus_mask, src_stream_h->acquired_focus);
+               return SOUND_MANAGER_ERROR_INVALID_STATE;
+       }
+
+       if (dst_stream_h->user_cb == NULL) {
+               LOGE("focus state changed callback should be set to destination handle");
+               return SOUND_MANAGER_ERROR_POLICY;
+       }
+
+       ret = mm_sound_deliver_focus(src_stream_h->focus_id, dst_stream_h->focus_id, (mm_sound_focus_type_e)focus_mask);
+       if (ret == MM_ERROR_NONE) {
+               src_stream_h->acquired_focus &= ~focus_mask;
+               src_stream_h->prev_acquired_focus &= ~focus_mask;
+               dst_stream_h->acquired_focus |= focus_mask;
+               dst_stream_h->prev_acquired_focus |= focus_mask;
+       }
 
-       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)
+int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
 {
        int ret = MM_ERROR_NONE;
+       sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
 
        LOGI(">> enter");
 
-       if (g_focus_watch_cb_table.user_cb) {
-               ret = mm_sound_unset_focus_watch_callback();
-               if (ret == MM_ERROR_NONE) {
-                       g_focus_watch_cb_table.user_cb = NULL;
-                       g_focus_watch_cb_table.user_data = NULL;
-               } else {
-                       ret = MM_ERROR_SOUND_INTERNAL;
-               }
-       } else {
-               ret = MM_ERROR_SOUND_INTERNAL;
-       }
+       SM_NULL_ARG_CHECK(stream_h);
+       SM_NULL_ARG_CHECK(device);
+       SM_NULL_ARG_CHECK(is_on);
 
-       LOGI("<< leave : ret(%p)", ret);
+       ret = mm_sound_is_stream_on_device(stream_h->pa_index, device, is_on);
 
-       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)
+int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
 {
        int ret = MM_ERROR_NONE;
-       int cur_session = -1;
-       int new_session = MM_SESSION_TYPE_MEDIA;
-
-       LOGI(">> enter : type=%d", type);
-
-       if(type < SOUND_SESSION_TYPE_MEDIA || type >  SOUND_SESSION_TYPE_CALL)
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-
-       switch(type) {
-       case SOUND_SESSION_TYPE_MEDIA:
-               new_session = MM_SESSION_TYPE_MEDIA;
-               break;
-       case SOUND_SESSION_TYPE_ALARM:
-               new_session = MM_SESSION_TYPE_ALARM;
-               break;
-       case SOUND_SESSION_TYPE_NOTIFICATION:
-               new_session = MM_SESSION_TYPE_NOTIFY;
-               break;
-       case SOUND_SESSION_TYPE_EMERGENCY:
-               new_session = MM_SESSION_TYPE_EMERGENCY;
-               break;
-       case SOUND_SESSION_TYPE_VOIP:
-               new_session = MM_SESSION_TYPE_VOIP;
-               break;
-       case SOUND_SESSION_TYPE_CALL:
-               new_session = MM_SESSION_TYPE_CALL;
-               break;
-       }
 
-       /* valid session check */
-       ret = mm_session_get_current_type(&cur_session);
-       if(ret == 0) {
-               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);
-                       }
-               }
-               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);
-               }
-       }
+       LOGI(">> enter");
 
-       if(g_session_interrupt_cb_table.is_registered) {
-               if (new_session == cur_session ||
-                       ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
-                       LOGI("<< leave : already set type=%d, ret=%p", type, ret);
-                       return SOUND_MANAGER_ERROR_NONE;
-               } else {
-                       ret = mm_session_finish();
-                       if (ret != MM_ERROR_NONE) {
-                               return __convert_sound_manager_error_code(__func__, ret);
-                       }
-                       g_session_interrupt_cb_table.is_registered = 0;
-                       g_cached_session_mode = -1;
-               }
-       }
-       ret = mm_session_init_ex(new_session , _session_interrupt_cb, NULL);
-       if(ret == 0){
-               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);
+       SM_NULL_ARG_CHECK(device_type);
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       ret = _get_current_media_routing_path("out", device_type);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_get_session_type (sound_session_type_e *type)
+int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
 {
        int ret = MM_ERROR_NONE;
-       int cur_session;
-
-       if( type == NULL )
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-       ret = mm_session_get_current_type(&cur_session);
-       if (ret != 0)
-               cur_session = SOUND_SESSION_TYPE_DEFAULT;
-       if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
-                       (cur_session != MM_SESSION_TYPE_VOIP) &&
-                       (cur_session != MM_SESSION_TYPE_CALL)) {
-               if( g_cached_session != -1 )
-                       cur_session = g_cached_session;
-               else //will be never reach here. just prevent code
-                       cur_session = SOUND_SESSION_TYPE_DEFAULT;
-       }
+       char *stream_type_str = NULL;
+       char *extra_info_str = NULL;
+       int option = 0;
+       bool is_focus_cb_thread = false;
+
+       LOGI(">> enter");
+
+       SM_NULL_ARG_CHECK(acquired_by);
+       SM_NULL_ARG_CHECK(flags);
 
-       switch(cur_session) {
-       case MM_SESSION_TYPE_MEDIA:
-       case MM_SESSION_TYPE_MEDIA_RECORD:
-               *type = SOUND_SESSION_TYPE_MEDIA;
-               break;
-       case MM_SESSION_TYPE_ALARM:
-               *type = SOUND_SESSION_TYPE_ALARM;
-               break;
-       case MM_SESSION_TYPE_NOTIFY:
-               *type = SOUND_SESSION_TYPE_NOTIFICATION;
-               break;
-       case MM_SESSION_TYPE_EMERGENCY:
-               *type = SOUND_SESSION_TYPE_EMERGENCY;
-               break;
-       case MM_SESSION_TYPE_VOIP:
-               *type = SOUND_SESSION_TYPE_VOIP;
-               break;
-       case MM_SESSION_TYPE_CALL:
-               *type = SOUND_SESSION_TYPE_CALL;
-               break;
-       default:
-               *type = cur_session;
-               break;
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
+               return _convert_sound_manager_error_code(__func__, ret);
+
+       if (is_focus_cb_thread) {
+               LOGE("this API should not be called in focus callback");
+               return SOUND_MANAGER_ERROR_INVALID_OPERATION;
        }
 
-       LOGI("returns : type=%d, ret=%p", *type, ret);
+       ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
+       if (ret == MM_ERROR_NONE) {
+               LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
+               ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
+               if (ret == MM_ERROR_NONE) {
+                       LOGI("                                : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
+                       *flags = option;
+                       if (extra_info)
+                               *extra_info = strdup(extra_info_str);
+               }
+               SM_SAFE_FREE(stream_type_str);
+               SM_SAFE_FREE(extra_info_str);
+       }
 
-       return 0;
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_set_media_session_option (sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
+int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_option = 0;
-       int updated = 0;
-
-       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);
-       if(d_option < 0 || d_option >  SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
-               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("need to set session type first");
-               return __convert_sound_manager_error_code(__func__, ret);
-       } else if ( ret == 0 && session > MM_SESSION_TYPE_MEDIA ) {
-               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);
-                       }
-               } else {
-                       return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
-               }
-       }
+       char *stream_type_str = NULL;
+       char *extra_info_str = NULL;
+       int option = 0;
+       bool is_focus_cb_thread = false;
 
-       switch (s_option) {
-       case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
-               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);
-                       }
-                       updated = 1;
-               }
-               break;
-       case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
-               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);
-                       }
-                       updated = 1;
-               }
-               break;
-       }
+       LOGI(">> enter");
 
-       switch (d_option) {
-       case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
-               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);
-                       }
-                       updated = 1;
-               }
-               break;
-       case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
-               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);
-                       }
-                       updated = 1;
-               }
-               break;
+       SM_NULL_ARG_CHECK(acquired_by);
+       SM_NULL_ARG_CHECK(flags);
+
+       if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
+               return _convert_sound_manager_error_code(__func__, ret);
+
+       if (is_focus_cb_thread) {
+               LOGE("this API should not be called in focus callback");
+               return SOUND_MANAGER_ERROR_INVALID_OPERATION;
        }
 
-       if (updated) {
-               LOGI("<< leave : updated");
-       } else {
-               LOGI("<< leave : already set same option(%x), skip it", session_option);
+       ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
+       if (ret == MM_ERROR_NONE) {
+               LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
+               ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
+               if (ret == MM_ERROR_NONE) {
+                       LOGI("                                 : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
+                       *flags = option;
+                       if (extra_info)
+                               *extra_info = strdup(extra_info_str);
+               }
+               SM_SAFE_FREE(stream_type_str);
+               SM_SAFE_FREE(extra_info_str);
        }
 
-       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)
+int sound_manager_add_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_watch_cb callback, void *user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_options = 0;
+       int i = 0;
 
        LOGI(">> enter");
 
-       if( s_option == NULL || d_option == NULL )
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-
-       ret = mm_session_get_current_information(&session, &session_options);
-       if( ret != 0 ) {
-               return __convert_sound_manager_error_code(__func__, ret);
-       } else if (session > SOUND_SESSION_TYPE_MEDIA ) {
-               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);
-                       }
-               } else {
-                       return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
-               }
-       }
-       /* get option */
-       if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS) {
-               *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
-       } else {
-               *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
+       SM_NULL_ARG_CHECK(callback);
+       SM_NULL_ARG_CHECK(id);
+
+       for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
+               if (focus_watch_info_arr[i].id == 0)
+                       break;
+       if (i == SOUND_STREAM_INFO_ARR_MAX) {
+               //LCOV_EXCL_START
+               LOGE("focus watch info array is full");
+               ret = MM_ERROR_SOUND_INTERNAL;
+               goto LEAVE;
+               //LCOV_EXCL_STOP
        }
-       if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
-               *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
-       } else {
-               *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
+
+       ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
+       if (ret == MM_ERROR_NONE) {
+               focus_watch_info_arr[i].id = *id;
+               focus_watch_info_arr[i].user_data = user_data;
+               focus_watch_info_arr[i].user_cb = callback;
        }
 
-       LOGI("<< leave : option for starting=%d, for during play=%d", *s_option, *d_option);
+LEAVE:
+       LOGD("id(%d)", *id);
 
-       return SOUND_MANAGER_ERROR_NONE;
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_set_media_session_resumption_option (sound_session_option_for_resumption_e option)
+int sound_manager_remove_focus_state_watch_cb(int id)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_option = 0;
-       int updated = 0;
-
-       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);
-
-       ret = mm_session_get_current_information(&session, &session_option);
-       if ( ret != 0 || !g_session_interrupt_cb_table.is_registered) {
-               LOGW("need to set session type first");
-               return __convert_sound_manager_error_code(__func__, ret);
-       } else if ( ret == 0 && session > MM_SESSION_TYPE_MEDIA ) {
-               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);
-                       }
-               } else {
-                       return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
-               }
-       }
+       int i = 0;
 
-       switch (option) {
-       case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
-               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);
-                       }
-                       updated = 1;
-               }
-               break;
-       case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
-               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);
-                       }
-                       updated = 1;
-               }
-               break;
+       LOGI(">> enter");
+
+       for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
+               if (focus_watch_info_arr[i].id == id)
+                       break;
+       if (i == SOUND_STREAM_INFO_ARR_MAX) {
+               LOGE("cound not find item in focus watch info array for this id(%d)", id);
+               ret = MM_ERROR_INVALID_ARGUMENT;
+               goto LEAVE;
        }
 
-       if (updated) {
-               LOGI("<< leave : updated");
-       } else {
-               LOGI("<< leave : already set same option(%x), skip it", session_option);
+       ret = mm_sound_unset_focus_watch_callback(id);
+       if (ret == MM_ERROR_NONE) {
+               focus_watch_info_arr[i].id = 0;
+               focus_watch_info_arr[i].user_data = NULL;
+               focus_watch_info_arr[i].user_cb = NULL;
        }
 
-       return __convert_sound_manager_error_code(__func__, ret);
+LEAVE:
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_get_media_session_resumption_option (sound_session_option_for_resumption_e *option)
+int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_options = 0;
 
-       LOGI(">> enter");
+       ret = mm_sound_get_device_list(device_mask, device_list);
 
-       if( option == NULL )
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-       ret = mm_session_get_current_information(&session, &session_options);
-       if( ret != 0 ) {
-               return __convert_sound_manager_error_code(__func__, ret);
-       } else if (session > SOUND_SESSION_TYPE_MEDIA ) {
-               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);
-                       }
-               } else {
-                       return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
-               }
-       }
-       /* get option */
-       if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
-               *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
-       } else {
-               *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
-       }
+       return _convert_sound_manager_error_code(__func__, ret);
+}
 
-       LOGI("<< leave : option for resumption=%d (0:by system, 1:by system or media paused)", *option);
+int sound_manager_free_device_list(sound_device_list_h device_list)
+{
+       int ret = MM_ERROR_NONE;
 
-       return SOUND_MANAGER_ERROR_NONE;
+       ret = mm_sound_free_device_list(device_list);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_set_voip_session_mode (sound_session_voip_mode_e mode)
+int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_options = 0;
 
-       LOGI(">> enter : mode=%d", mode);
+       ret = mm_sound_get_next_device(device_list, device);
 
-       ret = mm_session_get_current_information(&session, &session_options);
-       if( ret != MM_ERROR_NONE ) {
-               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);
-       }
-       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);
-       }
-       ret = __set_session_mode ((_session_mode_e)mode);
+       return _convert_sound_manager_error_code(__func__, ret);
+}
 
-       LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret);
+int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
+{
+       int ret = MM_ERROR_NONE;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       ret = mm_sound_get_prev_device(device_list, device);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_get_voip_session_mode (sound_session_voip_mode_e *mode)
+int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_options = 0;
-       _session_mode_e _mode = 0;
-
-       if(mode == NULL) {
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-       }
+       mm_sound_device_type_e mm_sound_device_type;
 
-       ret = mm_session_get_current_information(&session, &session_options);
-       if( ret != MM_ERROR_NONE ) {
-               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);
-       }
-       ret = __get_session_mode(&_mode);
+       ret = mm_sound_get_device_type(device, &mm_sound_device_type);
        if (ret == MM_ERROR_NONE)
-               *mode = (sound_session_voip_mode_e)_mode;
+               ret = _convert_device_type(mm_sound_device_type, type);
+
+       return _convert_sound_manager_error_code(__func__, ret);
+}
 
-       LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret);
+int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
+{
+       int ret = MM_ERROR_NONE;
+       mm_sound_device_io_direction_e mm_sound_io_direction;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       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);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_set_call_session_mode (sound_session_call_mode_e mode)
+int sound_manager_get_device_id(sound_device_h device, int *id)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_options = 0;
 
-       LOGI(">> enter : mode=%d", mode);
+       ret = mm_sound_get_device_id(device, id);
 
-       ret = mm_session_get_current_information(&session, &session_options);
-       if( ret != MM_ERROR_NONE ) {
-               return __convert_sound_manager_error_code(__func__, ret);
-       } else if (session != MM_SESSION_TYPE_CALL ) {
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
-       }
-       if(mode < SOUND_SESSION_CALL_MODE_RINGTONE || mode > SOUND_SESSION_CALL_MODE_VOICE_WITH_BLUETOOTH) {
-               ret = MM_ERROR_INVALID_ARGUMENT;
-               return __convert_sound_manager_error_code(__func__, ret);
-       }
-       ret = __set_session_mode ((_session_mode_e)mode);
+       return _convert_sound_manager_error_code(__func__, ret);
+}
+
+int sound_manager_get_device_name(sound_device_h device, char **name)
+{
+       int ret = MM_ERROR_NONE;
 
-       LOGI("<< leave : session=%p, mode=%d, ret=%p", session, mode, ret);
+       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_call_session_mode (sound_session_call_mode_e *mode)
+int sound_manager_is_device_running(sound_device_h device, bool *is_running)
 {
        int ret = MM_ERROR_NONE;
-       int session = 0;
-       int session_options = 0;
-       _session_mode_e _mode = 0;
 
-       if(mode == NULL) {
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-       }
+       LOGI(">> enter");
 
-       ret = mm_session_get_current_information(&session, &session_options);
-       if( ret != MM_ERROR_NONE ) {
-               return __convert_sound_manager_error_code(__func__, ret);
-       } else if (session != MM_SESSION_TYPE_CALL ) {
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
-       }
-       ret = __get_session_mode(&_mode);
-       if (ret == MM_ERROR_NONE)
-               *mode = (sound_session_call_mode_e)_mode;
+       SM_INSTANCE_CHECK(device);
+       SM_NULL_ARG_CHECK(is_running);
 
-       LOGI("returns : session=%p, mode=%d, ret=%p", session, *mode, ret);
+       ret = mm_sound_is_device_running(device, is_running);
 
-       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)
+int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
 {
        int ret = MM_ERROR_NONE;
-       if(callback == NULL)
-               return __convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
-
-       if(g_session_interrupt_cb_table.is_registered ==0){
-               ret = mm_session_init_ex(SOUND_SESSION_TYPE_DEFAULT /*default*/ , _session_interrupt_cb, NULL);
-               if(ret != 0)
-                       return __convert_sound_manager_error_code(__func__, ret);
-               g_session_interrupt_cb_table.is_registered = 1;
-       }
 
-       g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
-       g_session_interrupt_cb_table.user_data = user_data;
-       return SOUND_MANAGER_ERROR_NONE;
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
+       ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_unset_session_interrupted_cb (void)
+int sound_manager_get_supported_sample_formats(sound_device_h device, sound_sample_format_e **formats, unsigned int *num_of_elems)
 {
        int ret = MM_ERROR_NONE;
-       if (g_session_interrupt_cb_table.user_cb) {
-               g_session_interrupt_cb_table.user_cb = NULL;
-               g_session_interrupt_cb_table.user_data = NULL;
-       } else {
-               ret = MM_ERROR_SOUND_INTERNAL;
-       }
-       return __convert_sound_manager_error_code(__func__, ret);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+       SM_NULL_ARG_CHECK(formats);
+       SM_NULL_ARG_CHECK(num_of_elems);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
+
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _get_supported_sample_formats(device_id, formats, num_of_elems);
+
+       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)
+int sound_manager_set_sample_format(sound_device_h device, sound_sample_format_e format)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
+
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _set_sample_format(device_id, format);
 
-       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)
+int sound_manager_get_sample_format(sound_device_h device, sound_sample_format_e *format)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_next_device(device_list, device);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+       SM_NULL_ARG_CHECK(format);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _get_sample_format(device_id, format);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_get_prev_device (sound_device_list_h device_list, sound_device_h *device)
+int sound_manager_get_supported_sample_rates(sound_device_h device, sound_sample_rate_e **rates, unsigned int *num_of_elems)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_prev_device(device_list, device);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+       SM_NULL_ARG_CHECK(rates);
+       SM_NULL_ARG_CHECK(num_of_elems);
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
+
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _get_supported_sample_rates(device_id, rates, num_of_elems);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_get_device_type (sound_device_h device, sound_device_type_e *type)
+int sound_manager_set_sample_rate(sound_device_h device, sound_sample_rate_e rate)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)type);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
+
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _set_sample_rate(device_id, rate);
 
-       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)
+int sound_manager_get_sample_rate(sound_device_h device, sound_sample_rate_e *rate)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_device_io_direction(device, (mm_sound_device_io_direction_e*)io_direction);
+       int device_id;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       SM_INSTANCE_CHECK(device);
+       SM_NULL_ARG_CHECK(rate);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
+
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _get_sample_rate(device_id, rate);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_get_device_id (sound_device_h device, int *id)
+int sound_manager_set_avoid_resampling(sound_device_h device, bool enable)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_device_id(device, id);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _set_avoid_resampling(device_id, enable);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_get_device_name (sound_device_h device, char **name)
+int sound_manager_get_avoid_resampling(sound_device_h device, bool *enabled)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_device_name(device, name);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+       SM_NULL_ARG_CHECK(enabled);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
+
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _get_avoid_resampling(device_id, enabled);
 
-       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)
+int sound_manager_set_media_stream_only(sound_device_h device, bool enable)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
+       int device_id;
+
+       SM_INSTANCE_CHECK(device);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _set_media_stream_only(device_id, enable);
+
+       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)
+int sound_manager_get_media_stream_only(sound_device_h device, bool *enabled)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data);
-       if (ret == MM_ERROR_NONE) {
-               g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
-               g_device_connected_cb_table.user_data = user_data;
-       }
+       int device_id;
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       SM_INSTANCE_CHECK(device);
+       SM_NULL_ARG_CHECK(enabled);
+
+       if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
+               return ret;
+
+       if (!(ret = mm_sound_get_device_id(device, &device_id)))
+               ret = _get_media_stream_only(device_id, enabled);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_unset_device_connected_cb (void)
+int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
-       if (g_device_connected_cb_table.user_cb) {
-               ret = mm_sound_remove_device_connected_callback();
-               if (ret == MM_ERROR_NONE) {
-                       g_device_connected_cb_table.user_cb = NULL;
-                       g_device_connected_cb_table.user_data = NULL;
-               }
-       } else {
-               ret = MM_ERROR_SOUND_INTERNAL;
-       }
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       SM_NULL_ARG_CHECK(callback);
+       SM_NULL_ARG_CHECK(id);
+
+       ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, (unsigned int*)id);
+
+       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)
+int sound_manager_remove_device_connection_changed_cb(int id)
 {
        int ret = MM_ERROR_NONE;
-       ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data);
-       if (ret == MM_ERROR_NONE) {
-               g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
-               g_device_info_changed_cb_table.user_data = user_data;
-       }
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       if (id < 0)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+
+       ret = mm_sound_remove_device_connected_callback((unsigned int)id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_unset_device_information_changed_cb (void)
+int sound_manager_add_device_running_changed_cb(int device_mask, sound_device_running_changed_cb callback, void *user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
-       if (g_device_info_changed_cb_table.user_cb) {
-               ret = mm_sound_remove_device_information_changed_callback();
-               if (ret == MM_ERROR_NONE) {
-                       g_device_info_changed_cb_table.user_cb = NULL;
-                       g_device_info_changed_cb_table.user_data = NULL;
-               }
-       } else {
-               ret = MM_ERROR_SOUND_INTERNAL;
-       }
 
-       return __convert_sound_manager_error_code(__func__, ret);
+       SM_NULL_ARG_CHECK(callback);
+       SM_NULL_ARG_CHECK(id);
+
+       ret = mm_sound_add_device_running_changed_callback(device_mask, (mm_sound_device_running_changed_cb)callback, user_data, (unsigned int*)id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-__attribute__ ((destructor))
-void __sound_manager_finalize (void)
+int sound_manager_remove_device_running_changed_cb(int id)
 {
        int ret = MM_ERROR_NONE;
 
-       if(g_session_interrupt_cb_table.is_registered){
-               LOGI("<ENTER>");
-               ret = mm_session_finish();
-               if (ret != MM_ERROR_NONE) {
-                       LOGE("[%s] failed to mm_session_finish(), ret(%p)", __func__, ret);
-               }
-               g_session_interrupt_cb_table.is_registered = 0;
-               LOGI("<LEAVE>");
-       }
+       if (id < 0)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+
+       ret = mm_sound_remove_device_running_changed_callback((unsigned int)id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
+}
+
+int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
+{
+       int ret = MM_ERROR_NONE;
+
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
+       SM_NULL_ARG_CHECK(callback);
+       SM_NULL_ARG_CHECK(id);
+
+       ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
 
-__attribute__ ((constructor))
-void __sound_manager_initialize (void)
+int sound_manager_remove_device_state_changed_cb(int id)
 {
+       int ret = MM_ERROR_NONE;
+
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
+       if (id < 0)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
 
+       ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
 }
+