Add new routing API set 69/223569/1 submit/tizen_5.5/20200203.031202
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 31 Jan 2020 01:54:23 +0000 (10:54 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 31 Jan 2020 01:54:23 +0000 (10:54 +0900)
Functions are added as below
 : sound_manager_set_stream_preemptive_device()
 : sound_manager_get_stream_preemptive_device()

This function is to set a device id to streams made by the specific stream type.
Note that it'll affect all the streams belong to the stream type regardless of
process, it should be used carefully.

[Version] 0.6.2
[Issue Type] New feature

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

index 97034eeb11b678cf9455c083f1956bab6f5c51fb..0a0f187e0564b687c2e650ce9cdecc93a982d532 100644 (file)
@@ -482,6 +482,71 @@ int sound_manager_remove_device_id_for_stream_routing(sound_stream_info_h stream
  */
 int sound_manager_set_stream_preferred_device_id(sound_stream_info_h stream_info, sound_device_io_direction_e io_direction, int device_id);
 
+/**
+ * @internal
+ * @brief Definition for the value indicating that the preemptive device for the specific stream type was not set.
+ * @since_tizen 5.5
+ * @see sound_manager_get_stream_preemptive_device()
+ */
+#define SOUND_MANAGER_STREAM_NO_PREEMPTIVE_DEVICE    0
+
+/**
+ * @internal
+ * @brief Sets the preemptive device for the stream routing.
+ * @since_tizen 5.5
+ *
+ * @remarks    This function is to set a device id to streams made by the specific stream type.
+ *     The available stream types for this function are #SOUND_STREAM_TYPE_MEDIA, #SOUND_STREAM_TYPE_SYSTEM,\n
+ *     #SOUND_STREAM_TYPE_VOICE_INFORMATION and #SOUND_STREAM_TYPE_VOICE_RECOGNITION. Otherwise, #SOUND_MANAGER_ERROR_POLICY will be returned.
+ *
+ * @param[in]  stream_type     The type of stream
+ * @param[in]  io_direction    The IO direction of the device
+ * @param[in]  device_id       The preemptive device id (this can be #SOUND_MANAGER_STREAM_NO_PREEMPTIVE_DEVICE to unset)
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SOUND_MANAGER_ERROR_NONE Success
+ * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_POLICY Noncompliance with the sound system policy
+ * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
+ * @pre Get a device by calling sound_manager_get_device_list() and sound_manager_get_next_device().
+ * @pre Get a device id by calling sound_manager_get_device_id().
+ * @post You can get preemptive devices by calling sound_manager_get_stream_preemptive_device().
+ * @post Call sound_manager_free_device_list() to free the devices.
+ * @see sound_manager_get_stream_preemptive_device()
+ * @see sound_manager_get_device_list()
+ * @see sound_manager_get_next_device()
+ * @see sound_manager_get_device_id()
+ * @see sound_manager_free_device_list()
+ */
+int sound_manager_set_stream_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id);
+
+/**
+ * @internal
+ * @brief Gets the preemptive device for the stream routing.
+ * @since_tizen 5.5
+ *
+ * @remarks    This function is to return the preemptive device id per each direction if it has been set.
+ *     If there is no preemptive device for a given direction, the corresponding output value will be set to
+ *     #SOUND_MANAGER_STREAM_NO_PREEMPTIVE_DEVICE.
+ *     You can get a device handle of the id value by using sound_manager_get_device_list(),
+ *     sound_manager_get_next_device() and sound_manager_get_device_id().
+ *
+ * @param[in]  stream_type     The type of stream
+ * @param[out] in_device_id    The preemptive input device id
+ * @param[out] out_device_id   The preemptive output device id
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SOUND_MANAGER_ERROR_NONE Success
+ * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
+ * @see sound_manager_set_stream_preemptive_device()
+ * @see sound_manager_get_device_list()
+ * @see sound_manager_get_next_device()
+ * @see sound_manager_get_device_id()
+ * @see sound_manager_free_device_list()
+ */
+int sound_manager_get_stream_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id);
+
 /**
  * @internal
  * @brief Gets the state of the device by id.
index c11500970fed2072c2f0b9c145a2dd545365abf7..1f4ab7fa6bdd211a7e0357f7f703bd8599916033 100644 (file)
@@ -436,6 +436,71 @@ int sound_manager_remove_device_id_for_stream_routing(sound_stream_info_h stream
  */
 int sound_manager_set_stream_preferred_device_id(sound_stream_info_h stream_info, sound_device_io_direction_e io_direction, int device_id);
 
+/**
+ * @internal
+ * @brief Definition for the value indicating that the preemptive device for the specific stream type was not set.
+ * @since_tizen 5.5
+ * @see sound_manager_get_stream_preemptive_device()
+ */
+#define SOUND_MANAGER_STREAM_NO_PREEMPTIVE_DEVICE    0
+
+/**
+ * @internal
+ * @brief Sets the preemptive device for the stream routing.
+ * @since_tizen 5.5
+ *
+ * @remarks    This function is to set a device id to streams made by the specific stream type.
+ *     The available stream types for this function are #SOUND_STREAM_TYPE_MEDIA, #SOUND_STREAM_TYPE_SYSTEM,\n
+ *     #SOUND_STREAM_TYPE_VOICE_INFORMATION and #SOUND_STREAM_TYPE_VOICE_RECOGNITION. Otherwise, #SOUND_MANAGER_ERROR_POLICY will be returned.
+ *
+ * @param[in]  stream_type     The type of stream
+ * @param[in]  io_direction    The IO direction of the device
+ * @param[in]  device_id       The preemptive device id (this can be #SOUND_MANAGER_STREAM_NO_PREEMPTIVE_DEVICE to unset)
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SOUND_MANAGER_ERROR_NONE Success
+ * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_POLICY Noncompliance with the sound system policy
+ * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
+ * @pre Get a device by calling sound_manager_get_device_list() and sound_manager_get_next_device().
+ * @pre Get a device id by calling sound_manager_get_device_id().
+ * @post You can get preemptive devices by calling sound_manager_get_stream_preemptive_device().
+ * @post Call sound_manager_free_device_list() to free the devices.
+ * @see sound_manager_get_stream_preemptive_device()
+ * @see sound_manager_get_device_list()
+ * @see sound_manager_get_next_device()
+ * @see sound_manager_get_device_id()
+ * @see sound_manager_free_device_list()
+ */
+int sound_manager_set_stream_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id);
+
+/**
+ * @internal
+ * @brief Gets the preemptive device for the stream routing.
+ * @since_tizen 5.5
+ *
+ * @remarks    This function is to return the preemptive device id per each direction if it has been set.
+ *     If there is no preemptive device for a given direction, the corresponding output value will be set to
+ *     #SOUND_MANAGER_STREAM_NO_PREEMPTIVE_DEVICE.
+ *     You can get a device handle of the id value by using sound_manager_get_device_list(),
+ *     sound_manager_get_next_device() and sound_manager_get_device_id().
+ *
+ * @param[in]  stream_type     The type of stream
+ * @param[out] in_device_id    The preemptive input device id
+ * @param[out] out_device_id   The preemptive output device id
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SOUND_MANAGER_ERROR_NONE Success
+ * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
+ * @see sound_manager_set_stream_preemptive_device()
+ * @see sound_manager_get_device_list()
+ * @see sound_manager_get_next_device()
+ * @see sound_manager_get_device_id()
+ * @see sound_manager_free_device_list()
+ */
+int sound_manager_get_stream_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id);
+
 /**
  * @internal
  * @brief Gets the state of the device by id.
index 5a38da54d6da9b1efd8ea28c5f68cf10b81f8da2..f65fdd521746c51e78f5b996958d0499e7fbda74 100644 (file)
@@ -383,6 +383,10 @@ int _set_preferred_device_id(sound_stream_info_s *stream_info, sound_device_io_d
 
 int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id);
 
+int _set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id);
+
+int _get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id);
+
 int _get_latest_stream_pid(int stream_type, unsigned int *pid);
 
 #ifdef __cplusplus
index a74ed5cc58ee51bb6c104f65d48738912d2bfe4a..14daf9429c686f23d1529a5aab37c38c1960a813 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-sound-manager
 Summary:    Sound Manager library
-Version:    0.6.1
+Version:    0.6.2
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index d8c125e2743f94115fc55f4bb03bba3c88560b08..4bb216ddbac334d7389d206700cfe19ef157babc 100644 (file)
@@ -828,5 +828,25 @@ int sound_manager_get_latest_stream_pid(int stream_type, unsigned int *pid)
 
        ret = _get_latest_stream_pid(stream_type, pid);
 
+       return _convert_sound_manager_error_code(__func__, ret);
+}
+
+int sound_manager_set_stream_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e io_direction, int device_id)
+{
+       int ret = MM_ERROR_NONE;
+
+       ret = _set_preemptive_device(stream_type, io_direction, device_id);
+
+       return _convert_sound_manager_error_code(__func__, ret);
+}
+
+int sound_manager_get_stream_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
+{
+       int ret = MM_ERROR_NONE;
+
+       SM_NULL_ARG_CHECK(in_device_id || out_device_id);
+
+       ret = _get_preemptive_device(stream_type, in_device_id, out_device_id);
+
        return _convert_sound_manager_error_code(__func__, ret);
 }
\ No newline at end of file
index 6a0334d168f7ef57c0fd38cad6b92a7a7d6c51dc..3fcb782bf562450cec92d25d3b438b640f61f8f8 100644 (file)
@@ -41,6 +41,8 @@
 #define STREAM_NETWORK_SOURCE_MEDIA      "network-source-media"
 #define STREAM_EXT_MEDIA                 "ext-media"
 
+#define DBUS_METHOD_TIMEOUT                                     2000
+
 #define PA_BUS_NAME                                             "org.pulseaudio.Server"
 
 #define PA_STREAM_MANAGER_OBJECT_PATH                           "/org/pulseaudio/StreamManager"
@@ -50,6 +52,8 @@
 #define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION   "SetStreamRouteOption"
 #define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE   "SetStreamPreferredDevice"
 #define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE   "GetStreamPreferredDevice"
+#define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREEMPTIVE_DEVICE  "SetStreamPreemptiveDevice"
+#define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREEMPTIVE_DEVICE  "GetStreamPreemptiveDevice"
 #define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL      "GetVolumeMaxLevel"
 #define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL          "GetVolumeLevel"
 #define PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL          "SetVolumeLevel"
@@ -3188,6 +3192,140 @@ LEAVE:
        return ret;
 }
 
+static int __invoke_ipc_set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e io_direction, int device_id)
+{
+       int ret = MM_ERROR_NONE;
+       GVariant *result = NULL;
+       GDBusConnection *conn = NULL;
+       GError *err = NULL;
+       const gchar *dbus_ret = NULL;
+       const gchar *direction_str;
+       char *stream_type_str;
+       int i;
+
+       if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != MM_ERROR_NONE)
+               return ret;
+
+       if ((ret = __get_dbus_connection(&conn)))
+               return ret;
+
+       for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
+               if (io_direction != SOUND_DEVICE_IO_DIRECTION_BOTH && io_direction != i)
+                       continue;
+               direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
+
+               result = g_dbus_connection_call_sync(conn,
+                       PA_BUS_NAME,
+                       PA_STREAM_MANAGER_OBJECT_PATH,
+                       PA_STREAM_MANAGER_INTERFACE,
+                       PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREEMPTIVE_DEVICE,
+                       g_variant_new("(ssu)", stream_type_str, direction_str, (unsigned int)device_id),
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       DBUS_METHOD_TIMEOUT,
+                       NULL,
+                       &err);
+               if (!result || err) {
+                       LOGE("g_dbus_connection_call_sync() for SET_STREAM_PREEMPTIVE_DEVICE, direction(%s) error (%s)",
+                                       direction_str, err ? err->message : NULL);
+                       ret = _convert_dbus_error(err ? err->message : NULL);
+                       if (err)
+                               g_error_free(err);
+                       if (result)
+                               g_variant_unref(result);
+                       continue;
+               }
+
+               LOGI("Preemptive device(id:%d, direction:%s) is set", device_id, direction_str);
+
+               g_variant_get(result, "(&s)", &dbus_ret);
+               LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
+               if (!strncmp("STREAM_MANAGER_RETURN_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret)))
+                       ret = MM_ERROR_INVALID_ARGUMENT;
+               else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
+                       ret = MM_ERROR_POLICY_INTERNAL;
+               else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
+                       ret = MM_ERROR_SOUND_INTERNAL;
+
+               g_variant_unref(result);
+               if (ret)
+                       goto LEAVE;
+       }
+
+LEAVE:
+       g_object_unref(conn);
+       return ret;
+}
+
+static int __invoke_ipc_get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
+{
+       int ret = MM_ERROR_NONE;
+       GDBusConnection *conn = NULL;
+       GError *err = NULL;
+       GVariant *result = NULL;
+       const gchar *dbus_ret = NULL;
+       unsigned int _in_device_id;
+       unsigned int _out_device_id;
+       char *stream_type_str;
+
+       if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != MM_ERROR_NONE)
+               return ret;
+
+       if ((ret = __get_dbus_connection(&conn)))
+               return ret;
+
+       result = g_dbus_connection_call_sync(conn,
+               PA_BUS_NAME,
+               PA_STREAM_MANAGER_OBJECT_PATH,
+               PA_STREAM_MANAGER_INTERFACE,
+               PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREEMPTIVE_DEVICE,
+               g_variant_new("(s)", stream_type_str),
+               G_VARIANT_TYPE("(uus)"),
+               G_DBUS_CALL_FLAGS_NONE,
+               DBUS_METHOD_TIMEOUT,
+               NULL,
+               &err);
+       if (!result || err) {
+               LOGE("g_dbus_connection_call_sync() for GET_STREAM_PREEMPTIVE_DEVICE error");
+               ret = _convert_dbus_error(err ? err->message : NULL);
+               if (err)
+                       g_error_free(err);
+               goto LEAVE;
+       }
+       g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
+
+       LOGI("dbus return value is (%s)", dbus_ret);
+
+       if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
+               if (in_device_id) {
+                       *in_device_id = _in_device_id;
+                       LOGI("preemptive device id[in:%d]", *in_device_id);
+               }
+               if (out_device_id) {
+                       *out_device_id = _out_device_id;
+                       LOGI("preemptive device id[out:%d]", *out_device_id);
+               }
+       } else {
+               ret = MM_ERROR_SOUND_INTERNAL;
+       }
+
+LEAVE:
+       g_variant_unref(result);
+       g_object_unref(conn);
+
+       return ret;
+}
+
+int _set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id)
+{
+       return __invoke_ipc_set_preemptive_device(stream_type, direction, device_id);
+}
+
+int _get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
+{
+       return __invoke_ipc_get_preemptive_device(stream_type, in_device_id, out_device_id);
+}
+
 int _get_latest_stream_pid(int stream_type, unsigned int *pid)
 {
        int ret = MM_ERROR_NONE;
index 44bf196d9294fef221e81edb6c5956437cb52151..ea8d51b502285ac60e9085bc43e83c3a16371320 100644 (file)
@@ -76,6 +76,8 @@ enum {
        CURRENT_STATUS_SET_STREAM_PREFERRED_DEVICE,
        CURRENT_STATUS_SET_STREAM_PREFERRED_DEVICE_ID,
        CURRENT_STATUS_GET_STREAM_PREFERRED_DEVICE,
+       CURRENT_STATUS_SET_STREAM_PREEMPTIVE_DEVICE,
+       CURRENT_STATUS_GET_STREAM_PREEMPTIVE_DEVICE,
        CURRENT_STATUS_SET_STREAM_ROUTING_OPTION,
        CURRENT_STATUS_ACQUIRE_FOCUS,
        CURRENT_STATUS_RELEASE_FOCUS,
@@ -307,6 +309,10 @@ void _interpret_main_menu(char *cmd)
                g_menu_state = CURRENT_STATUS_SET_STREAM_PREFERRED_DEVICE_ID;
        else if (strncmp(cmd, "gpd", MAX_CMD_LEN) == 0)
                g_menu_state = CURRENT_STATUS_GET_STREAM_PREFERRED_DEVICE;
+       else if (strncmp(cmd, "spt", MAX_CMD_LEN) == 0)
+               g_menu_state = CURRENT_STATUS_SET_STREAM_PREEMPTIVE_DEVICE;
+       else if (strncmp(cmd, "gpt", MAX_CMD_LEN) == 0)
+               g_menu_state = CURRENT_STATUS_GET_STREAM_PREEMPTIVE_DEVICE;
        else if (strncmp(cmd, "afc", MAX_CMD_LEN) == 0)
                g_menu_state = CURRENT_STATUS_ACQUIRE_FOCUS;
        else if (strncmp(cmd, "rfc", MAX_CMD_LEN) == 0)
@@ -458,6 +464,8 @@ void display_sub_basic()
        g_print("spd. Set preferred device\t");
        g_print("spi. *Set preferred device id\t");
        g_print("gpd. Get preferred device\n");
+       g_print("spt. *Set preemptive device\t");
+       g_print("gpt. *Get preemptive device\n");
        g_print("afc. Acquire Focus\t");
        g_print("rfc. Release Focus\t");
        g_print("gfs. Get Focus State\n");
@@ -597,6 +605,14 @@ static void displaymenu()
                flag = 1;
        } else if (g_menu_state == CURRENT_STATUS_GET_STREAM_PREFERRED_DEVICE)
                g_print("*** press enter to get preferred device\n");
+       else if (g_menu_state == CURRENT_STATUS_SET_STREAM_PREEMPTIVE_DEVICE) {
+               if (flag == 0)
+                       g_print("*** input stream type(0:media 1:system, 2:voice-information, 3:voice-recognition)\n");
+               else if (flag == 1)
+                       g_print("*** input preemptive device id(0:unset, 1 ~: device_id) and direction(0:out, 1:in, 2:both)\n");
+               flag++;
+       } else if (g_menu_state == CURRENT_STATUS_GET_STREAM_PREEMPTIVE_DEVICE)
+               g_print("*** input stream type to get preemptive device (0:media 1:system: 2:voice-information, 3:voice-recognition)\n");
        else if (g_menu_state == CURRENT_STATUS_SET_STREAM_ROUTING_OPTION)
                g_print("*** input option(name/value) for routing (0:option_1/0, 1:option_1/1, 2:option_2/0, 3:option_2:1)\n");
        else if (g_menu_state == CURRENT_STATUS_ACQUIRE_FOCUS)
@@ -1935,6 +1951,134 @@ static void interpret(char *cmd)
                reset_menu_state();
                break;
        }
+       case CURRENT_STATUS_SET_STREAM_PREEMPTIVE_DEVICE: {
+               int ret = SOUND_MANAGER_ERROR_NONE;
+               static int cnt = 0;
+               static int device_id = 0;
+               static sound_stream_type_e      stream_type;
+               sound_device_io_direction_e direction;
+
+               if (cnt == 0) {
+                       switch (atoi(cmd)) {
+                       case 0:
+                               stream_type = SOUND_STREAM_TYPE_MEDIA;
+                               break;
+                       case 1:
+                               stream_type = SOUND_STREAM_TYPE_SYSTEM;
+                               break;
+                       case 2:
+                               stream_type = SOUND_STREAM_TYPE_VOICE_INFORMATION;
+                               break;
+                       case 3:
+                               stream_type = SOUND_STREAM_TYPE_VOICE_RECOGNITION;
+                               break;
+                       default:
+                               g_print("invalid argument, try again..\n");
+                               reset_menu_state();
+                               cnt = 0;
+                               goto end;
+                       }
+                       cnt++;
+               } else if (cnt == 1) {
+                       device_id = atoi(cmd);
+                       cnt++;
+               } else if (cnt == 2) {
+                       switch (atoi(cmd)) {
+                       case 0:
+                               direction = SOUND_DEVICE_IO_DIRECTION_OUT;
+                               break;
+                       case 1:
+                               direction = SOUND_DEVICE_IO_DIRECTION_IN;
+                               break;
+                       case 2:
+                               direction = SOUND_DEVICE_IO_DIRECTION_BOTH;
+                               break;
+                       default:
+                               g_print("invalid argument, try again..\n");
+                               reset_menu_state();
+                               cnt = 0;
+                               goto end;
+                       }
+                       cnt = 0;
+
+                       ret = sound_manager_set_stream_preemptive_device(stream_type, direction, device_id);
+                       if (ret)
+                               g_print("failed to sound_manager_set_stream_preemptive_device(), ret(0x%x)\n", ret);
+
+                       reset_menu_state();
+               }
+               break;
+       }
+       case CURRENT_STATUS_GET_STREAM_PREEMPTIVE_DEVICE: {
+               int ret = SOUND_MANAGER_ERROR_NONE;
+               int in_device_id = 0;
+               int out_device_id = 0;
+               sound_stream_type_e     stream_type;
+               sound_device_list_h device_list;
+               sound_device_h device;
+               sound_device_type_e device_type;
+               int id;
+
+               switch (atoi(cmd)) {
+               case 0:
+                       stream_type = SOUND_STREAM_TYPE_MEDIA;
+                       break;
+               case 1:
+                       stream_type = SOUND_STREAM_TYPE_SYSTEM;
+                       break;
+               case 2:
+                       stream_type = SOUND_STREAM_TYPE_VOICE_INFORMATION;
+                       break;
+               case 3:
+                       stream_type = SOUND_STREAM_TYPE_VOICE_RECOGNITION;
+                       break;
+               default:
+                       g_print("invalid argument, try again..\n");
+                       reset_menu_state();
+                       goto end;
+               }
+
+               ret = sound_manager_get_stream_preemptive_device(stream_type, &in_device_id, &out_device_id);
+               if (ret) {
+                       g_print("failed to sound_manager_get_stream_preemptive_device(), ret(0x%x)\n", ret);
+                       reset_menu_state();
+                       break;
+               }
+
+               if (in_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE)
+                       g_print("preemptive [ IN] device was not set\n");
+               if (out_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE)
+                       g_print("preemptive [OUT] device was not set\n");
+               if ((in_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE)  &&
+                       (out_device_id == SOUND_MANAGER_STREAM_NO_PREFERRED_DEVICE)) {
+                       reset_menu_state();
+                       break;
+               }
+
+               ret = sound_manager_get_device_list(SOUND_DEVICE_ALL_MASK, &device_list);
+               if (ret) {
+                       g_print("failed to get device list(), ret(0x%x)\n", ret);
+               } else {
+                       while (!sound_manager_get_next_device(device_list, &device)) {
+                               if (!sound_manager_get_device_id(device, &id)) {
+                                       if (in_device_id && id == in_device_id) {
+                                               if (sound_manager_get_device_type(device, &device_type) == SOUND_MANAGER_ERROR_NONE)
+                                                       g_print("preemptive [ IN] device type[%s], id[%d]\n", g_device_type_str[device_type], in_device_id);
+                                       }
+                                       if (out_device_id && id == out_device_id) {
+                                               if (sound_manager_get_device_type(device, &device_type) == SOUND_MANAGER_ERROR_NONE)
+                                                       g_print("preemptive [OUT] device type[%s], id[%d]\n", g_device_type_str[device_type], out_device_id);
+                                       }
+                               }
+                       }
+
+                       ret = sound_manager_free_device_list(device_list);
+                       if (ret)
+                               g_print("failed to sound_manager_free_device_list, ret(0x%x)\n", ret);
+               }
+               reset_menu_state();
+               break;
+       }
        case CURRENT_STATUS_ACQUIRE_FOCUS: {
                int ret = SOUND_MANAGER_ERROR_NONE;
                int focus_type = 0;