Add sound_manager_add[remove]_focus_state_watch_cb() 49/83249/7
authorSangchul Lee <sc11.lee@samsung.com>
Tue, 9 Aug 2016 23:39:30 +0000 (08:39 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 18 Aug 2016 04:35:54 +0000 (13:35 +0900)
- sound_manager_set[unset]_focus_state_watch_cb() has been revised as well as the callback prototype to pass the callback id.
- some API descriptions are revised.

[Version] Release 0.3.58
[Profile] Common
[Issue Type] Feature Enhancement

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

index 04004d3..9add44e 100644 (file)
  *        <td> This callback is called when the state of focus that belongs to the stream_info is changed.</td>
  *     </tr>
  *     <tr>
- *        <td> sound_manager_set_focus_state_watch_cb()</td>
- *        <td> sound_manager_unset_foucs_state_watch_cb()</td>
+ *        <td> sound_manager_add_focus_state_watch_cb()</td>
+ *        <td> sound_manager_remove_foucs_state_watch_cb()</td>
  *        <td> sound_stream_focus_state_watch_cb()</td>
- *        <td> This callback is called when the focus state for each sound stream type is changed.</td>
+ *        <td> This callback is called when the focus state for each sound stream type is changed regardless of the process.</td>
  *     </tr>
  *     <tr>
  *        <td> sound_manager_set_session_interrupted_cb()</td>
index fbfe161..08a3e44 100644 (file)
@@ -353,20 +353,21 @@ typedef void (*sound_stream_focus_state_changed_cb) (sound_stream_info_h stream_
 /**
  * @brief Called when the focus state for each sound stream type is changed regardless of the process.
  * @since_tizen 3.0
+ *
+ * @remarks    This function is invoked by the internal thread of the sound manager.\n
+ *     Therefore it is recommended not to call functions which update the UI from this callback.
+ *
+ * @param[in]   id             The focus state change watch cb id
  * @param[in]   focus_mask     The changed focus mask
  * @param[in]   focus_state    The changed focus state
  * @param[in]   reason         The reason for state change of the focus
  * @param[in]   extra_info     The extra information
  * @param[in]   user_data      The user data passed from the callback registration function
- *
- * @remarks    This function is issued in the internal thread of the sound manager.\n
- *     Therefore it is recommended not to call UI update function in this function.
- *
- * @pre You should register this callback using sound_manager_set_focus_state_watch_cb().
- * @see sound_manager_set_focus_state_watch_cb()
- * @see sound_manager_unset_focus_state_watch_cb()
+ * @pre You should register this callback using sound_manager_add_focus_state_watch_cb().
+ * @see sound_manager_add_focus_state_watch_cb()
+ * @see sound_manager_remove_focus_state_watch_cb()
  */
-typedef void (*sound_stream_focus_state_watch_cb) (sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason, const char *extra_info, void *user_data);
+typedef void (*sound_stream_focus_state_watch_cb) (int id, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason, const char *extra_info, void *user_data);
 
 /**
  * @}
@@ -806,40 +807,42 @@ int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *
 /**
  * @brief Registers the watch callback function to be invoked when the focus state for each sound stream type is changed regardless of the process.
  * @since_tizen 3.0
- * @param[in]  focus_mask              The focus mask that user wants to watch
- * @param[in]  callback        The focus state change watch callback function
- * @param[in]  user_data       The user data to be passed to the callback function
  *
- * @remarks    The previous watch callback should be unset before setting new watch callback.\n
- *     The registered callback is issued in the internal thread of the sound manager.\n
- *     Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ * @remarks    The registered callback is invoked by the internal thread of the sound manager.\n
+ *     Do not call this API within sound_stream_focus_state_changed_cb() or sound_stream_focus_state_watch_cb(),\n
  *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.
  *
+ * @param[in]  focus_mask      The focus mask that user wants to watch
+ * @param[in]  callback        The focus state change watch callback function
+ * @param[in]  user_data       The user data to be passed to the callback function
+ * @param[out] id              The focus state change watch 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_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
- * @see sound_manager_unset_focus_state_watch_cb()
+ * @see sound_manager_remove_focus_state_watch_cb()
  */
-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_add_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_watch_cb callback, void *user_data, int *id);
 
 /**
- * @brief Unregisters the focus state watch callback.
+ * @brief Unregisters the focus state change watch callback.
  * @since_tizen 3.0
  *
- * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() and sound_stream_focus_state_watch_cb(),\n
+ * @remarks    Do not call this API within sound_stream_focus_state_changed_cb() or sound_stream_focus_state_watch_cb(),\n
  *     otherwise SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned.
  *
+ * @param[in]  id              The focus state change watch 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_INVALID_OPERATION Invalid operation
  * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system
- * @see sound_manager_set_focus_state_watch_cb()
+ * @see sound_manager_add_focus_state_watch_cb()
  */
-int sound_manager_unset_focus_state_watch_cb(void);
+int sound_manager_remove_focus_state_watch_cb(int id);
 
 /**
  * @}
index d2a5dad..2ad55fc 100644 (file)
@@ -106,7 +106,7 @@ if (pthread_mutex_unlock(x_mutex)) { \
                g_stream_info_count++; \
 } \
 
-#define SM_UNREF_FOR_STREAM_INFO(x_count, x_return) \
+#define SM_UNREF_FOR_STREAM_INFO(x_count) \
 { \
        x_count--; \
 } \
@@ -195,16 +195,16 @@ typedef struct {
 } _session_interrupt_info_s;
 
 typedef struct {
-       unsigned int subs_id;
+       int id;
        void *user_data;
-       sound_manager_volume_changed_cb user_cb;
-} _volume_changed_info_s;
+       sound_stream_focus_state_watch_cb user_cb;
+} _focus_watch_info_s;
 
 typedef struct {
-       int index;
+       unsigned int subs_id;
        void *user_data;
-       sound_stream_focus_state_watch_cb user_cb;
-} _focus_watch_info_s;
+       sound_manager_volume_changed_cb user_cb;
+} _volume_changed_info_s;
 
 typedef struct {
        unsigned int subs_id;
index db77601..5bd8ba4 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-media-sound-manager
 Summary:    Sound Manager library
-Version:    0.3.57
+Version:    0.3.58
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index bc98ddc..7b2156a 100644 (file)
@@ -20,9 +20,9 @@
 
 _session_interrupt_info_s g_session_interrupt_cb_table = {0, 0, NULL, NULL};
 _volume_changed_info_s g_volume_changed_cb_table = {0, NULL, NULL};
-_focus_watch_info_s g_focus_watch_cb_table = {-1, NULL, NULL};
 _device_connected_info_s g_device_connected_cb_table = {0, NULL, NULL};
 _device_changed_info_s g_device_info_changed_cb_table = {0, 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;
@@ -230,7 +230,7 @@ int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
        if (ret == MM_ERROR_NONE) {
                free(stream_h);
                stream_h = NULL;
-               SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret);
+               SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
        }
        SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
 
@@ -389,61 +389,68 @@ LEAVE:
        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_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 id = -1;
+       int i = 0;
 
        LOGI(">> enter");
 
        SM_NULL_ARG_CHECK(callback);
+       SM_NULL_ARG_CHECK(id);
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
-       if (g_focus_watch_cb_table.user_cb) {
+       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) {
+               LOGE("focus watch info array is full");
                ret = MM_ERROR_SOUND_INTERNAL;
                goto LEAVE;
        }
 
-       SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
-       ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, &id);
+       ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, id);
        if (ret == MM_ERROR_NONE) {
-               g_focus_watch_cb_table.index = id;
-               g_focus_watch_cb_table.user_cb = callback;
-               g_focus_watch_cb_table.user_data = user_data;
+               SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
+               focus_watch_info_arr[i].id = *id;
+               focus_watch_info_arr[i].user_data = user_data;
+               focus_watch_info_arr[i].user_cb = callback;
        }
 
 LEAVE:
        SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
 
-       LOGD("cnt(%d)", g_stream_info_count);
+       LOGD("cnt(%d), id(%d)", g_stream_info_count, *id);
 
        return _convert_sound_manager_error_code(__func__, ret);
 }
 
-int sound_manager_unset_focus_state_watch_cb(void)
+int sound_manager_remove_focus_state_watch_cb(int id)
 {
        int ret = MM_ERROR_NONE;
+       int i = 0;
 
        LOGI(">> enter");
 
        SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
 
-       if (!g_focus_watch_cb_table.user_cb) {
+       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_SOUND_INTERNAL;
                goto LEAVE;
        }
 
-       ret = mm_sound_unset_focus_watch_callback(g_focus_watch_cb_table.index);
-       if (ret != MM_ERROR_NONE) {
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto LEAVE;
+       ret = mm_sound_unset_focus_watch_callback(id);
+       if (ret == MM_ERROR_NONE) {
+               SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
+               focus_watch_info_arr[i].id = 0;
+               focus_watch_info_arr[i].user_data = NULL;
+               focus_watch_info_arr[i].user_cb = NULL;
        }
 
-       g_focus_watch_cb_table.index = -1;
-       g_focus_watch_cb_table.user_cb = NULL;
-       g_focus_watch_cb_table.user_data = NULL;
-       SM_UNREF_FOR_STREAM_INFO(g_stream_info_count, ret);
-
 LEAVE:
        SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
 
index d16eabb..b64253c 100644 (file)
@@ -36,7 +36,7 @@
 extern _session_interrupt_info_s g_session_interrupt_cb_table;
 extern _session_mode_e g_cached_session_mode;
 extern int g_cached_voip_device_id;
-extern _focus_watch_info_s g_focus_watch_cb_table;
+extern _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;
 virtual_sound_stream_info_s *g_voip_vstream_h = NULL;
@@ -490,15 +490,28 @@ LEAVE:
 void _focus_watch_callback(int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason, const char *extra_info, void *user_data)
 {
        int ret = MM_ERROR_NONE;
+       int i = 0;
        sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
 
        ret = _convert_stream_type_to_change_reason(reason, &change_reason);
-       if (ret)
+       if (ret) {
                LOGE("failed to _convert_stream_type_to_enum(), reason(%s), err(0x%08x)", reason, ret);
+               goto LEAVE;
+       }
 
-       if (g_focus_watch_cb_table.user_cb)
-               g_focus_watch_cb_table.user_cb(focus_type, state, change_reason, extra_info, g_focus_watch_cb_table.user_data);
+       for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++) {
+               if ((focus_watch_info_arr[i].id > 0) && (focus_watch_info_arr[i].id == index)) {
+                       LOGI("[FOCUS WATCH USER CALLBACK(%p, id:%d) START]", focus_watch_info_arr[i].user_cb, index);
+                       focus_watch_info_arr[i].user_cb(index, focus_type, state, change_reason, extra_info, focus_watch_info_arr[i].user_data);
+                       LOGI("[FOCUS WATCH USER CALLBACK(%p) END]", focus_watch_info_arr[i].user_cb);
+                       break;
+               }
+       }
+       if (i == SOUND_STREAM_INFO_ARR_MAX)
+               LOGE("could not find index(%d), failed to call user callback", index);
 
+LEAVE:
+       LOGI("<< leave");
        return;
 }
 
@@ -1369,6 +1382,16 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_
        if (is_focus_cb_thread)
                return MM_ERROR_SOUND_INVALID_OPERATION;
 
+       if (!stream_h->is_focus_unavailable) {
+               for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
+                       if (sound_stream_info_arr[i] == NULL)
+                               break;
+               if (i == SOUND_STREAM_INFO_ARR_MAX) {
+                       LOGE("client sound stream info array is full");
+                       goto PA_ERROR;
+               }
+       }
+
        /* get configuration information of this stream type */
        if ((ret = _get_stream_conf_info(stream_h->stream_type, &stream_h->stream_conf_info)))
                return ret;
@@ -1416,20 +1439,9 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_
        if (!stream_h->is_focus_unavailable) {
                ret = mm_sound_register_focus(stream_h->index, stream_h->stream_type, _focus_state_change_callback, user_data);
                if (ret == MM_ERROR_NONE) {
-                       int i = 0;
                        stream_h->user_cb = callback;
                        stream_h->user_data = user_data;
-                       for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++) {
-                               if (sound_stream_info_arr[i] == NULL) {
-                                       sound_stream_info_arr[i] = stream_h;
-                                       break;
-                               }
-                       }
-                       if (i == SOUND_STREAM_INFO_ARR_MAX) {
-                               LOGE("client sound stream info array is full");
-                               ret = mm_sound_unregister_focus(stream_h->index);
-                               goto PA_ERROR;
-                       }
+                       sound_stream_info_arr[i] = stream_h;
                } else {
                        LOGE("failed to register focus, ret(0x%x)", ret);
                        /* disconnect */
@@ -1437,8 +1449,10 @@ int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_
                }
        }
        goto SUCCESS;
+
 PA_ERROR_WITH_UNLOCK:
        pa_threaded_mainloop_unlock(stream_h->pa_mainloop);
+
 PA_ERROR:
        for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
                if (stream_h->stream_conf_info.avail_in_devices[i])
index 1baf3bf..90f21dc 100644 (file)
@@ -68,8 +68,8 @@ enum {
        CURRENT_STATUS_GET_ACQUIRED_FOCUS,
        CURRENT_STATUS_GET_SOUND_TYPE,
        CURRENT_STATUS_DESTROY_STREAM_INFO,
-       CURRENT_STATUS_SET_FOCUS_WATCH_CB,
-       CURRENT_STATUS_UNSET_FOCUS_WATCH_CB,
+       CURRENT_STATUS_ADD_FOCUS_WATCH_CB,
+       CURRENT_STATUS_REMOVE_FOCUS_WATCH_CB,
        CURRENT_STATUS_SET_FOCUS_REACQUISITION,
        CURRENT_STATUS_GET_FOCUS_REACQUISITION,
        CURRENT_STATUS_GET_REASON_FOR_P_FOCUS,
@@ -99,7 +99,7 @@ void focus_callback(sound_stream_info_h stream_info, sound_stream_focus_change_r
        int ret = SOUND_MANAGER_ERROR_NONE;
        sound_stream_focus_state_e playback_focus_state;
        sound_stream_focus_state_e recording_focus_state;
-       g_print("*** FOCUS callback is called, stream_info(%p) ***\n", stream_info);
+       g_print("\n*** FOCUS callback is called, stream_info(%p) ***\n", stream_info);
        g_print(" - change_reason(%d), extra_info(%s), user_data(%p)\n", reason, extra_info, user_data);
 
        ret = sound_manager_get_focus_state(stream_info, &playback_focus_state, &recording_focus_state);
@@ -121,9 +121,9 @@ void focus_callback(sound_stream_info_h stream_info, sound_stream_focus_change_r
        return;
 }
 
-void focus_watch_callback(sound_stream_focus_mask_e  focus_mask, sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason, const char *extra_info, void *user_data)
+void focus_watch_callback(int id, sound_stream_focus_mask_e  focus_mask, sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason, const char *extra_info, void *user_data)
 {
-       g_print("*** FOCUS WATCH callback is called ***\n");
+       g_print("\n*** FOCUS WATCH callback is called, id(%d) ***\n", id);
        g_print(" - changed_focus_mask(%d), changed_focus_state(%d), change_reason(%d), extra_info(%s), user_data(%p)\n",
                        focus_mask, focus_state, reason, extra_info, user_data);
        return;
@@ -214,10 +214,10 @@ void _interpret_main_menu(char *cmd)
                g_menu_state = CURRENT_STATUS_GET_ACQUIRED_FOCUS;
        else if (strncmp(cmd, "gst", 3) == 0)
                g_menu_state = CURRENT_STATUS_GET_SOUND_TYPE;
-       else if (strncmp(cmd, "sfw", 3) == 0)
-               g_menu_state = CURRENT_STATUS_SET_FOCUS_WATCH_CB;
-       else if (strncmp(cmd, "ufw", 3) == 0)
-               g_menu_state = CURRENT_STATUS_UNSET_FOCUS_WATCH_CB;
+       else if (strncmp(cmd, "afw", 3) == 0)
+               g_menu_state = CURRENT_STATUS_ADD_FOCUS_WATCH_CB;
+       else if (strncmp(cmd, "rfw", 3) == 0)
+               g_menu_state = CURRENT_STATUS_REMOVE_FOCUS_WATCH_CB;
        else if (strncmp(cmd, "sfr", 3) == 0)
                g_menu_state = CURRENT_STATUS_SET_FOCUS_REACQUISITION;
        else if (strncmp(cmd, "gfr", 3) == 0)
@@ -310,8 +310,8 @@ void display_sub_basic()
        g_print("afc. Acquire Focus\t");
        g_print("rfc. Release Focus\t");
        g_print("gfs. Get Focus State\n");
-       g_print("sfw. Set Focus State Watch CB\t");
-       g_print("ufw. Unset Focus State Watch CB\n");
+       g_print("afw. Add Focus State Watch CB\t");
+       g_print("rfw. Remove Focus State Watch CB\n");
        g_print("sfr. Set Focus Reacquisition\t");
        g_print("gfr. Get Focus Reacquisition\n");
        g_print("grp. Get Reason for Current Acquired Playback Focus\t");
@@ -415,10 +415,10 @@ static void displaymenu()
                g_print("*** press enter to get sound type\n");
        else if (g_menu_state == CURRENT_STATUS_DESTROY_STREAM_INFO)
                g_print("*** press enter to destroy stream information\n");
-       else if (g_menu_state == CURRENT_STATUS_SET_FOCUS_WATCH_CB)
+       else if (g_menu_state == CURRENT_STATUS_ADD_FOCUS_WATCH_CB)
                g_print("*** input focus type to watch for (0:playback, 1:recording, 2:both)\n");
-       else if (g_menu_state == CURRENT_STATUS_UNSET_FOCUS_WATCH_CB)
-               g_print("*** press enter to unset focus state watch cb\n");
+       else if (g_menu_state == CURRENT_STATUS_REMOVE_FOCUS_WATCH_CB)
+               g_print("*** input focus watch callback id to remove\n");
        else if (g_menu_state == CURRENT_STATUS_SET_FOCUS_REACQUISITION)
                g_print("*** input focus reacquisition property (1:enable, 2:disable)\n");
        else if (g_menu_state == CURRENT_STATUS_GET_FOCUS_REACQUISITION)
@@ -1278,7 +1278,7 @@ static void interpret(char *cmd)
                }
                ret = sound_manager_release_focus(g_stream_info_h, focus_mask, "sound_manager_test(release_focus)");
                if (ret)
-                               g_print("fail to sound_manager_acquire_focus(), ret(0x%x)\n", ret);
+                       g_print("fail to sound_manager_release_focus(), ret(0x%x)\n", ret);
 
                reset_menu_state();
                break;
@@ -1327,10 +1327,11 @@ static void interpret(char *cmd)
                reset_menu_state();
                break;
        }
-       case CURRENT_STATUS_SET_FOCUS_WATCH_CB: {
+       case CURRENT_STATUS_ADD_FOCUS_WATCH_CB: {
                int ret = SOUND_MANAGER_ERROR_NONE;
                int focus_type = 0;
                sound_stream_focus_mask_e focus_mask;
+               int id;
 
                focus_type = atoi(cmd);
                switch (focus_type) {
@@ -1347,18 +1348,23 @@ static void interpret(char *cmd)
                        focus_mask = SOUND_STREAM_FOCUS_FOR_PLAYBACK;
                        break;
                }
-               ret = sound_manager_set_focus_state_watch_cb(focus_mask, focus_watch_callback, NULL);
+               ret = sound_manager_add_focus_state_watch_cb(focus_mask, focus_watch_callback, NULL, &id);
                if (ret)
-                       g_print("fail to sound_manager_set_focus_state_watch_cb(), ret(0x%x)\n", ret);
+                       g_print("fail to sound_manager_add_focus_state_watch_cb(), ret(0x%x)\n", ret);
+               else
+                       g_print("id: %d\n", id);
 
                reset_menu_state();
                break;
        }
-       case CURRENT_STATUS_UNSET_FOCUS_WATCH_CB: {
+       case CURRENT_STATUS_REMOVE_FOCUS_WATCH_CB: {
                int ret = SOUND_MANAGER_ERROR_NONE;
-               ret = sound_manager_unset_focus_state_watch_cb();
+               int id = 0;
+
+               id = atoi(cmd);
+               ret = sound_manager_remove_focus_state_watch_cb(id);
                if (ret)
-                       g_print("fail to sound_manager_unset_focus_state_watch_cb(), ret(0x%x)\n", ret);
+                       g_print("fail to sound_manager_remove_focus_state_watch_cb(%d), ret(0x%x)\n", id, ret);
                reset_menu_state();
                break;
        }