Fix codes not to destroy internal focus handle among VoIP session modes 44/117544/9
authorSangchul Lee <sc11.lee@samsung.com>
Mon, 6 Mar 2017 10:02:15 +0000 (19:02 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 9 Mar 2017 07:28:57 +0000 (16:28 +0900)
[Version] 0.3.103
[Profile] Common
[Issue Type] Backward compatibility

Change-Id: I444f6b0a3eba3ed9478471b673f6a2f36f026995
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/sound_manager_internal.h
include/sound_manager_private.h
packaging/capi-media-sound-manager.spec
src/sound_manager.c
src/sound_manager_internal.c
src/sound_manager_private.c

index 80b8263..9dfa9d5 100644 (file)
@@ -230,6 +230,7 @@ int sound_manager_get_index_from_stream_information(sound_stream_info_h stream_i
  * @retval #SOUND_MANAGER_ERROR_NONE Success
  * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
  * @retval #SOUND_MANAGER_ERROR_NO_DATA No data
+ * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_set_session_type()
  * @see sound_manager_set_voip_session_mode()
  */
index 0c670c8..33d4e66 100644 (file)
@@ -304,6 +304,10 @@ int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream);
 
 int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream);
 
+int _make_progress_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream);
+
+int _stop_progress_virtual_stream(virtual_sound_stream_info_s *virtual_stream);
+
 #ifdef __cplusplus
 }
 #endif
index 2aea72e..0ad293c 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-media-sound-manager
 Summary:    Sound Manager library
-Version:    0.3.102
+Version:    0.3.103
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 691c7ce..652ca6b 100644 (file)
@@ -31,11 +31,14 @@ _session_mode_e g_cached_session_mode = -1;
 int g_cached_voip_device_id = -1;
 int g_cached_voip_device_id2 = -1;
 extern sound_stream_info_s *g_voip_stream_info;
+extern sound_stream_info_s *g_voip_ringtone_stream_info;
 extern virtual_sound_stream_info_s *g_voip_vstream_h;
+extern virtual_sound_stream_info_s *g_voip_ringtone_vstream_h;
 
 /* These variables will be removed when session features are deprecated. */
 extern int g_stream_info_count;
 extern pthread_mutex_t g_stream_info_count_mutex;
+pthread_mutex_t g_session_mutex;
 pthread_mutex_t g_interrupt_cb_mutex, g_device_info_cb_mutex, g_device_conn_cb_mutex, g_volume_cb_mutex;
 
 int sound_manager_get_max_volume(sound_type_e type, int *max)
@@ -649,13 +652,16 @@ int sound_manager_set_session_type(sound_session_type_e type)
                break;
        }
 
+       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+
        /* valid session check */
        ret = mm_session_get_current_type(&cur_session);
        if (ret == MM_ERROR_NONE) {
                if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
                        if (type > SOUND_SESSION_TYPE_MEDIA) {
                                LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
-                               return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
+                               ret = MM_ERROR_POLICY_INTERNAL;
+                               goto LEAVE;
                        }
                }
        }
@@ -664,28 +670,37 @@ int sound_manager_set_session_type(sound_session_type_e type)
                if (new_session == cur_session ||
                        ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
                        LOGI("already set type=%d, ret=0x%x", type, ret);
-                       return SOUND_MANAGER_ERROR_NONE;
+                       goto LEAVE;
                } else {
                        ret = mm_session_finish();
                        if (ret != MM_ERROR_NONE)
-                               return _convert_sound_manager_error_code(__func__, ret);
+                               goto LEAVE;
 
                        g_session_interrupt_cb_table.is_registered = 0;
                        if (cur_session == MM_SESSION_TYPE_VOIP) {
+                               /* De-initialize regarding VoIP session */
                                g_cached_session_mode = -1;
                                g_cached_voip_device_id = -1;
                                g_cached_voip_device_id2 = -1;
                                if (g_voip_vstream_h) {
-                                       _stop_virtual_stream(g_voip_vstream_h);
-                                       _destroy_virtual_stream(g_voip_vstream_h);
+                                       _stop_progress_virtual_stream(g_voip_vstream_h);
                                        g_voip_vstream_h = NULL;
                                }
-                               /*voip stream destruction*/
+                               if (g_voip_ringtone_vstream_h) {
+                                       _stop_progress_virtual_stream(g_voip_ringtone_vstream_h);
+                                       g_voip_ringtone_vstream_h = NULL;
+                               }
                                if (g_voip_stream_info) {
                                        ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
                                        SM_SAFE_FREE(g_voip_stream_info);
                                        if (ret != MM_ERROR_NONE)
-                                               return _convert_sound_manager_error_code(__func__, ret);
+                                               goto LEAVE;
+                               }
+                               if (g_voip_ringtone_stream_info) {
+                                       ret = _destroy_pa_connection_and_unregister_focus(g_voip_ringtone_stream_info);
+                                       SM_SAFE_FREE(g_voip_ringtone_stream_info);
+                                       if (ret != MM_ERROR_NONE)
+                                               goto LEAVE;
                                }
                        }
                }
@@ -695,6 +710,8 @@ int sound_manager_set_session_type(sound_session_type_e type)
                g_session_interrupt_cb_table.is_registered = 1;
 
        LOGI("type=%d", type);
+LEAVE:
+       SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
 
        return _convert_sound_manager_error_code(__func__, ret);
 }
@@ -708,6 +725,8 @@ int sound_manager_get_session_type(sound_session_type_e *type)
        if (type == NULL)
                return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
 
+       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
+
        ret = mm_session_get_current_type(&cur_session);
        if (ret != MM_ERROR_NONE) {
                LOGW("session hasn't been set, setting default session");
@@ -748,6 +767,8 @@ int sound_manager_get_session_type(sound_session_type_e *type)
 
        LOGI("type=%d", *type);
 
+       SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
+
        return SOUND_MANAGER_ERROR_NONE;
 }
 
@@ -985,6 +1006,8 @@ int sound_manager_set_voip_session_mode(sound_session_voip_mode_e mode)
        LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
        LOGI(">> enter : mode=%d", mode);
 
+       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+
        ret = mm_session_get_current_information(&session, &session_options);
        if (ret != MM_ERROR_NONE)
                goto LEAVE;
@@ -1004,6 +1027,8 @@ int sound_manager_set_voip_session_mode(sound_session_voip_mode_e mode)
        LOGI("session=%d, mode=%d(0:RINGTONE 1:MIC_RCV 2:MIC_SPK 3:EAR 4:BT)", session, mode);
 
 LEAVE:
+       SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
+
        return _convert_sound_manager_error_code(__func__, ret);
 }
 
@@ -1014,6 +1039,9 @@ int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
        int session_options = 0;
 
        LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
+
+       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+
        if (mode == NULL) {
                LOGE("mode is null");
                ret = MM_ERROR_INVALID_ARGUMENT;
@@ -1036,6 +1064,8 @@ int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
        LOGI("session=%d, mode=%d", session, *mode);
 
 LEAVE:
+       SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
+
        return _convert_sound_manager_error_code(__func__, ret);
 }
 
index 3499ac3..c5e26a8 100644 (file)
 /* 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;
+extern pthread_mutex_t g_session_mutex;
 extern sound_stream_info_s *g_voip_stream_info;
+extern sound_stream_info_s *g_voip_ringtone_stream_info;
+extern virtual_sound_stream_info_s *g_voip_vstream_h;
+extern virtual_sound_stream_info_s *g_voip_ringtone_vstream_h;
 
 #ifndef TIZEN_FEATURE_TV_PROD
 int sound_manager_get_max_master_volume(int *max_level)
@@ -174,13 +178,24 @@ int sound_manager_get_internal_voip_stream_information(sound_stream_info_h *stre
 {
        SM_NULL_ARG_CHECK(stream_info);
 
-       if (g_voip_stream_info == NULL) {
-               LOGE("internal voip internal stream_info does not exist");
+       SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
+
+       if (g_voip_vstream_h == NULL && g_voip_ringtone_vstream_h == NULL) {
+               LOGE("voip mode is not set");
+               SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
                return SOUND_MANAGER_ERROR_NO_DATA;
        }
 
-       LOGI("internal VoIP stream_info[%p]", g_voip_stream_info);
-       *stream_info = (sound_stream_info_h)g_voip_stream_info;
+       if (g_voip_ringtone_vstream_h) {
+               LOGI("ringtone mode is activated");
+               *stream_info = (sound_stream_info_h)g_voip_ringtone_stream_info;
+       } else {
+               *stream_info = (sound_stream_info_h)g_voip_stream_info;
+       }
+
+       LOGI("internal VoIP stream_info[%p]", *stream_info);
+
+       SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
 
        return SOUND_MANAGER_ERROR_NONE;
 }
index ca324e8..70d51ba 100644 (file)
@@ -33,6 +33,7 @@
 #define PA_STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS       "UpdateFocusStatus"
 #define VCONF_PATH_PREFIX_VOLUME                                "file/private/sound/volume/"
 #define VCONF_PATH_MAX                                          64
+#define EXT_INFO_VOIP_SESSION                                   "for voip session"
 
 #define CHECK_AND_SET_DEVICE(x_dst_device1, x_dst_device2, x_src_device) \
 do { \
@@ -53,7 +54,9 @@ extern int g_cached_voip_device_id2;
 extern _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
 sound_stream_info_s *sound_stream_info_arr[SOUND_STREAM_INFO_ARR_MAX];
 sound_stream_info_s *g_voip_stream_info = NULL;
+sound_stream_info_s *g_voip_ringtone_stream_info = NULL;
 virtual_sound_stream_info_s *g_voip_vstream_h = NULL;
+virtual_sound_stream_info_s *g_voip_ringtone_vstream_h = NULL;
 int g_stream_info_count = 0;
 pthread_mutex_t g_stream_info_count_mutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -1300,11 +1303,13 @@ void _voip_focus_state_change_callback(sound_stream_info_h stream_info,
        if (!(info->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ||
                !(info->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING)) {
                /* stop virtual stream for rintone-voip or voip */
+               if (g_voip_ringtone_vstream_h) {
+                       _stop_progress_virtual_stream(g_voip_ringtone_vstream_h);
+                       g_voip_ringtone_vstream_h = NULL;
+                       LOGW("internal voip ringtone stream is interrupted by (%d)", reason);
+               }
                if (g_voip_vstream_h) {
-                       /* stop virtual stream handle */
-                       _stop_virtual_stream(g_voip_vstream_h);
-                       /* destroy virtual stream handle */
-                       _destroy_virtual_stream(g_voip_vstream_h);
+                       _stop_progress_virtual_stream(g_voip_vstream_h);
                        g_voip_vstream_h = NULL;
                        LOGW("internal voip stream is interrupted by (%d)", reason);
                }
@@ -1335,45 +1340,41 @@ int _set_session_mode(_session_mode_e mode)
 
        if (mode == _SESSION_MODE_RINGTONE) {
                if (g_voip_vstream_h) {
-                       /* stop vstream and destroy vstream */
-                       _stop_virtual_stream(g_voip_vstream_h);
-                       _destroy_virtual_stream(g_voip_vstream_h);
+                       _stop_progress_virtual_stream(g_voip_vstream_h);
                        g_voip_vstream_h = NULL;
-                       /* destroy stream info */
-                       _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
-                       SM_SAFE_FREE(g_voip_stream_info);
                }
-               if (!g_voip_stream_info) {
-                       g_voip_stream_info = malloc(sizeof(sound_stream_info_s));
-                       if (!g_voip_stream_info) {
+               if (!g_voip_ringtone_stream_info) {
+                       g_voip_ringtone_stream_info = malloc(sizeof(sound_stream_info_s));
+                       if (!g_voip_ringtone_stream_info) {
                                ret = MM_ERROR_OUT_OF_MEMORY;
                                goto ERROR_CASE;
                        }
-                       memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s));
-               }
-               /* create stream info and acquire focus for rintone-voip stream */
-               g_voip_stream_info->stream_type = "ringtone-voip";
-               if ((ret = _make_pa_connection_and_register_focus(g_voip_stream_info, true, _voip_focus_state_change_callback, NULL))) {
-                       SM_SAFE_FREE(g_voip_stream_info);
-                       goto ERROR_CASE;
+                       memset(g_voip_ringtone_stream_info, 0, sizeof(sound_stream_info_s));
+                       g_voip_ringtone_stream_info->stream_type = "ringtone-voip";
+                       if ((ret = _make_pa_connection_and_register_focus(g_voip_ringtone_stream_info, true, _voip_focus_state_change_callback, NULL))) {
+                               SM_SAFE_FREE(g_voip_ringtone_stream_info);
+                               goto ERROR_CASE;
+                       }
                }
 
-               /* acquire focus */
-               if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, "for voip session")))
-                       goto ERROR_CASE;
+               if ((ret = mm_sound_acquire_focus(g_voip_ringtone_stream_info->index, FOCUS_FOR_BOTH, EXT_INFO_VOIP_SESSION))) {
+                       if (ret != MM_ERROR_SOUND_INVALID_STATE)
+                               goto ERROR_CASE;
+                       LOGI("already acquired, skip it");
+                       ret = MM_ERROR_NONE;
+               }
 
-               g_voip_stream_info->acquired_focus |= FOCUS_FOR_BOTH;
-               _update_focus_status(g_voip_stream_info->index, (unsigned int)g_voip_stream_info->acquired_focus);
+               g_voip_ringtone_stream_info->acquired_focus |= FOCUS_FOR_BOTH;
+               _update_focus_status(g_voip_ringtone_stream_info->index, (unsigned int)g_voip_ringtone_stream_info->acquired_focus);
 
-               /* create virtual stream for ringtone-voip */
-               if ((ret = _create_virtual_stream(g_voip_stream_info, &g_voip_vstream_h))) {
-                       ret = MM_ERROR_SOUND_INTERNAL;
-                       goto ERROR_CASE;
+               /* create and start virtual stream for ringtone-voip */
+               if (!g_voip_ringtone_vstream_h) {
+                       if ((ret = _make_progress_virtual_stream(g_voip_ringtone_stream_info, &g_voip_ringtone_vstream_h))) {
+                               ret = MM_ERROR_SOUND_INTERNAL;
+                               goto ERROR_CASE;
+                       }
                }
 
-               if ((ret = _start_virtual_stream(g_voip_vstream_h)))
-                       goto ERROR_CASE;
-
        } else {
        /* _SESSION_MODE_VOICE_WITH_BUILTIN_RECEIVER: Built-in RCV and Built-in MIC
         * _SESSION_MODE_VOICE_WITH_BUILTIN_SPEAKER : Built-in SPK and Built-in MIC
@@ -1437,31 +1438,32 @@ int _set_session_mode(_session_mode_e mode)
                        goto ERROR_CASE_NO_DESTROY;
                }
 
-               if (g_cached_session_mode == _SESSION_MODE_RINGTONE) {
-                       /* stop vstream and destroy vstream */
-                       _stop_virtual_stream(g_voip_vstream_h);
-                       _destroy_virtual_stream(g_voip_vstream_h);
-                       g_voip_vstream_h = NULL;
-                       /* destroy stream info */
-                       _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
-                       SM_SAFE_FREE(g_voip_stream_info);
+               if (g_voip_ringtone_vstream_h) {
+                       _stop_progress_virtual_stream(g_voip_ringtone_vstream_h);
+                       g_voip_ringtone_vstream_h = NULL;
                }
-               /* create stream info and acquire focus for voip stream */
-               if (g_cached_session_mode == -1 || g_cached_session_mode == _SESSION_MODE_RINGTONE) {
+
+               if (!g_voip_stream_info) {
+                       g_voip_stream_info = malloc(sizeof(sound_stream_info_s));
                        if (!g_voip_stream_info) {
-                               g_voip_stream_info = malloc(sizeof(sound_stream_info_s));
-                               if (!g_voip_stream_info) {
-                                       LOGE("failed to malloc for g_voip_stream_info");
-                                       goto ERROR_CASE;
-                               }
-                               memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s));
-                               LOGI("g_voip_stream_info(%p) is newly created", g_voip_stream_info);
+                               LOGE("failed to malloc for g_voip_stream_info");
+                               goto ERROR_CASE;
                        }
+                       memset(g_voip_stream_info, 0, sizeof(sound_stream_info_s));
+                       LOGI("g_voip_stream_info(%p) is newly created", g_voip_stream_info);
                        g_voip_stream_info->stream_type = "voip";
                        if ((ret = _make_pa_connection_and_register_focus(g_voip_stream_info, true, _voip_focus_state_change_callback, NULL))) {
                                SM_SAFE_FREE(g_voip_stream_info);
                                goto ERROR_CASE;
                        }
+
+                       if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, EXT_INFO_VOIP_SESSION))) {
+                               if (ret != MM_ERROR_SOUND_INVALID_STATE)
+                                       goto ERROR_CASE;
+                               LOGI("already acquired, skip it");
+                               ret = MM_ERROR_NONE;
+                       }
+
                        if (proper_device) {
                                if ((ret = _add_device_for_stream_routing(g_voip_stream_info, proper_device)))
                                        goto ERROR_CASE;
@@ -1474,21 +1476,17 @@ int _set_session_mode(_session_mode_e mode)
                        if ((ret = _apply_stream_routing(g_voip_stream_info)))
                                goto ERROR_CASE;
 
-                       /* acquire focus */
-                       if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, "for voip session")))
-                               goto ERROR_CASE;
-
                        g_voip_stream_info->acquired_focus |= FOCUS_FOR_BOTH;
                        _update_focus_status(g_voip_stream_info->index, (unsigned int)g_voip_stream_info->acquired_focus);
 
-                       /* create virtual stream for voip */
-                       if ((ret = _create_virtual_stream(g_voip_stream_info, &g_voip_vstream_h)))
-                               goto ERROR_CASE;
-
-                       if ((ret = _start_virtual_stream(g_voip_vstream_h)))
-                               goto ERROR_CASE;
-
                } else {
+                       if ((ret = mm_sound_acquire_focus(g_voip_stream_info->index, FOCUS_FOR_BOTH, EXT_INFO_VOIP_SESSION))) {
+                               if (ret != MM_ERROR_SOUND_INVALID_STATE)
+                                       goto ERROR_CASE_NO_DESTROY;
+                               LOGI("already acquired, skip it");
+                               ret = MM_ERROR_NONE;
+                       }
+
                        if (prev_device) {
                                if ((ret = _remove_device_for_stream_routing(g_voip_stream_info, prev_device)))
                                        goto ERROR_CASE_NO_DESTROY;
@@ -1508,10 +1506,16 @@ int _set_session_mode(_session_mode_e mode)
                        if ((ret = _apply_stream_routing(g_voip_stream_info)))
                                goto ERROR_CASE_NO_DESTROY;
                }
+
+               if (!g_voip_vstream_h) {
+                       if ((ret = _make_progress_virtual_stream(g_voip_stream_info, &g_voip_vstream_h))) {
+                               ret = MM_ERROR_SOUND_INTERNAL;
+                               goto ERROR_CASE;
+                       }
+               }
        }
        g_cached_session_mode = mode;
-       g_cached_voip_device_id = -1;
-       g_cached_voip_device_id2 = -1;
+
        if (proper_device)
                mm_sound_get_device_id(proper_device, &g_cached_voip_device_id);
        if (proper_device2)
@@ -1522,15 +1526,21 @@ int _set_session_mode(_session_mode_e mode)
        return ret;
 ERROR_CASE:
        if (g_voip_vstream_h) {
-               /* destroy virtual stream handle */
                _destroy_virtual_stream(g_voip_vstream_h);
                g_voip_vstream_h = NULL;
        }
+       if (g_voip_ringtone_vstream_h) {
+               _destroy_virtual_stream(g_voip_ringtone_vstream_h);
+               g_voip_ringtone_vstream_h = NULL;
+       }
        if (g_voip_stream_info) {
-               /* destroy stream info */
                _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
                SM_SAFE_FREE(g_voip_stream_info);
        }
+       if (g_voip_ringtone_stream_info) {
+               _destroy_pa_connection_and_unregister_focus(g_voip_ringtone_stream_info);
+               SM_SAFE_FREE(g_voip_ringtone_stream_info);
+       }
 ERROR_CASE_NO_DESTROY:
        if (device_list)
                mm_sound_free_device_list(device_list);
@@ -2098,3 +2108,32 @@ int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
 
        return ret;
 }
+
+int _make_progress_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream)
+{
+       int ret = MM_ERROR_NONE;
+
+       SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
+       SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
+
+       if ((ret = _create_virtual_stream(stream_info, virtual_stream)))
+               LOGE("failed to _create_virtual_stream(), ret(0x%x)", ret);
+       else if ((ret = _start_virtual_stream(*virtual_stream)))
+               LOGE("failed to _start_virtual_stream(), ret(0x%x)", ret);
+
+       return ret;
+}
+
+int _stop_progress_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
+{
+       int ret = MM_ERROR_NONE;
+
+       SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
+
+       if ((ret = _stop_virtual_stream(virtual_stream)))
+               LOGE("failed to _stop_virtual_stream(), ret(0x%x)", ret);
+       else if ((ret = _destroy_virtual_stream(virtual_stream)))
+               LOGE("failed to _destroy_virtual_stream(), ret(0x%x)", ret);
+
+       return ret;
+}