Change set/unset callback to add/remove callback, and add device state changed callback 46/102546/1 accepted/tizen/common/20161207.184512 accepted/tizen/ivi/20161208.012205 accepted/tizen/mobile/20161208.011810 accepted/tizen/tv/20161208.012010 accepted/tizen/wearable/20161208.012111 submit/tizen/20161207.075356
authorJeongho Mok <jho.mok@samsung.com>
Wed, 30 Nov 2016 10:41:54 +0000 (19:41 +0900)
committerJeongho Mok <jho.mok@samsung.com>
Tue, 6 Dec 2016 05:29:39 +0000 (21:29 -0800)
[Version] 0.3.84
[Profile] Common
[Issue Type] API

Change-Id: Ie34a02ae4012fcf6264fbf6050907bc736cb1e01
(cherry picked from commit 53818999b5fe83130379bc5d45066d9ded93b018)

include/sound_manager.h
packaging/capi-media-sound-manager.spec
src/sound_manager.c
test/sound_manager_test.c

index 9171d40caf92c8cc511522367877a9c70822b56e..c8aecb85717140f6f3f9b7e5725c41e47d0f784f 100644 (file)
@@ -310,6 +310,7 @@ typedef enum {
 } sound_device_mask_e;
 
 /**
+* @deprecated Deprecated since 3.0. Use sound_manager_add_device_state_changed_cb() instead.
 * @brief Enumeration for changed information of sound device.
 * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
 */
@@ -425,6 +426,7 @@ typedef void (*sound_session_interrupted_cb) (sound_session_interrupted_code_e c
  */
 
 /**
+ * @deprecated Deprecated since 3.0. Use sound_device_connection_changed_cb() instead.
  * @brief Called when the state of connection of a sound device was changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in]   sound_device_h The sound_device
@@ -437,6 +439,7 @@ typedef void (*sound_session_interrupted_cb) (sound_session_interrupted_code_e c
 typedef void (*sound_device_connected_cb) (sound_device_h device, bool is_connected, void *user_data);
 
 /**
+ * @deprecated Deprecated since 3.0.
  * @brief Called when the information of a sound device was changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in]   sound_device_h The sound_device
@@ -448,6 +451,30 @@ typedef void (*sound_device_connected_cb) (sound_device_h device, bool is_connec
  */
 typedef void (*sound_device_information_changed_cb) (sound_device_h device, sound_device_changed_info_e changed_info, void *user_data);
 
+/**
+ * @brief Called when the connection state of a sound device was changed.
+ * @since_tizen 3.0
+ * @param[in]   device The sound_device
+ * @param[in]   is_connected   The state of device connection: @c true = connected, @c false = disconnected
+ * @param[in]   user_data      The user data passed from the callback registration function
+ * @pre You should add this callback using sound_manager_add_device_connection_changed_cb().
+ * @see sound_manager_add_device_connection_changed_cb()
+ * @see sound_manager_remove_device_connection_changed_cb()
+ */
+typedef void (*sound_device_connection_changed_cb) (sound_device_h device, bool is_connected, void *user_data);
+
+/**
+ * @brief Called when the state of a sound device was changed.
+ * @since_tizen 3.0
+ * @param[in]   device The sound_device
+ * @param[in]   state  The state of the device
+ * @param[in]   user_data      The user data passed from the callback registration function
+ * @pre You should add this callback using sound_manager_add_device_state_changed_cb().
+ * @see sound_manager_add_device_state_changed_cb()
+ * @see sound_manager_remove_device_state_changed_cb()
+ */
+typedef void (*sound_device_state_changed_cb) (sound_device_h device, sound_device_state_e state, void *user_data);
+
 /**
  * @}
  */
@@ -548,6 +575,7 @@ int sound_manager_get_current_sound_type(sound_type_e *type);
 int sound_manager_unset_current_sound_type(void) TIZEN_DEPRECATED_API;
 
 /**
+ * @deprecated Deprecated since 3.0. Use sound_manager_add_volume_changed_cb() instead.
  * @brief Registers a callback function to be invoked when the volume level is changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in]  callback        Callback function to indicate change in volume
@@ -561,9 +589,10 @@ int sound_manager_unset_current_sound_type(void) TIZEN_DEPRECATED_API;
  * @see sound_manager_unset_volume_changed_cb()
  * @see sound_manager_volume_changed_cb()
  */
-int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data);
+int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data) TIZEN_DEPRECATED_API;
 
 /**
+ * @deprecated Deprecated since 3.0. Use sound_manager_remove_volume_changed_cb() instead.
  * @brief Unregisters the volume change callback.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @return 0 on success, otherwise a negative error value
@@ -571,7 +600,36 @@ int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_set_volume_changed_cb()
  */
-int sound_manager_unset_volume_changed_cb(void);
+int sound_manager_unset_volume_changed_cb(void) TIZEN_DEPRECATED_API;
+
+/**
+ * @brief Adds a callback function to be invoked when the volume level is changed.
+ * @since_tizen 3.0
+ * @param[in]  callback        Callback function to indicate change in volume
+ * @param[in]  user_data       The user data to be passed to the callback function
+ * @param[out] id      The callback 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
+ * @post sound_manager_volume_changed_cb() will be invoked.
+ * @see sound_manager_remove_volume_changed_cb()
+ * @see sound_manager_volume_changed_cb()
+ */
+int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id);
+
+/**
+ * @brief Removes the volume change callback.
+ * @since_tizen 3.0
+ * @param[in]  id      The id of the callback to remove
+ * @return 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_add_volume_changed_cb()
+ */
+int sound_manager_remove_volume_changed_cb(int id);
 
 /**
  * @}
@@ -1362,9 +1420,10 @@ int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *
  * @see sound_manager_unset_device_connected_cb()
  * @see sound_device_connected_cb()
  */
-int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data);
+int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data) TIZEN_DEPRECATED_API;
 
 /**
+ * @deprecated Deprecated since 3.0. Use sound_manager_remove_device_connection_changed_cb() instead.
  * @brief Unregisters the callback function which is called when the state of connection of a sound device was changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @return @c 0 on success,
@@ -1373,9 +1432,43 @@ int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_set_device_connected_cb()
  */
-int sound_manager_unset_device_connected_cb(void);
+int sound_manager_unset_device_connected_cb(void) TIZEN_DEPRECATED_API;
 
 /**
+ * @brief Adds a callback function to be invoked when the connection state of a sound device was changed.
+ * @since_tizen 3.0
+ *
+ * @param[in]  device_mask     Device masks for which changes should be tracked, values of #sound_device_mask_e combined with bitwise 'or'
+ * @param[in]  callback        The device connection state changed callback function
+ * @param[in]  user_data       The user data to be passed to the callback function
+ * @param[out] id      The callback 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
+ * @post  sound_device_connected_cb() will be invoked.
+ * @see sound_manager_remove_device_connection_changed_cb()
+ * @see sound_device_connection_changed_cb()
+ */
+int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id);
+
+/**
+ * @brief Removes a callback function invoked when the connection of a sound device was changed.
+ * @since_tizen 3.0
+ *
+ * @param[in]  id      The id of the callback to remove
+ * @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_add_device_connection_changed_cb()
+ */
+int sound_manager_remove_device_connection_changed_cb(int id);
+
+/**
+ * @deprecated Deprecated since 3.0. Use sound_manager_add_device_state_changed_cb() instead.
  * @brief Registers a callback function to be invoked when the information of a sound device was changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in]  device_mask     The mask value
@@ -1390,9 +1483,10 @@ int sound_manager_unset_device_connected_cb(void);
  * @see sound_manager_unset_device_information_changed_cb()
  * @see sound_device_information_changed_cb()
  */
-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_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data) TIZEN_DEPRECATED_API;
 
 /**
+ * @deprecated Deprecated since 3.0. Use sound_manager_remove_device_state_changed_cb() instead.
  * @brief Unregisters the callback function which is called when the information of a sound device was changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @return @c 0 on success,
@@ -1401,7 +1495,40 @@ int sound_manager_set_device_information_changed_cb(sound_device_mask_e device_m
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
  * @see sound_manager_set_device_information_changed_cb()
  */
-int sound_manager_unset_device_information_changed_cb(void);
+int sound_manager_unset_device_information_changed_cb(void) TIZEN_DEPRECATED_API;
+
+/**
+ * @brief Adds a callback function to be invoked when the state of a sound device was changed.
+ * @since_tizen 3.0
+ *
+ * @param[in]  device_mask     Device masks for which changes should be tracked, values of #sound_device_mask_e combined with bitwise 'or'
+ * @param[in]  callback        The device state changed callback function
+ * @param[in]  user_data       The user data to be passed to the callback function
+ * @param[out] id      The callback 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
+ * @post  sound_device_state_changed_cb() will be invoked.
+ * @see sound_manager_remove_device_state_changed_cb()
+ * @see sound_device_state_connected_cb()
+ */
+int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id);
+
+/**
+ * @brief Removes a callback function invoked when the state of a sound device was changed.
+ * @since_tizen 3.0
+ *
+ * @param[in]  id      The id of the callback to remove
+ * @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_add_device_state_changed_cb()
+ */
+int sound_manager_remove_device_state_changed_cb(int id);
 
 /**
  * @}
index be70f82703dae134c7694df4708bb2eef9a3e2b9..fcae45e9b261e85649c081742685428d818e6c76 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-media-sound-manager
 Summary:    Sound Manager library
-Version:    0.3.83
+Version:    0.3.84
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index ed663f85eb003b956b7304cf2dfd8082cd83b69f..7e73d856e2861ad9fa40eefdd18b1f45e41fdb6b 100644 (file)
@@ -144,6 +144,9 @@ int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback
        int ret = MM_ERROR_NONE;
        unsigned int subs_id = 0;
 
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
+               "Use sound_manager_add_volume_changed_cb() instead.", __func__);
+
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
        ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, &subs_id);
@@ -162,6 +165,9 @@ int sound_manager_unset_volume_changed_cb(void)
 {
        int ret = MM_ERROR_NONE;
 
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
+               "Use sound_manager_remove_volume_changed_cb() instead.", __func__);
+
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
        if (g_volume_changed_cb_table.subs_id > 0) {
@@ -180,6 +186,30 @@ int sound_manager_unset_volume_changed_cb(void)
        return _convert_sound_manager_error_code(__func__, ret);
 }
 
+int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id)
+{
+       int ret = MM_ERROR_NONE;
+
+       if (!callback || !id)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+
+       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_remove_volume_changed_cb(int id)
+{
+       int ret = MM_ERROR_NONE;
+
+       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_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;
@@ -1155,6 +1185,9 @@ int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound
        int ret = MM_ERROR_NONE;
        unsigned int subs_id = 0;
 
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
+               "Use sound_manager_add_device_connection_changed_cb() instead.", __func__);
+
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
        ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, &subs_id);
@@ -1173,6 +1206,9 @@ int sound_manager_unset_device_connected_cb(void)
 {
        int ret = MM_ERROR_NONE;
 
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
+               "Use sound_manager_remove_device_connection_changed_cb() instead.", __func__);
+
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
        if (g_device_connected_cb_table.subs_id == 0) {
@@ -1193,11 +1229,37 @@ LEAVE:
        return _convert_sound_manager_error_code(__func__, ret);
 }
 
+int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connected_cb callback, void *user_data, int *id)
+{
+       int ret = MM_ERROR_NONE;
+
+       if (!callback || !id)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+
+       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_remove_device_connection_changed_cb(int id)
+{
+       int ret = MM_ERROR_NONE;
+
+       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_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
 {
        int ret = MM_ERROR_NONE;
        unsigned int subs_id = 0;
 
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
+               "Use sound_manager_add_device_state_changed_cb() instead.", __func__);
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
        ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data, &subs_id);
@@ -1216,6 +1278,8 @@ int sound_manager_unset_device_information_changed_cb(void)
 {
        int ret = MM_ERROR_NONE;
 
+       LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
+               "Use sound_manager_remove_device_state_changed_cb() instead.", __func__);
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
        if (g_device_info_changed_cb_table.subs_id == 0) {
@@ -1236,6 +1300,30 @@ LEAVE:
        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;
+
+       if (!callback || !id)
+               return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
+
+       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);
+}
+
+int sound_manager_remove_device_state_changed_cb(int id)
+{
+       int ret = MM_ERROR_NONE;
+
+       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);
+}
+
 __attribute__ ((destructor))
 void __sound_manager_finalize(void)
 {
index 8529e50a0aa1b93fe17dae6783cb748a8f2f52e1..501828c268788b6c5ae24ed783b00357aa88b4c7 100644 (file)
@@ -60,8 +60,12 @@ enum {
        CURRENT_STATUS_GET_DEVICE_PREV,
        CURRENT_STATUS_SET_DEVICE_CONNECTED_CB,
        CURRENT_STATUS_UNSET_DEVICE_CONNECTED_CB,
+       CURRENT_STATUS_ADD_DEVICE_CONNECTION_CHANGED_CB,
+       CURRENT_STATUS_REMOVE_DEVICE_CONNECTION_CHANGED_CB,
        CURRENT_STATUS_SET_DEVICE_INFO_CHANGED_CB,
        CURRENT_STATUS_UNSET_DEVICE_INFO_CHANGED_CB,
+       CURRENT_STATUS_ADD_DEVICE_STATE_CHANGED_CB,
+       CURRENT_STATUS_REMOVE_DEVICE_STATE_CHANGED_CB,
        CURRENT_STATUS_CREATE_STREAM_INFO,
        CURRENT_STATUS_ADD_DEVICE_FOR_STREAM_ROUTING,
        CURRENT_STATUS_REMOVE_DEVICE_FOR_STREAM_ROUTING,
@@ -97,6 +101,8 @@ sound_device_list_h g_device_list = NULL;
 sound_device_mask_e g_device_mask = SOUND_DEVICE_ALL_MASK;
 sound_stream_info_h g_stream_info_h = NULL;
 virtual_sound_stream_h g_vstream_h = NULL;
+int g_device_conn_cb_id;
+int g_device_state_cb_id;
 
 static const char *g_device_direction_str[] = {"IN", "OUT", "BOTH"};
 static const char *g_device_state_str[] = {"De-Activated", "Activated"};
@@ -202,10 +208,18 @@ void _interpret_main_menu(char *cmd)
                g_menu_state = CURRENT_STATUS_SET_DEVICE_CONNECTED_CB;
        else if (strncmp(cmd, "ud", 3) == 0)
                g_menu_state = CURRENT_STATUS_UNSET_DEVICE_CONNECTED_CB;
+       else if (strncmp(cmd, "adcc", 4) == 0)
+               g_menu_state = CURRENT_STATUS_ADD_DEVICE_CONNECTION_CHANGED_CB;
+       else if (strncmp(cmd, "rdcc", 3) == 0)
+               g_menu_state = CURRENT_STATUS_REMOVE_DEVICE_CONNECTION_CHANGED_CB;
        else if (strncmp(cmd, "si", 3) == 0)
                g_menu_state = CURRENT_STATUS_SET_DEVICE_INFO_CHANGED_CB;
        else if (strncmp(cmd, "ui", 3) == 0)
                g_menu_state = CURRENT_STATUS_UNSET_DEVICE_INFO_CHANGED_CB;
+       else if (strncmp(cmd, "adsc", 4) == 0)
+               g_menu_state = CURRENT_STATUS_ADD_DEVICE_STATE_CHANGED_CB;
+       else if (strncmp(cmd, "rdsc", 4) == 0)
+               g_menu_state = CURRENT_STATUS_REMOVE_DEVICE_STATE_CHANGED_CB;
        else if (strncmp(cmd, "csi", 3) == 0)
                g_menu_state = CURRENT_STATUS_CREATE_STREAM_INFO;
        else if (strncmp(cmd, "ads", 3) == 0)
@@ -310,6 +324,10 @@ void display_sub_basic()
        g_print("ud. Unset Device Connenected CB\n");
        g_print("si. Set Device Information Changed CB\t");
        g_print("ui. Unset Device Information Changed CB\n");
+       g_print("adcc. Add Device Connenection Changed CB\t\t");
+       g_print("rdcc. Remove Device Connenection Changed CB\n");
+       g_print("adsc. Add Device State Changed CB\t\t");
+       g_print("rdsc. Remove Device State Changed CB\n");
        g_print("-----------------------------------------------------------------------------------------\n");
        g_print("                                    STREAM POLICY MODULE \n");
        g_print("-----------------------------------------------------------------------------------------\n");
@@ -411,6 +429,10 @@ static void displaymenu()
                g_print("*** press enter to set device information changed cb\n");
        else if (g_menu_state == CURRENT_STATUS_UNSET_DEVICE_INFO_CHANGED_CB)
                g_print("*** press enter to unset device information changed cb\n");
+       else if (g_menu_state == CURRENT_STATUS_ADD_DEVICE_STATE_CHANGED_CB)
+               g_print("*** press enter to add device state changed cb\n");
+       else if (g_menu_state == CURRENT_STATUS_REMOVE_DEVICE_STATE_CHANGED_CB)
+               g_print("*** press enter to remove device state changed cb\n");
        else if (g_menu_state == CURRENT_STATUS_CREATE_STREAM_INFO)
                g_print("*** input stream type to create stream information\n(0:media, 1:system, 2:alarm, 3:notification, 4:emergency, 5:ringtone-call, 6:voice-call, 7:voip, 8:media-ext-only, 9:loopback, 10:solo, 11:radio)\n");
        else if (g_menu_state == CURRENT_STATUS_ADD_DEVICE_FOR_STREAM_ROUTING)
@@ -616,6 +638,18 @@ void _set_device_info_changed_cb(sound_device_h device, sound_device_changed_inf
        g_print("    Direc[ %-4s ] State[ %-12s ]\n", direc, state);
 }
 
+void _device_state_changed_cb(sound_device_h device, sound_device_state_e state, void *user_data)
+{
+       int id = -1;
+       char *type, *name;
+       const char *direc, *_state;
+
+       _get_device_props_simple(device, &id, &type, &name, &direc, &_state);
+
+       g_print("[Device #%d %s %s] state changed\n", id, type, name);
+       g_print("    Direc[ %-4s ] State(%d)[ %-12s ]\n", direc, state, _state);
+}
+
 void reset_menu_state(void)
 {
        g_menu_state = CURRENT_STATUS_MAINMENU;
@@ -1046,6 +1080,22 @@ static void interpret(char *cmd)
                reset_menu_state();
                break;
        }
+       case CURRENT_STATUS_ADD_DEVICE_CONNECTION_CHANGED_CB: {
+               if (sound_manager_add_device_connection_changed_cb(g_device_mask, _set_device_connected_cb, NULL, &g_device_conn_cb_id))
+                       g_print("fail to add device connection changed cb\n");
+               else
+                       g_print("success to add device connection changed cb\n");
+               reset_menu_state();
+               break;
+       }
+       case CURRENT_STATUS_REMOVE_DEVICE_CONNECTION_CHANGED_CB: {
+               if (sound_manager_remove_device_connection_changed_cb(g_device_conn_cb_id))
+                       g_print("fail to remove device connection changed cb\n");
+               else
+                       g_print("success to remove device connection changed cb\n");
+               reset_menu_state();
+               break;
+       }
        case CURRENT_STATUS_SET_DEVICE_INFO_CHANGED_CB: {
                if (sound_manager_set_device_information_changed_cb(g_device_mask, _set_device_info_changed_cb, NULL))
                        g_print("fail to set device information changed cb\n");
@@ -1062,6 +1112,22 @@ static void interpret(char *cmd)
                reset_menu_state();
                break;
        }
+       case CURRENT_STATUS_ADD_DEVICE_STATE_CHANGED_CB: {
+               if (sound_manager_add_device_state_changed_cb(g_device_mask, _device_state_changed_cb, NULL, &g_device_state_cb_id))
+                       g_print("fail to add device state changed cb\n");
+               else
+                       g_print("success to add device state changed cb\n");
+               reset_menu_state();
+               break;
+       }
+       case CURRENT_STATUS_REMOVE_DEVICE_STATE_CHANGED_CB: {
+               if (sound_manager_remove_device_state_changed_cb(g_device_state_cb_id))
+                       g_print("fail to remove device state  changed cb\n");
+               else
+                       g_print("success to remove device state changed cb\n");
+               reset_menu_state();
+               break;
+       }
        case CURRENT_STATUS_CREATE_STREAM_INFO: {
                int ret = SOUND_MANAGER_ERROR_NONE;
                int stream_type = 0;