Use socket for IPC of focus APIs instead of the DBus 06/164106/9 accepted/tizen/unified/20180702.062852 submit/tizen/20180626.044608
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 15 Dec 2017 09:05:12 +0000 (18:05 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 25 Jun 2018 07:10:16 +0000 (16:10 +0900)
The benefits of this change are here.
 - Connection is established when registering a focus node. This leads to
   remove the previous signal handler for cleaning focus resources.
 - Response time is enhanced as per the change of IPC.(DBus to socket)

[Version] 0.12.20
[Issue Type] Enhancement

Change-Id: Ifbc3ecde29985e9150ed7429b8616ef6cbe99d92
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
25 files changed:
Makefile.am
common/mm_sound_dbus.c
configure.ac
focus_server/include/mm_sound_mgr_focus.h
focus_server/include/mm_sound_mgr_focus_ipc.h
focus_server/mm_sound_mgr_focus.c
focus_server/mm_sound_mgr_focus_dbus.c
focus_server/mm_sound_mgr_focus_ipc.c
focus_server/mm_sound_mgr_focus_socket.c
include/mm_sound.h
include/mm_sound_client.h
include/mm_sound_common.h
include/mm_sound_focus.h
include/mm_sound_focus_private.h [new file with mode: 0644]
include/mm_sound_focus_socket.h
include/mm_sound_intf.h
include/mm_sound_proxy.h
mm_sound_client.c
mm_sound_focus.c
mm_sound_focus_private.c [new file with mode: 0644]
mm_sound_focus_socket.c
mm_sound_proxy.c
packaging/libmm-sound.spec
server/mm_sound_mgr_ipc_dbus.c
testsuite/mm_sound_testsuite_simple.c

index 3b201a9..b4d4bdd 100644 (file)
@@ -4,9 +4,7 @@ SUBDIRS = common \
                server \
                testsuite
 
-if USE_FOCUS
 SUBDIRS += focus_server
-endif
 
 lib_LTLIBRARIES = libmmfsound.la
 
@@ -21,12 +19,12 @@ libmmfsound_la_SOURCES = mm_sound.c \
                        mm_sound_proxy.c \
                        mm_sound_device.c \
                        mm_sound_pa_client.c
-if USE_FOCUS
 includelibmmfsound_HEADERS += include/mm_sound_focus.h \
+                               include/mm_sound_focus_private.h \
                                include/mm_sound_focus_socket.h
 libmmfsound_la_SOURCES += mm_sound_focus.c \
+                               mm_sound_focus_private.c \
                                mm_sound_focus_socket.c
-endif
 
 libmmfsound_la_DEPENDENCIES = common/libmmfsoundcommon.la
 
@@ -62,11 +60,6 @@ libmmfsound_la_LDFLAGS = -version-info 1:0:1
 libmmfsound_la_CFLAGS += $(MMLOGSVR_CFLAGS) -DMMF_LOG_OWNER=0x020 -DMMF_DEBUG_PREFIX=\"MMF-SOUND\"
 libmmfsound_la_LIBADD += $(MMLOGSVR_LIBS)
 
-if USE_FOCUS
-libmmfsound_la_CFLAGS += -DUSE_FOCUS
-endif
-
-
 lib_LTLIBRARIES += libmmfkeysound.la
 
 includelibmmfkeysounddir = $(includedir)/mmf
index db3f600..fcd43b3 100644 (file)
@@ -73,21 +73,6 @@ const mm_sound_dbus_method_info_t g_methods[AUDIO_METHOD_MAX] = {
        [AUDIO_METHOD_IS_STREAM_ON_DEVICE] = {
                .name = "IsStreamOnDevice",
        },
-       [AUDIO_METHOD_GET_UNIQUE_ID] = {
-               .name = "GetUniqueId",
-       },
-       [AUDIO_METHOD_REGISTER_FOCUS] = {
-               .name = "RegisterFocus",
-       },
-       [AUDIO_METHOD_UNREGISTER_FOCUS] = {
-               .name = "UnregisterFocus",
-       },
-       [AUDIO_METHOD_SET_FOCUS_REACQUISITION] = {
-               .name = "SetFocusReacquisition",
-       },
-       [AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE] = {
-               .name = "GetAcquiredFocusStreamType",
-       },
        [AUDIO_METHOD_ACQUIRE_FOCUS] = {
                .name = "AcquireFocus",
        },
@@ -97,15 +82,6 @@ const mm_sound_dbus_method_info_t g_methods[AUDIO_METHOD_MAX] = {
        [AUDIO_METHOD_UPDATE_STREAM_FOCUS_STATUS] = {
                .name = "UpdateFocusStatusByFocusId",
        },
-       [AUDIO_METHOD_WATCH_FOCUS] = {
-               .name = "WatchFocus",
-       },
-       [AUDIO_METHOD_UNWATCH_FOCUS] = {
-               .name = "UnwatchFocus",
-       },
-       [AUDIO_METHOD_DELIVER_FOCUS] = {
-               .name = "DeliverFocus",
-       },
        [AUDIO_METHOD_SET_FILTER] = {
                .name = "SetFilter",
        },
@@ -145,9 +121,6 @@ const mm_sound_dbus_signal_info_t g_events[AUDIO_EVENT_MAX] = {
        [AUDIO_EVENT_FOCUS_WATCH] = {
                .name = "FocusWatch",
        },
-       [AUDIO_EVENT_EMERGENT_EXIT] = {
-               .name = "EmergentExit",
-       },
        [AUDIO_EVENT_CLIENT_SUBSCRIBED] = {
                .name = "ClientSubscribed",
        },
@@ -421,8 +394,6 @@ static void _dbus_signal_callback(GDBusConnection *connection,
                (cb_data->user_cb)(AUDIO_EVENT_FOCUS_WATCH, params, cb_data->user_data);
        else if (!strcmp(signal_name, g_events[AUDIO_EVENT_PLAY_FILE_END].name))
                (cb_data->user_cb)(AUDIO_EVENT_PLAY_FILE_END, params, cb_data->user_data);
-       else if (!strcmp(signal_name, g_events[AUDIO_EVENT_EMERGENT_EXIT].name))
-               (cb_data->user_cb)(AUDIO_EVENT_EMERGENT_EXIT, params, cb_data->user_data);
        else if (!strcmp(signal_name, g_events[AUDIO_EVENT_DEVICE_RUNNING_CHANGED].name))
                (cb_data->user_cb)(AUDIO_EVENT_DEVICE_RUNNING_CHANGED, params, cb_data->user_data);
 }
index 8a28a10..223fa53 100644 (file)
@@ -78,16 +78,6 @@ AC_SUBST(LWIPC_LIBS)
 fi
 AM_CONDITIONAL([USE_LWIPC], [test "x$USE_LWIPC" = "xyes"])
 
-AC_ARG_ENABLE(focus, AC_HELP_STRING([--enable-focus], [enable focus feature]),
-[
- case "${enableval}" in
-        yes) USE_FOCUS=yes ;;
-        no)  USE_FOCUS=no ;;
-        *)   AC_MSG_ERROR(bad value ${enableval} for --enable-focus) ;;
- esac
- ],[USE_FOCUS=no])
-AM_CONDITIONAL([USE_FOCUS], [test "x$USE_FOCUS" = "xyes"])
-
 AC_ARG_ENABLE(prelink, AC_HELP_STRING([--enable-prelink], [enable pre-link feature]),
 [
  case "${enableval}" in
index 7c60f5d..21dfbd8 100644 (file)
@@ -23,6 +23,7 @@
 #define __MM_SOUND_MGR_FOCUS_H__
 
 #include "../include/mm_sound.h"
+#include "../include/mm_sound_common.h"
 #include "../include/mm_sound_focus.h"
 #include "../include/mm_sound_stream.h"
 #include "mm_sound_mgr_focus_ipc.h"
@@ -89,10 +90,10 @@ int mm_sound_mgr_focus_set_reacquisition(const _mm_sound_mgr_focus_param_t *para
 int mm_sound_mgr_focus_get_stream_type_of_acquired_focus(focus_type_e focus_type, char **stream_type, int *option, char **ext_info);
 int mm_sound_mgr_focus_request_acquire(const _mm_sound_mgr_focus_param_t *param);
 int mm_sound_mgr_focus_request_release(const _mm_sound_mgr_focus_param_t *param);
-int mm_sound_mgr_focus_set_watch_cb(const _mm_sound_mgr_focus_param_t *param);
-int mm_sound_mgr_focus_unset_watch_cb(const _mm_sound_mgr_focus_param_t *param);
+int mm_sound_mgr_focus_add_watch_node(const _mm_sound_mgr_focus_param_t *param);
+int mm_sound_mgr_focus_remove_watch_node(const _mm_sound_mgr_focus_param_t *param);
 int mm_sound_mgr_focus_deliver(const _mm_sound_mgr_focus_param_t *param);
-int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param);
+int mm_sound_mgr_focus_emergent_exit_by_id(int id);
 
 #endif /* __MM_SOUND_MGR_FOCUS_H__ */
 
index 8e28cce..0698a40 100644 (file)
 
 #include <stdbool.h>
 
-int __mm_sound_mgr_focus_ipc_register_focus(int client_pid, int handle_id, const char* stream_type);
+int __mm_sound_mgr_focus_ipc_register_focus(int pid, int handle_id, const char* stream_type);
 int __mm_sound_mgr_focus_ipc_unregister_focus(int pid, int handle_id);
+int __mm_sound_mgr_focus_ipc_add_watch_node(int pid, int handle_id, int focus_type);
+int __mm_sound_mgr_focus_ipc_remove_watch_node(int pid, int handle_id);
 int __mm_sound_mgr_focus_ipc_set_focus_reacquisition(int pid, int handle_id, bool reacquisition);
 int __mm_sound_mgr_focus_ipc_get_acquired_focus_stream_type(int focus_type, char **stream_type, int *option, char **ext_info);
 int __mm_sound_mgr_focus_ipc_acquire_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_in_thread);
index e3d297a..746cc25 100644 (file)
@@ -56,16 +56,6 @@ typedef struct {
        int option;
 } focus_cb_data;
 
-#define CLEAR_DEAD_NODE_LIST(x)  do { \
-       debug_warning("list = %p, node = %p, pid=[%d]", x, node, (node) ? node->pid : -1); \
-       if (x && node && (mm_sound_util_is_process_alive(node->pid) == FALSE)) { \
-               debug_warning("PID:%d does not exist now! remove from device cb list", node->pid); \
-               __clear_focus_pipe(node); \
-               x = g_list_remove(x, node); \
-               g_free(node); \
-       } \
-} while (0)
-
 #define UPDATE_FOCUS_TAKEN_INFO(x_postfix, x_node, x_pid, x_hid) do { \
        debug_msg("updating node[%p], taken_"#x_postfix"[%d] : pid = [%d], handle_id = [%d]", x_node, i, x_pid, x_hid); \
        x_node->taken_##x_postfix[i].pid = x_pid; \
@@ -115,28 +105,29 @@ static void __clear_focus_pipe(focus_node_t *node)
                filename2 = __get_focus_pipe_path(node->pid, node->handle_id, "r", true);
        }
        if (filename) {
-               if (remove(filename))
-                       debug_error("remove() failure, filename(%s), errno(%d)", filename, errno);
-               else
+               if (remove(filename)) {
+                       char str_error[256];
+                       strerror_r(errno, str_error, sizeof(str_error));
+                       debug_error("remove() failure, filename(%s), err[%s]", filename, str_error);
+               } else {
                        debug_log("removed file(%s)", filename);
+               }
                free(filename);
        }
        if (filename2) {
-               if (remove(filename2))
-                       debug_error("remove() failure, filename2(%s), errno(%d)", filename2, errno);
-               else
+               if (remove(filename2)) {
+                       char str_error[256];
+                       strerror_r(errno, str_error, sizeof(str_error));
+                       debug_error("remove() failure, filename2(%s), err[%s]", filename2, str_error);
+               } else {
                        debug_log("removed file(%s)", filename2);
+               }
                free(filename2);
        }
 
        debug_fleave();
 }
 
-static void _clear_focus_node_list_func(focus_node_t *node, gpointer user_data)
-{
-       CLEAR_DEAD_NODE_LIST(g_focus_node_list);
-}
-
 static int _mm_sound_mgr_focus_get_priority_from_stream_type(int *priority, const char *stream_type)
 {
        int ret = MM_ERROR_NONE;
@@ -616,9 +607,6 @@ int mm_sound_mgr_focus_create_node(const _mm_sound_mgr_focus_param_t *param)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
                CONTINUE_IF_NOT_MY_FOCUS_NODE(node, param);
@@ -672,9 +660,6 @@ int mm_sound_mgr_focus_destroy_node(const _mm_sound_mgr_focus_param_t *param)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
                CONTINUE_IF_NOT_MY_FOCUS_NODE(node, param);
@@ -760,9 +745,6 @@ int mm_sound_mgr_focus_set_reacquisition(const _mm_sound_mgr_focus_param_t *para
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        /* Find node to set reacquisition */
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
@@ -837,9 +819,6 @@ int mm_sound_mgr_focus_get_stream_type_of_acquired_focus(focus_type_e focus_type
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        /* Find node to set reacquisition */
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
@@ -892,9 +871,6 @@ int mm_sound_mgr_focus_request_acquire(const _mm_sound_mgr_focus_param_t *param)
        if (!param->is_in_thread)
                MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
                CONTINUE_IF_NOT_MY_FOCUS_NODE(node, param);
@@ -1007,9 +983,6 @@ int mm_sound_mgr_focus_request_release(const _mm_sound_mgr_focus_param_t *param)
        if (!param->is_in_thread)
                MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
                CONTINUE_IF_NOT_MY_FOCUS_NODE(node, param);
@@ -1077,7 +1050,7 @@ FINISH:
        return ret;
 }
 
-int mm_sound_mgr_focus_set_watch_cb(const _mm_sound_mgr_focus_param_t *param)
+int mm_sound_mgr_focus_add_watch_node(const _mm_sound_mgr_focus_param_t *param)
 {
        int ret = MM_ERROR_NONE;
        GList *list = NULL;
@@ -1087,9 +1060,6 @@ int mm_sound_mgr_focus_set_watch_cb(const _mm_sound_mgr_focus_param_t *param)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
                if ((node->pid == param->pid) && (node->handle_id == param->handle_id) && node->is_for_watch) {
@@ -1123,7 +1093,7 @@ FINISH:
        return ret;
 }
 
-int mm_sound_mgr_focus_unset_watch_cb(const _mm_sound_mgr_focus_param_t *param)
+int mm_sound_mgr_focus_remove_watch_node(const _mm_sound_mgr_focus_param_t *param)
 {
        int ret = MM_ERROR_SOUND_INTERNAL;
        GList *list = NULL;
@@ -1133,9 +1103,6 @@ int mm_sound_mgr_focus_unset_watch_cb(const _mm_sound_mgr_focus_param_t *param)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
                if ((node->pid == param->pid) && (node->handle_id == param->handle_id) && node->is_for_watch) {
@@ -1173,9 +1140,6 @@ int mm_sound_mgr_focus_deliver(const _mm_sound_mgr_focus_param_t *param)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        for (list = g_focus_node_list; list != NULL; list = list->next) {
                CONTINUE_IF_LIST_DATA_IS_NULL(src_node, list);
                if ((src_node->pid == param->pid) && (src_node->handle_id == param->handle_id)) {
@@ -1254,7 +1218,7 @@ FINISH:
        return ret;
 }
 
-int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param)
+int mm_sound_mgr_focus_emergent_exit_by_id(int id)
 {
        int ret = MM_ERROR_NONE;
        GList *list = NULL;
@@ -1267,15 +1231,11 @@ int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       /* Update list for dead process */
-       g_list_foreach(g_focus_node_list, (GFunc)_clear_focus_node_list_func, NULL);
-
        list = g_focus_node_list;
        while (list) {
                CONTINUE_IF_LIST_DATA_IS_NULL(node, list);
-               if (node->pid != param->pid) {
+               if (node->handle_id != id) {
                        list = list->next;
-                       debug_log("node not found, next list = %p", list);
                        continue;
                }
                if (node->is_for_watch) {
@@ -1293,8 +1253,8 @@ int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param)
                        for (list_s = g_focus_node_list; list_s != NULL; list_s = list_s->next) {
                                CONTINUE_IF_LIST_DATA_IS_NULL(node, list_s);
                                for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
-                                       if (node->taken_by_id[i].pid == param->pid) {
-                                               if (my_node->taken_by_id[i].pid)
+                                       if (node->taken_by_id[i].handle_id == id) {
+                                               if (my_node->taken_by_id[i].handle_id)
                                                        UPDATE_FOCUS_TAKEN_INFO(by_id, node, my_node->taken_by_id[i].pid, my_node->taken_by_id[i].handle_id);
                                                else
                                                        UPDATE_FOCUS_TAKEN_INFO(by_id, node, 0, 0);
@@ -1318,12 +1278,12 @@ int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param)
                        MMSOUND_STRNCPY(param_s.stream_type, my_node->stream_type, MAX_STREAM_TYPE_LEN);
                        for (list_s = g_focus_node_list; list_s != NULL; list_s = list_s->next) {
                                CONTINUE_IF_LIST_DATA_IS_NULL(node, list_s);
-                               if (my_node->pid == node->pid || node->is_for_watch)
+                               if (my_node->handle_id == node->handle_id || node->is_for_watch)
                                        continue;
                                for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
                                        if (!(my_node->status & (i+1)))
                                                continue;
-                                       if (node->taken_by_id[i].pid == param_s.pid && node->taken_by_id[i].handle_id == param_s.handle_id) {
+                                       if (node->taken_by_id[i].handle_id == param_s.handle_id) {
                                                /* do callback for resumption */
                                                if ((ret = _mm_sound_mgr_focus_do_callback(FOCUS_COMMAND_ACQUIRE, node, &param_s)))
                                                        debug_error("Fail to _focus_do_callback for COMMAND ACQUIRE to node[%p], ret[0x%x]", node, ret);
@@ -1350,7 +1310,6 @@ int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param)
 
        debug_fleave();
        return ret;
-
 }
 
 int MMSoundMgrFocusInit(void)
index 98d85d6..dbf7265 100644 (file)
 static const gchar introspection_xml[] =
        "<node>"
        "  <interface name='org.tizen.FocusServer1'>"
-       "    <method name='GetUniqueId'>"
-       "      <arg name='id' type='i' direction='out'/>"
-       "    </method>"
-       "    <method name='RegisterFocus'>"
-       "      <arg name='pid' type='i' direction='in'/>"
-       "      <arg name='handle_id' type='i' direction='in'/>"
-       "      <arg name='stream_type' type='s' direction='in'/>"
-       "    </method>"
-       "    <method name='UnregisterFocus'>"
-       "      <arg name='pid' type='i' direction='in'/>"
-       "      <arg name='handle_id' type='i' direction='in'/>"
-       "    </method>"
-       "    <method name='SetFocusReacquisition'>"
-       "      <arg name='pid' type='i' direction='in'/>"
-       "      <arg name='handle_id' type='i' direction='in'/>"
-       "      <arg name='reacquisition' type='b' direction='in'/>"
-       "    </method>"
-       "    <method name='GetAcquiredFocusStreamType'>"
-       "      <arg name='focus_type' type='i' direction='in'/>"
-       "      <arg name='stream_type' type='s' direction='out'/>"
-       "      <arg name='option' type='i' direction='out'/>"
-       "      <arg name='ext_info' type='s' direction='out'/>"
-       "    </method>"
        "    <method name='AcquireFocus'>"
        "      <arg name='pid' type='i' direction='in'/>"
        "      <arg name='handle_id' type='i' direction='in'/>"
@@ -58,24 +35,6 @@ static const gchar introspection_xml[] =
        "      <arg name='option' type='i' direction='in'/>"
        "      <arg name='ext_info' type='s' direction='in'/>"
        "    </method>"
-       "    <method name='WatchFocus'>"
-       "      <arg name='pid' type='i' direction='in'/>"
-       "      <arg name='handle_id' type='i' direction='in'/>"
-       "      <arg name='focus_type' type='i' direction='in'/>"
-       "    </method>"
-       "    <method name='UnwatchFocus'>"
-       "      <arg name='pid' type='i' direction='in'/>"
-       "      <arg name='handle_id' type='i' direction='in'/>"
-       "    </method>"
-       "    <method name='DeliverFocus'>"
-       "      <arg name='pid' type='i' direction='in'/>"
-       "      <arg name='src_handle_id' type='i' direction='in'/>"
-       "      <arg name='dst_handle_id' type='i' direction='in'/>"
-       "      <arg name='focus_type' type='i' direction='in'/>"
-       "    </method>"
-       "    <method name='EmergentExitFocus'>"
-       "      <arg name='pid' type='i' direction='in'/>"
-       "    </method>"
        "  </interface>"
        "</node>";
 static GDBusConnection* conn_g;
@@ -93,52 +52,14 @@ struct mm_sound_mgr_focus_dbus_signal {
        dbus_signal_sender sender;
 };
 
-static void handle_method_get_unique_id(GDBusMethodInvocation* invocation);
-static void handle_method_register_focus(GDBusMethodInvocation* invocation);
-static void handle_method_unregister_focus(GDBusMethodInvocation* invocation);
-static void handle_method_set_focus_reacquisition(GDBusMethodInvocation* invocation);
-static void handle_method_get_acquired_focus_stream_type(GDBusMethodInvocation* invocation);
 static void handle_method_acquire_focus(GDBusMethodInvocation* invocation);
 static void handle_method_release_focus(GDBusMethodInvocation* invocation);
-static void handle_method_watch_focus(GDBusMethodInvocation* invocation);
-static void handle_method_unwatch_focus(GDBusMethodInvocation* invocation);
-static void handle_method_deliver_focus(GDBusMethodInvocation* invocation);
 
 /* Currently , Just using method's name and handler */
 /* TODO : generate introspection xml automatically, with these value include argument and reply */
 /* TODO : argument check with these information */
 /* TODO : divide object and interface with features (ex. play, path, device, focus, asm) */
 static mm_sound_dbus_method_intf_t methods[AUDIO_METHOD_MAX] = {
-       [AUDIO_METHOD_GET_UNIQUE_ID] = {
-               .info = {
-                       .name = "GetUniqueId",
-               },
-               .handler = handle_method_get_unique_id
-       },
-       [AUDIO_METHOD_REGISTER_FOCUS] = {
-               .info = {
-                       .name = "RegisterFocus",
-               },
-               .handler = handle_method_register_focus
-       },
-       [AUDIO_METHOD_UNREGISTER_FOCUS] = {
-               .info = {
-                       .name = "UnregisterFocus",
-               },
-               .handler = handle_method_unregister_focus
-       },
-       [AUDIO_METHOD_SET_FOCUS_REACQUISITION] = {
-               .info = {
-                       .name = "SetFocusReacquisition",
-               },
-               .handler = handle_method_set_focus_reacquisition
-       },
-       [AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE] = {
-               .info = {
-                       .name = "GetAcquiredFocusStreamType",
-               },
-               .handler = handle_method_get_acquired_focus_stream_type
-       },
        [AUDIO_METHOD_ACQUIRE_FOCUS] = {
                .info = {
                        .name = "AcquireFocus",
@@ -150,30 +71,11 @@ static mm_sound_dbus_method_intf_t methods[AUDIO_METHOD_MAX] = {
                        .name = "ReleaseFocus",
                },
                .handler = handle_method_release_focus
-       },
-       [AUDIO_METHOD_WATCH_FOCUS] = {
-               .info = {
-                       .name = "WatchFocus",
-               },
-               .handler = handle_method_watch_focus
-       },
-       [AUDIO_METHOD_UNWATCH_FOCUS] = {
-               .info = {
-                       .name = "UnwatchFocus",
-               },
-               .handler = handle_method_unwatch_focus
-       },
-       [AUDIO_METHOD_DELIVER_FOCUS] = {
-               .info = {
-                       .name = "DeliverFocus",
-               },
-               .handler = handle_method_deliver_focus
        }
 };
 
 static GDBusNodeInfo *introspection_data = NULL;
 guint focus_server_owner_id ;
-unsigned emergent_exit_subs_id;
 
 /*
        For pass error code with 'g_dbus_method_invocation_return_error'
@@ -256,127 +158,6 @@ static void _method_call_return_error(GDBusMethodInvocation *invocation, int ret
        g_dbus_method_invocation_return_dbus_error(invocation, err_name, "failed");
 }
 
-static void handle_method_get_unique_id(GDBusMethodInvocation* invocation)
-{
-       static int unique_id = 0;
-
-       debug_fenter();
-
-       _method_call_return_value(invocation, g_variant_new("(i)", ++unique_id));
-
-       debug_fleave();
-}
-
-static void handle_method_register_focus(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int handle_id = 0;
-       const char* stream_type = NULL;
-       GVariant *params = NULL;
-       int pid = 0;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(ii&s)", &pid, &handle_id, &stream_type);
-       ret = __mm_sound_mgr_focus_ipc_register_focus(_get_sender_pid(invocation), handle_id, stream_type);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("()"));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-
-static void handle_method_unregister_focus(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int pid = 0, handle_id = 0;
-       GVariant *params = NULL;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(ii)", &pid, &handle_id);
-       ret = __mm_sound_mgr_focus_ipc_unregister_focus(_get_sender_pid(invocation), handle_id);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("()"));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-
-static void handle_method_set_focus_reacquisition(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int pid = 0, handle_id = 0;
-       gboolean reacquisition;
-       GVariant *params = NULL;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(iib)", &pid, &handle_id, &reacquisition);
-       ret = __mm_sound_mgr_focus_ipc_set_focus_reacquisition(_get_sender_pid(invocation), handle_id, reacquisition);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("()"));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-
-static void handle_method_get_acquired_focus_stream_type(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int focus_type = 0;
-       char *stream_type = NULL;
-       int option = 0;
-       char *ext_info = NULL;
-       GVariant *params = NULL;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(i)", &focus_type);
-       ret = __mm_sound_mgr_focus_ipc_get_acquired_focus_stream_type(focus_type, &stream_type, &option, &ext_info);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("(sis)", stream_type, option, ext_info));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-
 static void handle_method_acquire_focus(GDBusMethodInvocation* invocation)
 {
        int ret = MM_ERROR_NONE;
@@ -433,89 +214,6 @@ send_reply:
        debug_fleave();
 }
 
-static void handle_method_watch_focus(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int handle_id = 0, focus_type = 0;
-       GVariant *params = NULL;
-       int pid = 0;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(iii)", &pid, &handle_id, &focus_type);
-       ret = __mm_sound_mgr_focus_ipc_watch_focus(_get_sender_pid(invocation), handle_id, focus_type);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("()"));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-
-static void handle_method_unwatch_focus(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int pid = 0;
-       int handle_id = 0;
-       GVariant *params = NULL;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(ii)", &pid, &handle_id);
-       ret = __mm_sound_mgr_focus_ipc_unwatch_focus(_get_sender_pid(invocation), handle_id);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("()"));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-
-static void handle_method_deliver_focus(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int pid = 0;
-       int src_handle_id = 0;
-       int dst_handle_id = 0;
-       int focus_type = 0;
-       GVariant *params = NULL;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(iiii)", &pid, &src_handle_id, &dst_handle_id, &focus_type);
-       ret = __mm_sound_mgr_focus_ipc_deliver_focus(pid, src_handle_id, dst_handle_id, focus_type);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("()"));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-
 /**********************************************************************************/
 static void handle_method_call(GDBusConnection *connection,
                                                        const gchar *sender,
@@ -534,7 +232,7 @@ static void handle_method_call(GDBusConnection *connection,
        }
        debug_msg("Method Call, obj : %s, intf : %s, method : %s", object_path, interface_name, method_name);
 
-       for (method_idx = AUDIO_METHOD_GET_UNIQUE_ID; method_idx < AUDIO_METHOD_MAX; method_idx++) {
+       for (method_idx = AUDIO_METHOD_ACQUIRE_FOCUS; method_idx < AUDIO_METHOD_UPDATE_STREAM_FOCUS_STATUS; method_idx++) {
                if (!g_strcmp0(method_name, methods[method_idx].info.name))
                        methods[method_idx].handler(invocation);
        }
@@ -565,25 +263,6 @@ static gboolean handle_set_property(GDBusConnection *connection,
        return TRUE;
 }
 
-void emergent_exit_signal_handler(audio_event_t event, GVariant *param, void *userdata)
-{
-       int ret = MM_ERROR_NONE;
-       int pid = 0;
-
-       if (event != AUDIO_EVENT_EMERGENT_EXIT)
-               return;
-
-       debug_fenter();
-
-       g_variant_get(param, "(i)", &pid);
-       debug_log("emergent exit : pid %d", pid);
-       ret = __mm_sound_mgr_focus_ipc_emergent_exit(pid);
-       if (ret)
-               debug_error("__mm_sound_mgr_focus_ipc_emergent_exit failed : 0x%x", ret);
-
-       debug_fleave();
-}
-
 static const GDBusInterfaceVTable interface_vtable = {
        handle_method_call,
        handle_get_property,
@@ -727,10 +406,6 @@ int MMSoundMgrFocusDbusInit(void)
                debug_error("dbus own name for focus-server error");
                return MM_ERROR_SOUND_INTERNAL;
        }
-       if (mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_EMERGENT_EXIT, emergent_exit_signal_handler, NULL, NULL, &emergent_exit_subs_id) != MM_ERROR_NONE) {
-               debug_error("dbus signal subscribe for emergent exit error");
-               return MM_ERROR_SOUND_INTERNAL;
-       }
 
        debug_leave();
 
@@ -741,8 +416,6 @@ void MMSoundMgrFocusDbusFini(void)
 {
        debug_enter();
 
-       if (emergent_exit_subs_id != 0)
-               mm_sound_dbus_signal_unsubscribe(emergent_exit_subs_id);
        _mm_sound_mgr_focus_dbus_unown_name(focus_server_owner_id);
        g_dbus_node_info_unref(introspection_data);
 
index d300e45..1c2b811 100644 (file)
 #include "include/mm_sound_mgr_focus.h"
 #include <mm_debug.h>
 
-int __mm_sound_mgr_focus_ipc_register_focus(int client_pid, int handle_id, const char* stream_type)
+int __mm_sound_mgr_focus_ipc_register_focus(int pid, int handle_id, const char* stream_type)
 {
        _mm_sound_mgr_focus_param_t param;
        int ret = MM_ERROR_NONE;
 
        memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
-       param.pid = client_pid;
+       param.pid = pid;
        param.handle_id = handle_id;
        MMSOUND_STRNCPY(param.stream_type, stream_type, MAX_STREAM_TYPE_LEN);
 
@@ -59,6 +59,35 @@ int __mm_sound_mgr_focus_ipc_unregister_focus(int pid, int handle_id)
        return ret;
 }
 
+int __mm_sound_mgr_focus_ipc_add_watch_node(int pid, int handle_id, int focus_type)
+{
+       _mm_sound_mgr_focus_param_t param;
+       int ret = MM_ERROR_NONE;
+
+       memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
+       param.pid = pid;
+       param.handle_id = handle_id;
+       param.request_type = focus_type;
+
+       ret = mm_sound_mgr_focus_add_watch_node(&param);
+
+       return ret;
+}
+
+int __mm_sound_mgr_focus_ipc_remove_watch_node(int pid, int handle_id)
+{
+       _mm_sound_mgr_focus_param_t param;
+       int ret = MM_ERROR_NONE;
+
+       memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
+       param.pid = pid;
+       param.handle_id = handle_id;
+
+       ret = mm_sound_mgr_focus_remove_watch_node(&param);
+
+       return ret;
+}
+
 // method -> callback
 int __mm_sound_mgr_focus_ipc_set_focus_reacquisition(int pid, int handle_id, bool reacquisition)
 {
@@ -133,36 +162,6 @@ int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_typ
        return ret;
 }
 
-int __mm_sound_mgr_focus_ipc_watch_focus(int pid, int handle_id, int focus_type)
-{
-       _mm_sound_mgr_focus_param_t param;
-       int ret = MM_ERROR_NONE;
-
-       memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
-       param.pid = pid;
-       param.handle_id = handle_id;
-       param.request_type = focus_type;
-
-       ret = mm_sound_mgr_focus_set_watch_cb(&param);
-
-       return ret;
-}
-
-// method + remove callback
-int __mm_sound_mgr_focus_ipc_unwatch_focus(int pid, int handle_id)
-{
-       _mm_sound_mgr_focus_param_t param;
-       int ret = MM_ERROR_NONE;
-
-       memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
-       param.pid = pid;
-       param.handle_id = handle_id;
-
-       ret = mm_sound_mgr_focus_unset_watch_cb(&param);
-
-       return ret;
-}
-
 int __mm_sound_mgr_focus_ipc_deliver_focus(int pid, int src_handle_id, int dst_handle_id, int focus_type)
 {
        _mm_sound_mgr_focus_param_t param;
@@ -178,17 +177,3 @@ int __mm_sound_mgr_focus_ipc_deliver_focus(int pid, int src_handle_id, int dst_h
 
        return ret;
 }
-
-int __mm_sound_mgr_focus_ipc_emergent_exit(int pid)
-{
-       _mm_sound_mgr_focus_param_t param;
-       int ret = MM_ERROR_NONE;
-
-       memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
-       param.pid = pid;
-
-       ret = mm_sound_mgr_focus_emergent_exit(&param);
-
-       return ret;
-}
-
index 06e3ba9..ae5f6b7 100644 (file)
 #include "include/mm_sound_mgr_focus.h"
 #include "include/mm_sound_mgr_focus_ipc.h"
 
-static pthread_t g_focus_work_thread_id = 0;
-
-
-typedef int (*focus_function_handler) (_mm_sound_mgr_focus_socket_param_t *param);
-static int handle_acquire_focus(_mm_sound_mgr_focus_socket_param_t *param);
-static int handle_release_focus(_mm_sound_mgr_focus_socket_param_t *param);
+static pthread_t g_focus_ready_thread_id = 0;
+
+typedef int (*focus_function_handler) (int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_register_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_unregister_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_add_watch_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_remove_watch_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_acquire_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_release_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_set_focus_reacquisition(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_deliver_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
+static int handle_get_acquired_focus_info(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result);
 
 enum {
+       FOCUS_FUNCTION_REGISTER,
+       FOCUS_FUNCTION_UNREGISTER,
+       FOCUS_FUNCTION_ADD_WATCH,
+       FOCUS_FUNCTION_REMOVE_WATCH,
        FOCUS_FUNCTION_ACQUIRE,
        FOCUS_FUNCTION_RELEASE,
+       FOCUS_FUNCTION_SET_REACQUISITION,
+       FOCUS_FUNCTION_DELIVER,
+       FOCUS_FUNCTION_GET_ACQUIRED_INFO,
        FOCUS_FUNCTION_MAX,
 };
 
@@ -54,6 +67,22 @@ typedef struct mm_sound_focus_function_intf {
 } mm_sound_focus_function_intf_t;
 
 static mm_sound_focus_function_intf_t functions[FOCUS_FUNCTION_MAX] = {
+       [FOCUS_FUNCTION_REGISTER] = {
+               .name = FOCUS_FUNC_NAME_REGISTER,
+               .handler = handle_register_focus
+       },
+       [FOCUS_FUNCTION_UNREGISTER] = {
+               .name = FOCUS_FUNC_NAME_UNREGISTER,
+               .handler = handle_unregister_focus
+       },
+       [FOCUS_FUNCTION_ADD_WATCH] = {
+               .name = FOCUS_FUNC_NAME_ADD_WATCH,
+               .handler = handle_add_watch_focus
+       },
+       [FOCUS_FUNCTION_REMOVE_WATCH] = {
+               .name = FOCUS_FUNC_NAME_REMOVE_WATCH,
+               .handler = handle_remove_watch_focus
+       },
        [FOCUS_FUNCTION_ACQUIRE] = {
                .name = FOCUS_FUNC_NAME_ACQUIRE,
                .handler = handle_acquire_focus
@@ -62,38 +91,92 @@ static mm_sound_focus_function_intf_t functions[FOCUS_FUNCTION_MAX] = {
                .name = FOCUS_FUNC_NAME_RELEASE,
                .handler = handle_release_focus
        },
+       [FOCUS_FUNCTION_SET_REACQUISITION] = {
+               .name = FOCUS_FUNC_NAME_SET_REACQUISITON,
+               .handler = handle_set_focus_reacquisition
+       },
+       [FOCUS_FUNCTION_DELIVER] = {
+               .name = FOCUS_FUNC_NAME_DELIVER,
+               .handler = handle_deliver_focus
+       },
+       [FOCUS_FUNCTION_GET_ACQUIRED_INFO] = {
+               .name = FOCUS_FUNC_NAME_GET_ACQUIRED_INFO,
+               .handler = handle_get_acquired_focus_info
+       }
 };
 
-static const char* convert_error_string_from_int(int error)
+static int handle_register_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
 {
-       switch (error) {
-       case MM_ERROR_NONE:
-               return FOCUS_ERROR_NONE;
+       int ret = MM_ERROR_NONE;
 
-       case MM_ERROR_INVALID_ARGUMENT:
-               return FOCUS_ERROR_INVALID_PARAMETER;
+       debug_fenter();
+
+       ret = __mm_sound_mgr_focus_ipc_register_focus(param->pid, fd, param->stream_type);
+       result->handle_id = fd;
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int handle_unregister_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
+{
+       int ret = MM_ERROR_NONE;
 
-       case MM_ERROR_POLICY_BLOCKED:
-       case MM_ERROR_POLICY_INTERNAL:
-               return FOCUS_ERROR_POLICY;
+       debug_fenter();
+
+       if (fd != param->handle_id) {
+               debug_error("fd[%d] does not match with handle_id[%d] from param", fd, param->handle_id);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+       ret = __mm_sound_mgr_focus_ipc_unregister_focus(param->pid, param->handle_id);
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int handle_add_watch_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       ret = __mm_sound_mgr_focus_ipc_add_watch_node(param->pid, fd, param->focus_type);
+       result->handle_id = fd;
+
+       debug_fleave();
+
+       return ret;
+}
 
-       case MM_ERROR_SOUND_INVALID_STATE:
-               return FOCUS_ERROR_INVALID_STATE;
+static int handle_remove_watch_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
+{
+       int ret = MM_ERROR_NONE;
 
-       case MM_ERROR_SOUND_INTERNAL:
-               return FOCUS_ERROR_INTERNAL;
+       debug_fenter();
 
-       default:
-               return FOCUS_ERROR_INTERNAL;
+       if (fd != param->handle_id) {
+               debug_error("fd[%d] does not match with handle_id[%d] from param", fd, param->handle_id);
+               return MM_ERROR_SOUND_INTERNAL;
        }
+       ret = __mm_sound_mgr_focus_ipc_remove_watch_node(param->pid, param->handle_id);
+
+       debug_fleave();
+
+       return ret;
 }
 
-static int handle_acquire_focus(_mm_sound_mgr_focus_socket_param_t *param)
+static int handle_acquire_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
 {
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
+       if (fd != param->handle_id) {
+               debug_error("fd[%d] does not match with handle_id[%d] from param", fd, param->handle_id);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
        ret = __mm_sound_mgr_focus_ipc_acquire_focus(param->pid, param->handle_id, param->focus_type,
                                                                                                param->option, param->ext_info, true);
 
@@ -102,12 +185,16 @@ static int handle_acquire_focus(_mm_sound_mgr_focus_socket_param_t *param)
        return ret;
 }
 
-static int handle_release_focus(_mm_sound_mgr_focus_socket_param_t *param)
+static int handle_release_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
 {
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
+       if (fd != param->handle_id) {
+               debug_error("fd[%d] does not match with handle_id[%d] from param", fd, param->handle_id);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
        ret = __mm_sound_mgr_focus_ipc_release_focus(param->pid, param->handle_id, param->focus_type,
                                                                                                param->option, param->ext_info, true);
 
@@ -116,38 +203,174 @@ static int handle_release_focus(_mm_sound_mgr_focus_socket_param_t *param)
        return ret;
 }
 
-static int focus_functions_handler(_mm_sound_mgr_focus_socket_param_t *param)
+static int handle_set_focus_reacquisition(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       if (fd != param->handle_id) {
+               debug_error("fd[%d] does not match with handle_id[%d] from param", fd, param->handle_id);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+       ret = __mm_sound_mgr_focus_ipc_set_focus_reacquisition(param->pid, param->handle_id, param->reacquisition);
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int handle_deliver_focus(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       ret = __mm_sound_mgr_focus_ipc_deliver_focus(param->pid, param->handle_id, param->handle_id_dst, param->focus_type);
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int handle_get_acquired_focus_info(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
+{
+       int ret = MM_ERROR_NONE;
+       char *res_stream_type = NULL;
+       char *res_ext_info = NULL;
+
+       debug_fenter();
+
+       if (!result) {
+               debug_error("invalid arguments, result[%p]", result);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       ret = __mm_sound_mgr_focus_ipc_get_acquired_focus_stream_type(param->focus_type, &res_stream_type, &result->option, &res_ext_info);
+       if (ret == MM_ERROR_NONE) {
+               MMSOUND_STRNCPY(result->stream_type, res_stream_type, MM_SOUND_NAME_NUM);
+               MMSOUND_STRNCPY(result->ext_info, res_ext_info, MM_SOUND_NAME_NUM);
+       }
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int focus_functions_handler(int fd, _mm_sound_focus_socket_param_t *param, _mm_sound_focus_socket_result_t *result)
 {
        int i = 0;
-       int ret = MM_ERROR_SOUND_INTERNAL;
+       int ret = MM_ERROR_NONE;
 
        if (param == NULL)
-               return MM_ERROR_SOUND_INTERNAL;
+               return MM_ERROR_INVALID_ARGUMENT;
 
-       debug_log("param[%p], function_name[%s]", param, param->func_name);
+       debug_log("fd[%d], param[%p], function_name[%s]", fd, param, param->func_name);
 
        for (i = 0; i < FOCUS_FUNCTION_MAX; i++) {
                if (!strncmp(param->func_name, functions[i].name, MAX_ERROR_LEN))
-                       ret = functions[i].handler(param);
+                       ret = functions[i].handler(fd, param, result);
        }
 
        return ret;
 }
 
-static void *thread_func(void *data)
+static bool need_to_exit(const char *func_name)
+{
+       if (!strncmp(func_name, FOCUS_FUNC_NAME_UNREGISTER, MM_SOUND_NAME_NUM) ||
+               !strncmp(func_name, FOCUS_FUNC_NAME_REMOVE_WATCH, MM_SOUND_NAME_NUM) ||
+               !strncmp(func_name, FOCUS_FUNC_NAME_GET_ACQUIRED_INFO, MM_SOUND_NAME_NUM))
+               return true;
+
+       return false;
+}
+
+static void* work_thread_func(void *data)
 {
-       int fd = -1;
        int accepted_fd = -1;
        char str_error[MAX_ERROR_LEN] = {'\0',};
-       _mm_sound_mgr_focus_socket_param_t read_data;
+       _mm_sound_focus_socket_param_t read_data;
+       _mm_sound_focus_socket_result_t result;
        int rval = 0;
-       char ret_buf[MAX_ERROR_LEN] = {'\0',};
 
        if (data == NULL) {
                debug_error("invalid data");
                pthread_exit(NULL);
        }
 
+       debug_fenter();
+
+       accepted_fd = (int)(data);
+
+       do {
+               memset(&read_data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+               if ((rval = read(accepted_fd, &read_data, sizeof(_mm_sound_focus_socket_param_t))) < 0) {
+                       strerror_r(errno, str_error, sizeof(str_error));
+                       debug_error("failed to read(), err: %s", str_error);
+
+               } else if (rval == sizeof(_mm_sound_focus_socket_param_t)) {
+                       int ret = MM_ERROR_NONE;
+
+                       debug_log("data read successfully, command[%s], pid[%d]",
+                                       read_data.func_name, read_data.pid);
+
+                       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+                       if ((ret = focus_functions_handler(accepted_fd, &read_data, &result)))
+                               debug_error("failed to focus_function_handler(), err[0x%x]", ret);
+                       result.ret = ret;
+
+                       /* send result */
+                       if (write(accepted_fd, &result, sizeof(_mm_sound_focus_socket_result_t)) < 0) {
+                               strerror_r(errno, str_error, sizeof(str_error));
+                               debug_error("failed to write(), err: %s", str_error);
+                       }
+
+                       if (need_to_exit(read_data.func_name))
+                               goto LEAVE;
+               } else {
+                       debug_error("failed to read(), read size mismatched, rval(%d), expect size(%d)",
+                                               rval, sizeof(_mm_sound_focus_socket_param_t));
+                       goto LEAVE;
+               }
+       } while (1);
+
+LEAVE:
+       debug_fleave();
+       debug_log("now close fd[%d]", accepted_fd);
+       /* clean-up FD and focus node */
+       mm_sound_mgr_focus_emergent_exit_by_id(accepted_fd);
+       close(accepted_fd);
+       pthread_exit(NULL);
+}
+
+static void* ready_thread_func(void *data)
+{
+       int fd = -1;
+       int accepted_fd = -1;
+       char str_error[MAX_ERROR_LEN] = {'\0',};
+       int ret = 0;
+       pthread_t focus_work_thread_id;
+       pthread_attr_t attr;
+
+       if (data == NULL) {
+               debug_error("invalid data");
+               pthread_exit(NULL);
+       }
+
+       debug_fenter();
+
+       ret = pthread_attr_init(&attr);
+       if (ret != 0) {
+               debug_error("failed to init pthread attr, errno=%d", ret);
+               goto LEAVE;
+       }
+
+       ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+       if (ret != 0) {
+               debug_error("failed to set detach state, errno=%d", ret);
+               goto LEAVE;
+       }
+
        fd = (int)data;
 
        if (listen(fd, 5)) {
@@ -167,33 +390,16 @@ static void *thread_func(void *data)
 
                debug_log("accepted fd [%d]", accepted_fd);
 
-               memset(&read_data, 0x00, sizeof(_mm_sound_mgr_focus_socket_param_t));
-               if ((rval = read(accepted_fd, &read_data, sizeof(_mm_sound_mgr_focus_socket_param_t))) < 0) {
-                       strerror_r(errno, str_error, sizeof(str_error));
-                       debug_error("failed to read(), err: %s", str_error);
-               } else if (rval == sizeof(_mm_sound_mgr_focus_socket_param_t)) {
-                       int ret = MM_ERROR_NONE;
-                       debug_log("data read successfully..");
-                       debug_log(" : pid[%d], handle_id[%d], focus_type[%d]", read_data.pid, read_data.handle_id, read_data.focus_type);
-                       debug_log(" : option[%d], ext_info[%s]", read_data.option, read_data.ext_info);
-
-                       if ((ret = focus_functions_handler(&read_data)))
-                               debug_log("failed to focus_function_handler(), err[0x%x]", ret);
-
-                       snprintf(ret_buf, sizeof(ret_buf), "%s", convert_error_string_from_int(ret));
-                       if (write(accepted_fd, ret_buf, sizeof(ret_buf)) < 0) {
-                               strerror_r(errno, str_error, sizeof(str_error));
-                               debug_error("failed to write(), err: %s", str_error);
-                       }
-               } else {
-                       debug_error("failed to read(), read size mismatched, rval(%d), expect size(%d)",
-                                               rval, sizeof(_mm_sound_mgr_focus_socket_param_t));
+               if (pthread_create(&focus_work_thread_id, &attr, (void *)work_thread_func, (void *)accepted_fd)) {
+                       debug_error("failed to create work thread, accepted_fd(%d)", accepted_fd);
+                       goto LEAVE;
                }
 
-               close(accepted_fd);
        } while (1);
 
 LEAVE:
+       debug_fleave();
+       pthread_attr_destroy(&attr);
        close(fd);
        pthread_exit(NULL);
 }
@@ -257,13 +463,13 @@ void MMSoundMgrFocusSocketFini(int fd)
 {
        debug_enter();
 
-       if (g_focus_work_thread_id) {
+       if (g_focus_ready_thread_id) {
                unlink(FOCUS_SERVER_SOCK);
                shutdown(fd, SHUT_RDWR);
                close(fd);
-               pthread_join(g_focus_work_thread_id, NULL);
+               pthread_join(g_focus_ready_thread_id, NULL);
                debug_msg("pthread join well");
-               g_focus_work_thread_id = 0;
+               g_focus_ready_thread_id = 0;
        }
 
        debug_leave();
@@ -279,8 +485,8 @@ int MMSoundMgrFocusSocketReadyToWork(int fd)
        }
 
        debug_log("fd [%d]", fd);
-       if (pthread_create(&g_focus_work_thread_id, NULL, (void *)thread_func, (void *)fd)) {
-               debug_error("failed to start work thread");
+       if (pthread_create(&g_focus_ready_thread_id, NULL, (void *)ready_thread_func, (void *)fd)) {
+               debug_error("failed to create ready thread");
                return MM_ERROR_SOUND_INTERNAL;
        }
 
index ffb2cfd..a38345a 100644 (file)
@@ -791,9 +791,6 @@ typedef enum {
        MM_SOUND_VOLUME_DEVICE_OUT_MULTIMEDIA_DOCK,             /**< Multimedia DOCK device */
 } mm_sound_volume_device_out_t;
 
-#define MM_SOUND_ROUTE_NUM 16
-#define MM_SOUND_NAME_NUM 32
-
 /*
  * MMSound Device APIs
  */
index 3055fc8..f5d7c0a 100644 (file)
 
 #include "mm_sound_private.h"
 #include "mm_sound_device.h"
-#ifdef USE_FOCUS
+
 #include "mm_sound_focus.h"
 typedef enum {
        IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB,
        IDLE_EVENT_TYPE_UNREGISTER_FOCUS,
        IDLE_EVENT_TYPE_MAX
 } focus_idle_event_type_e;
-#endif
 
 //#define MEMTYPE_TRANS_PER_MAX (1024 * 1024) /* 1MB */
 
@@ -57,10 +56,8 @@ int mm_sound_client_remove_device_state_changed_callback(unsigned int id);
 int mm_sound_client_add_device_running_changed_callback(int device_flags, mm_sound_device_running_changed_cb func, void *userdata, unsigned int *id);
 int mm_sound_client_remove_device_running_changed_callback(unsigned int id);
 int mm_sound_client_is_stream_on_device(int stream_id, int device_id, bool *is_on);
-#ifdef USE_FOCUS
-int mm_sound_client_get_unique_id(int *id);
 int mm_sound_client_is_focus_cb_thread(GThread *mine, bool *result);
-int mm_sound_client_register_focus(int id, int pid, const char *stream_type, mm_sound_focus_changed_cb callback, void* user_data);
+int mm_sound_client_register_focus(int pid, const char *stream_type, mm_sound_focus_changed_cb callback, void* user_data, int *id);
 int mm_sound_client_unregister_focus(int id);
 int mm_sound_client_set_focus_reacquisition(int id, bool reacquisition);
 int mm_sound_client_get_focus_reacquisition(int id, bool *reacquisition);
@@ -68,12 +65,11 @@ int mm_sound_client_get_acquired_focus_stream_type(int focus_type, char **stream
 int mm_sound_client_acquire_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info);
 int mm_sound_client_release_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info);
 int mm_sound_client_update_stream_focus_status(int id, unsigned int status);
-int mm_sound_client_deliver_focus(int pid, int src_id, int dst_id, mm_sound_focus_type_e focus_type);
+int mm_sound_client_deliver_focus(int src_id, int dst_id, mm_sound_focus_type_e focus_type);
 int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, void* user_data, int *id);
 int mm_sound_client_unset_focus_watch_callback(int id);
 int mm_sound_client_request_unset_focus_watch_callback(int id);
 int mm_sound_client_execute_focus_func_in_main_context(focus_idle_event_type_e type, int data);
-#endif
 
 int mm_sound_client_add_test_callback(mm_sound_test_cb func, void* user_data, unsigned int *subs_id);
 int mm_sound_client_remove_test_callback(unsigned int subs_id);
index ef977aa..4871e72 100644 (file)
@@ -28,6 +28,8 @@
 #define SOUND_SERVER_READY "/tmp/.sound_server_ready"
 #define FOCUS_SERVER_READY "/tmp/.focus_server_ready"
 
+#define MM_SOUND_NAME_NUM 32
+
 #define MMSOUND_ENTER_CRITICAL_SECTION(x_mutex) \
 switch (pthread_mutex_lock(x_mutex)) { \
 case EINVAL: \
index 94fcff1..d725233 100644 (file)
@@ -34,6 +34,8 @@
        extern "C" {
 #endif
 
+#include <stdbool.h>
+
 typedef enum {
        FOCUS_IS_RELEASED,
        FOCUS_IS_ACQUIRED,
@@ -46,11 +48,10 @@ typedef enum {
        FOCUS_FOR_BOTH,
 } mm_sound_focus_type_e;
 
-int mm_sound_focus_get_id(int *id);
 int mm_sound_focus_is_cb_thread(bool *result);
 
 typedef void (*mm_sound_focus_changed_cb) (int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, int option, const char *ext_info, void *user_data);
-int mm_sound_register_focus(int id, const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data);
+int mm_sound_register_focus(const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data, int *id);
 int mm_sound_unregister_focus(int id);
 int mm_sound_set_focus_reacquisition(int id, bool reacquisition);
 int mm_sound_get_focus_reacquisition(int id, bool *reacquisition);
diff --git a/include/mm_sound_focus_private.h b/include/mm_sound_focus_private.h
new file mode 100644 (file)
index 0000000..d84bb79
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MM_SOUND_FOCUS_PRIVATE_H__
+#define __MM_SOUND_FOCUS_PRIVATE_H__
+
+#include "mm_sound_common.h"
+#include "mm_sound_stream.h"
+#include "mm_sound_focus.h"
+
+#define FOCUS_HANDLE_MAX 512
+#define FOCUS_HANDLE_INIT_VAL -1
+
+typedef struct _FocusSource {
+       GSource source;
+       GPollFD poll_fd;
+} FocusSource;
+
+typedef struct {
+       int focus_pid;
+       int handle;
+       int client_fd;
+       int focus_fd;
+       FocusSource *fsrc;
+       bool is_used;
+       bool auto_reacquire;
+       GMutex focus_lock;
+       GThread *focus_cb_thread;
+       GMainLoop *focus_loop;
+       mm_sound_focus_changed_cb focus_callback;
+       mm_sound_focus_changed_watch_cb watch_callback;
+       void* user_data;
+       bool unset_watch_callback_requested;
+} focus_sound_info_t;
+
+typedef struct {
+       int pid;
+       int handle;
+       int type;
+       int state;
+       char stream_type[MAX_STREAM_TYPE_LEN];
+       char ext_info[MM_SOUND_NAME_NUM];
+       int option;
+} focus_cb_data_lib;
+
+typedef gboolean(*focus_callback_handler_t)(gpointer user_data);
+focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
+
+int focus_find_empty_index(int *handle);
+int focus_find_index_by_handle(int handle);
+int focus_watch_find_index_by_handle(int handle);
+
+int focus_init_context(int index);
+void focus_deinit_context(int index);
+void focus_init_callback(int index, bool is_for_watching);
+void focus_deinit_callback(int index, bool is_for_watching);
+
+#endif /* __MM_SOUND_FOCUS_PRIVATE_H__ */
index b3b258a..a105617 100644 (file)
@@ -26,7 +26,7 @@
        extern "C" {
 #endif
 
-#include "include/mm_sound.h"
+#include "include/mm_sound_common.h"
 #include "include/mm_sound_focus.h"
 
 #define FOCUS_SERVER_SOCK "/tmp/.focus_server.socket"
 
 typedef struct {
        char func_name[MM_SOUND_NAME_NUM];
-       int pid;
+       char stream_type[MM_SOUND_NAME_NUM];
        int handle_id;
+       int handle_id_dst;
+       int pid;
        mm_sound_focus_type_e focus_type;
        int option;
        char ext_info[MM_SOUND_NAME_NUM];
+       bool reacquisition;
        bool is_in_thread;                 /* Called within focus callback thread */
-} _mm_sound_mgr_focus_socket_param_t;
+} _mm_sound_focus_socket_param_t;
+
+typedef struct {
+       int ret;
+       int handle_id;
+       int option;
+       char stream_type[MM_SOUND_NAME_NUM];
+       char ext_info[MM_SOUND_NAME_NUM];
+} _mm_sound_focus_socket_result_t;
 
 /* Function names */
-#define FOCUS_FUNC_NAME_ACQUIRE          "AcquireFocus"
-#define FOCUS_FUNC_NAME_RELEASE          "ReleaseFocus"
+#define FOCUS_FUNC_NAME_REGISTER          "RegisterFocus"
+#define FOCUS_FUNC_NAME_UNREGISTER        "UnregisterFocus"
+#define FOCUS_FUNC_NAME_ADD_WATCH         "AddWatchFocus"
+#define FOCUS_FUNC_NAME_REMOVE_WATCH      "RemoveWatchFocus"
+#define FOCUS_FUNC_NAME_ACQUIRE           "AcquireFocus"
+#define FOCUS_FUNC_NAME_RELEASE           "ReleaseFocus"
+#define FOCUS_FUNC_NAME_SET_REACQUISITON  "SetFocusReacquisition"
+#define FOCUS_FUNC_NAME_DELIVER           "DeliverFocus"
+#define FOCUS_FUNC_NAME_GET_ACQUIRED_INFO "GetAcquiredFocusInfo"
 
 /* Error defines */
 #define FOCUS_ERROR_NONE                 "error_none"
@@ -53,8 +71,15 @@ typedef struct {
 #define FOCUS_ERROR_INTERNAL             "error_internal"
 #define FOCUS_ERROR_INVALID_STATE        "error_invalid_state"
 
-int mm_sound_focus_socket_acquire(int instance, int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread);
-int mm_sound_focus_socket_release(int instance, int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread);
+int mm_sound_focus_socket_register(int pid, const char *stream_type, int *client_fd, int *server_fd);
+int mm_sound_focus_socket_unregister(int pid, int client_fd, int server_fd);
+int mm_sound_focus_socket_add_watch_cb(int pid, mm_sound_focus_type_e focus_type, int *client_fd, int *server_fd);
+int mm_sound_focus_socket_remove_watch_cb(int pid, int client_fd, int server_fd);
+int mm_sound_focus_socket_acquire(int pid, int client_fd, int server_fd, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread);
+int mm_sound_focus_socket_release(int pid, int client_fd, int server_fd, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread);
+int mm_sound_focus_socket_set_reacquisition(int pid, int client_fd, int server_fd, bool reacquisition);
+int mm_sound_focus_socket_deliver(int pid, int src_client_fd, int src_server_fd, int dst_client_fd, int dst_server_fd, mm_sound_focus_type_e focus_type);
+int mm_sound_focus_socket_get_acquired_focus_stream_type(mm_sound_focus_type_e focus_type, char **stream_type, int *option, char **ext_info);
 
 #ifdef __cplusplus
 }
index 1ae0713..ab4a200 100644 (file)
@@ -56,17 +56,9 @@ typedef enum audio_method {
        AUDIO_METHOD_GET_AUDIO_PATH,
        AUDIO_METHOD_SET_VOLUME_LEVEL,
 
-       AUDIO_METHOD_GET_UNIQUE_ID,
-       AUDIO_METHOD_REGISTER_FOCUS,
-       AUDIO_METHOD_UNREGISTER_FOCUS,
-       AUDIO_METHOD_SET_FOCUS_REACQUISITION,
-       AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE,
        AUDIO_METHOD_ACQUIRE_FOCUS,
        AUDIO_METHOD_RELEASE_FOCUS,
        AUDIO_METHOD_UPDATE_STREAM_FOCUS_STATUS, /* It communicates with stream-manager to update focus status. */
-       AUDIO_METHOD_WATCH_FOCUS,
-       AUDIO_METHOD_UNWATCH_FOCUS,
-       AUDIO_METHOD_DELIVER_FOCUS,
 
        AUDIO_METHOD_SET_FILTER,
        AUDIO_METHOD_UNSET_FILTER,
@@ -84,7 +76,6 @@ typedef enum audio_event {
        AUDIO_EVENT_DEVICE_STATE_CHANGED,
        AUDIO_EVENT_FOCUS_CHANGED,
        AUDIO_EVENT_FOCUS_WATCH,
-       AUDIO_EVENT_EMERGENT_EXIT,
        AUDIO_EVENT_CLIENT_SUBSCRIBED, /* Clients send this signal when they subscribed some signal. */
        AUDIO_EVENT_CLIENT_HANDLED, /* Clients send this siganl when they handled some signal. */
        AUDIO_EVENT_DEVICE_RUNNING_CHANGED,
index 7cd9a86..f2352e6 100644 (file)
@@ -33,9 +33,7 @@
 
 #include "mm_sound_private.h"
 #include "mm_sound_device.h"
-#ifdef USE_FOCUS
 #include "mm_sound_focus.h"
-#endif
 #include "include/mm_sound_client.h"
 
 typedef void (*mm_sound_proxy_userdata_free) (void *data);
@@ -65,19 +63,16 @@ int mm_sound_proxy_set_filter_by_type(const char *stream_type, const char *filte
 int mm_sound_proxy_unset_filter_by_type(const char *stream_type);
 int mm_sound_proxy_control_filter_by_type(const char *stream_type, const char *filter_name, const char *filter_controls);
 
-#ifdef USE_FOCUS
-int mm_sound_proxy_get_unique_id(int *id);
-int mm_sound_proxy_register_focus(int id, int instance, const char *stream_type, mm_sound_focus_changed_cb callback, void* user_data);
-int mm_sound_proxy_unregister_focus(int instance, int id);
-int mm_sound_proxy_set_focus_reacquisition(int instance, int id, bool reacquisition);
+int mm_sound_proxy_register_focus(int pid, const char *stream_type, int *id);
+int mm_sound_proxy_unregister_focus(int index);
+int mm_sound_proxy_set_focus_reacquisition(int index, bool reacquisition);
 int mm_sound_proxy_get_acquired_focus_stream_type(int focus_type, char **stream_type, int *option, char **ext_info);
-int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info);
-int mm_sound_proxy_release_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info);
+int mm_sound_proxy_acquire_focus(int index, mm_sound_focus_type_e type, int option, const char *ext_info);
+int mm_sound_proxy_release_focus(int index, mm_sound_focus_type_e type, int option, const char *ext_info);
 int mm_sound_proxy_update_stream_focus_status(int focus_id, unsigned int status);
-int mm_sound_proxy_deliver_focus(int pid, int src_id, int dst_id, mm_sound_focus_type_e focus_type);
-int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, void *user_data);
-int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle);
-#endif
+int mm_sound_proxy_deliver_focus(int src_index, int dst_index, mm_sound_focus_type_e focus_type);
+int mm_sound_proxy_add_focus_watch_callback(int index, mm_sound_focus_type_e type);
+int mm_sound_proxy_remove_focus_watch_callback(int index);
 
 int mm_sound_proxy_add_test_callback(mm_sound_test_cb func, void *userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id);
 int mm_sound_proxy_remove_test_callback(unsigned subs_id);
index 701ca84..b732824 100644 (file)
  *
  */
 
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <poll.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
-#include <signal.h>
-
 #include <pthread.h>
-#include <semaphore.h>
-
+#include <glib.h>
 #include <mm_error.h>
 #include <mm_debug.h>
 
 #include "include/mm_sound_common.h"
 #include "include/mm_sound_device.h"
 #include "include/mm_sound_stream.h"
-
-#include <glib.h>
-#if defined(__GSOURCE_CALLBACK__)
-#include <sys/poll.h>
-#endif
+#include "include/mm_sound_focus_private.h"
 
 #define CLIENT_HANDLE_MAX 256
-
-#define FOCUS_HANDLE_MAX 512
-#define FOCUS_HANDLE_INIT_VAL -1
-#define CONFIG_ENABLE_RETCB
-
 #define VOLUME_TYPE_LEN 64
 
-struct sigaction system_int_old_action;
-struct sigaction system_abrt_old_action;
-struct sigaction system_segv_old_action;
-struct sigaction system_term_old_action;
-struct sigaction system_sys_old_action;
-struct sigaction system_xcpu_old_action;
+extern focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
 
 struct callback_data {
        void *user_cb;
@@ -69,11 +47,6 @@ struct callback_data {
        guint subs_id;
 };
 
-typedef struct _FocusSource {
-       GSource source;
-       GPollFD poll_fd;
-} FocusSource;
-
 #define GET_CB_DATA(_cb_data, _func, _userdata, _extradata) \
        do { \
                _cb_data = (struct callback_data*) g_malloc0(sizeof(struct callback_data)); \
@@ -82,42 +55,9 @@ typedef struct _FocusSource {
                _cb_data->extra_data = _extradata; \
        } while (0)
 
-#ifdef USE_FOCUS
-typedef struct {
-       int focus_tid;
-       int handle;
-       int focus_fd;
-       FocusSource *fsrc;
-       bool is_used;
-       bool auto_reacquire;
-       GMutex focus_lock;
-       GThread *focus_cb_thread;
-       GMainLoop *focus_loop;
-       mm_sound_focus_changed_cb focus_callback;
-       mm_sound_focus_changed_watch_cb watch_callback;
-       void* user_data;
-       bool unset_watch_callback_requested;
-} focus_sound_info_t;
-
-typedef struct {
-       int pid;
-       int handle;
-       int type;
-       int state;
-       char stream_type[MAX_STREAM_TYPE_LEN];
-       char ext_info[MM_SOUND_NAME_NUM];
-       int option;
-} focus_cb_data_lib;
-
-typedef gboolean(*focus_callback_handler_t)(gpointer user_data);
-
-focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
 static pthread_mutex_t g_index_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t g_event_mutex = PTHREAD_MUTEX_INITIALIZER;
 guint g_idle_event_src;
-#endif
-
-gboolean g_need_emergent_exit = FALSE;
 
 typedef struct {
        /* handle to watch end of playing */
@@ -131,129 +71,15 @@ typedef struct _focus_idle_event {
        int data;
 } focus_idle_event_t;
 
-void mm_sound_client_cleanup(void)
-{
-#ifndef TIZEN_TV
-       int ret = MM_ERROR_NONE;
-
-       if (g_need_emergent_exit) {
-               ret = mm_sound_proxy_emergent_exit(getpid());
-               if (ret == MM_ERROR_NONE)
-                       debug_msg("Success to emergent_exit");
-               else
-                       debug_error("Error occurred : 0x%x", ret);
-       }
-#else
-       if (g_need_emergent_exit)
-               mm_sound_proxy_emergent_exit(getpid());
-#endif
-}
-
-void _system_signal_handler(int signo, siginfo_t *siginfo, void *context)
-{
-       sigset_t old_mask, all_mask;
-
-#ifndef TIZEN_TV
-       debug_warning("Got signal : signo(%d)", signo);
-#endif
-
-       /* signal block */
-
-       sigfillset(&all_mask);
-       sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
-
-       mm_sound_client_cleanup();
-
-       sigprocmask(SIG_SETMASK, &old_mask, NULL);
-       /* signal unblock */
-
-       switch (signo) {
-       case SIGINT:
-               if (system_int_old_action.sa_sigaction)
-                       system_int_old_action.sa_sigaction(signo, siginfo, context);
-               else
-                       sigaction(signo, &system_int_old_action, NULL);
-               break;
-       case SIGABRT:
-               if (system_abrt_old_action.sa_sigaction)
-                       system_abrt_old_action.sa_sigaction(signo, siginfo, context);
-               else
-                       sigaction(signo, &system_abrt_old_action, NULL);
-               break;
-       case SIGSEGV:
-               if (system_segv_old_action.sa_sigaction)
-                       system_segv_old_action.sa_sigaction(signo, siginfo, context);
-               else
-                       sigaction(signo, &system_segv_old_action, NULL);
-               break;
-       case SIGTERM:
-               if (system_term_old_action.sa_sigaction)
-                       system_term_old_action.sa_sigaction(signo, siginfo, context);
-               else
-                       sigaction(signo, &system_term_old_action, NULL);
-               break;
-       case SIGSYS:
-               if (system_sys_old_action.sa_sigaction)
-                       system_sys_old_action.sa_sigaction(signo, siginfo, context);
-               else
-                       sigaction(signo, &system_sys_old_action, NULL);
-               break;
-       case SIGXCPU:
-               if (system_xcpu_old_action.sa_sigaction)
-                       system_xcpu_old_action.sa_sigaction(signo, siginfo, context);
-               else
-                       sigaction(signo, &system_xcpu_old_action, NULL);
-               break;
-       default:
-               break;
-       }
-
-#ifndef TIZEN_TV
-       debug_warning("signal handling end");
-#endif
-}
-
-#ifdef TIZEN_TV
-static bool _is_dotnet_app(void)
-{
-       char *is_dotnet = NULL;
-
-       is_dotnet = getenv("DOTNET_APP");
-       if (is_dotnet && atoi(is_dotnet) == 1)
-               return true;
-       else
-               return false;
-}
-#endif
-
 int mm_sound_client_initialize(void)
 {
        int ret = MM_ERROR_NONE;
-       struct sigaction system_action;
 
        debug_fenter();
 
        mm_sound_proxy_initialize();
        g_idle_event_src = 0;
 
-#ifdef TIZEN_TV
-       if (_is_dotnet_app()) {
-               debug_warning("no signal handler for dotnet!!");
-               return ret;
-       }
-#endif
-       system_action.sa_sigaction = _system_signal_handler;
-       system_action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
-
-       sigemptyset(&system_action.sa_mask);
-
-       sigaction(SIGINT, &system_action, &system_int_old_action);
-       sigaction(SIGABRT, &system_action, &system_abrt_old_action);
-       sigaction(SIGSEGV, &system_action, &system_segv_old_action);
-       sigaction(SIGTERM, &system_action, &system_term_old_action);
-       sigaction(SIGSYS, &system_action, &system_sys_old_action);
-       sigaction(SIGXCPU, &system_action, &system_xcpu_old_action);
-
        debug_fleave();
        return ret;
 }
@@ -264,31 +90,13 @@ int mm_sound_client_finalize(void)
 
        debug_fenter();
 
-       mm_sound_client_cleanup();
-
        ret = mm_sound_proxy_finalize();
 
-#ifdef USE_FOCUS
        if (g_idle_event_src > 0) {
                MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_event_mutex, MM_ERROR_SOUND_INTERNAL);
                g_source_remove(g_idle_event_src);
                MMSOUND_LEAVE_CRITICAL_SECTION(&g_event_mutex);
        }
-#endif
-
-#ifdef TIZEN_TV
-       if (_is_dotnet_app()) {
-               debug_warning("no signal handler for dotnet!!");
-               return ret;
-       }
-#endif
-
-       sigaction(SIGINT, &system_int_old_action, NULL);
-       sigaction(SIGABRT, &system_abrt_old_action, NULL);
-       sigaction(SIGSEGV, &system_segv_old_action, NULL);
-       sigaction(SIGTERM, &system_term_old_action, NULL);
-       sigaction(SIGSYS, &system_sys_old_action, NULL);
-       sigaction(SIGXCPU, &system_xcpu_old_action, NULL);
 
        debug_fleave();
        return ret;
@@ -630,8 +438,6 @@ int mm_sound_client_add_device_connected_callback(int device_flags, mm_sound_dev
 
        ret = mm_sound_proxy_add_device_connected_callback(_mm_sound_device_connected_callback_wrapper_func,
                                                                                                        cb_data, g_free, subs_id);
-       if (ret == MM_ERROR_NONE)
-               g_need_emergent_exit = TRUE;
 
        debug_fleave();
        return ret;
@@ -1021,605 +827,6 @@ int mm_sound_client_control_filter_by_type(const char *stream_type, const char *
        return ret;
 }
 
-#ifdef USE_FOCUS
-static gpointer _focus_thread_func(gpointer data)
-{
-       unsigned int thread_id = (unsigned int)pthread_self();
-       GMainLoop *focus_loop = (GMainLoop*)data;
-
-       debug_warning(">>> thread id(%u), mainloop[%p]", thread_id, focus_loop);
-       if (focus_loop)
-               g_main_loop_run(focus_loop);
-       debug_warning("<<< quit : thread id(%u), mainloop[%p]", thread_id, focus_loop);
-
-       return NULL;
-}
-
-static gboolean _focus_fd_prepare(GSource *source, gint *timeout)
-{
-#ifdef __DEBUG__
-       debug_warning("[ PREPARE : %p, (%p, %d)", source, timeout, timeout ? *timeout : -1);
-#endif
-       return FALSE;
-}
-
-static gboolean _focus_fd_check(GSource * source)
-{
-       FocusSource* fsource = (FocusSource *)source;
-
-       if (!fsource) {
-               debug_error("GSource is null");
-               return FALSE;
-       }
-#ifdef __DEBUG__
-       debug_warning("CHECK : %p, 0x%x ]", source, fsource->pollfd.revents);
-#endif
-       if (fsource->poll_fd.revents & (POLLIN | POLLPRI))
-               return TRUE;
-       else
-               return FALSE;
-}
-
-static gboolean _focus_fd_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
-{
-       debug_warning("*** DISPATCH : %p, (%p, %p)", source, callback, user_data);
-       return callback(user_data);
-}
-
-static void _focus_fd_finalize(GSource *source)
-{
-       debug_warning("### FINALIZE : %p", source);
-}
-
-static int _focus_find_index_by_handle(int handle)
-{
-       int i = 0;
-       for (i = 0; i < FOCUS_HANDLE_MAX; i++) {
-               if (g_focus_sound_handle[i].focus_callback && handle == g_focus_sound_handle[i].handle) {
-                       /* debug_msg("found index(%d) for handle(%d)", i, handle);*/
-                       return (handle == FOCUS_HANDLE_INIT_VAL) ? -1 : i;
-               }
-       }
-       return -1;
-}
-
-static int _focus_watch_find_index_by_handle(int handle)
-{
-       int i = 0;
-       for (i = 0; i < FOCUS_HANDLE_MAX; i++) {
-               if (g_focus_sound_handle[i].watch_callback && handle == g_focus_sound_handle[i].handle) {
-                       /* debug_msg("found index(%d) for watch handle(%d)", i, handle);*/
-                       return (handle == FOCUS_HANDLE_INIT_VAL) ? -1 : i;
-               }
-       }
-       return -1;
-}
-
-static gboolean _focus_callback_handler(gpointer user_data)
-{
-       focus_sound_info_t *focus_handle = (focus_sound_info_t *)user_data;
-       GPollFD *poll_fd;
-       int count;
-       int tid = 0;
-       focus_cb_data_lib cb_data;
-
-       debug_log(">>> thread id(%u)", (unsigned int)pthread_self());
-
-       if (!focus_handle) {
-               debug_error("focus_handle is null");
-               return G_SOURCE_CONTINUE;
-       }
-       poll_fd = &focus_handle->fsrc->poll_fd;
-       debug_log("focus_handle(%p), poll_fd(%p)", focus_handle, poll_fd);
-
-       memset(&cb_data, 0, sizeof(focus_cb_data_lib));
-
-       if (poll_fd->revents & (POLLIN | POLLPRI)) {
-               int changed_state = -1;
-
-               count = read(poll_fd->fd, &cb_data, sizeof(cb_data));
-               if (count < 0) {
-                       char str_error[256];
-                       strerror_r(errno, str_error, sizeof(str_error));
-                       debug_error("GpollFD read fail, errno=%d(%s)", errno, str_error);
-                       return G_SOURCE_CONTINUE;
-               }
-               changed_state = cb_data.state;
-
-               g_mutex_lock(&focus_handle->focus_lock);
-
-               tid = focus_handle->focus_tid;
-
-               if (changed_state != -1) {
-                       debug_msg("Got and start CB : TID(%d), handle(%d), type(%d), state(%d,(DEACTIVATED(0)/ACTIVATED(1)), trigger(%s)",
-                                       tid, cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type);
-                       if (focus_handle->focus_callback == NULL) {
-                                       debug_error("focus callback is null..");
-                                       g_mutex_unlock(&focus_handle->focus_lock);
-                                       return G_SOURCE_CONTINUE;
-                       }
-                       debug_msg("[CALLBACK(%p) START]", focus_handle->focus_callback);
-                       (focus_handle->focus_callback)(cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type,
-                                                                               cb_data.option, cb_data.ext_info, focus_handle->user_data);
-                       debug_msg("[CALLBACK END]");
-               }
-#ifdef CONFIG_ENABLE_RETCB
-               {
-                       int rett = 0;
-                       int tmpfd = -1;
-                       unsigned int buf = 0;
-                       char *filename2 = g_strdup_printf("/tmp/FOCUS.%d.%dr", focus_handle->focus_tid, cb_data.handle);
-                       tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
-                       if (tmpfd < 0) {
-                               char str_error[256];
-                               strerror_r(errno, str_error, sizeof(str_error));
-                               debug_warning("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)",
-                                                       tid, tmpfd, filename2, errno, str_error);
-                               g_free(filename2);
-                               g_mutex_unlock(&focus_handle->focus_lock);
-                               return G_SOURCE_CONTINUE;
-                       }
-                       /* buf contains data as below,
-                        * |<--12bits--><--4bits (reacquisition)--><--16bits (handle)-->| */
-                       buf = (unsigned int)((0x0000ffff & cb_data.handle) | (focus_handle->auto_reacquire << 16));
-                       rett = write(tmpfd, &buf, sizeof(buf));
-                       close(tmpfd);
-                       g_free(filename2);
-                       debug_msg("[RETCB] tid(%d) finishing CB (write=%d)", tid, rett);
-               }
-#endif
-       }
-
-       g_mutex_unlock(&focus_handle->focus_lock);
-
-       debug_fleave();
-
-       return G_SOURCE_CONTINUE;
-}
-
-static gboolean _focus_watch_callback_handler(gpointer user_data)
-{
-       focus_sound_info_t *focus_handle = (focus_sound_info_t *)user_data;
-       GPollFD *poll_fd;
-       int count;
-       int tid = 0;
-       focus_cb_data_lib cb_data;
-
-       debug_log(">>> thread id(%u)", (unsigned int)pthread_self());
-
-       if (!focus_handle) {
-               debug_error("focus_handle is null");
-               return G_SOURCE_CONTINUE;
-       }
-       poll_fd = &focus_handle->fsrc->poll_fd;
-       debug_log("focus_handle(%p), poll_fd(%p)", focus_handle, poll_fd);
-
-       memset(&cb_data, 0, sizeof(focus_cb_data_lib));
-
-       if (poll_fd->revents & (POLLIN | POLLPRI)) {
-               count = read(poll_fd->fd, &cb_data, sizeof(cb_data));
-               if (count < 0) {
-                       char str_error[256];
-                       strerror_r(errno, str_error, sizeof(str_error));
-                       debug_error("GpollFD read fail, errno=%d(%s)", errno, str_error);
-                       return G_SOURCE_CONTINUE;
-               }
-
-               if (!focus_handle->is_used) {
-                       debug_warning("unsetting watch calllback has been already requested");
-                       goto SKIP_CB_AND_RET;
-               }
-
-               g_mutex_lock(&focus_handle->focus_lock);
-
-               tid = focus_handle->focus_tid;
-
-               debug_msg("Got and start CB : TID(%d), handle(%d), type(%d), state(%d,(DEACTIVATED(0)/ACTIVATED(1)), trigger(%s)",
-                               tid, cb_data.handle,  cb_data.type, cb_data.state, cb_data.stream_type);
-
-               if (focus_handle->watch_callback == NULL) {
-                       debug_warning("watch callback is null..");
-                       goto SKIP_CB_AND_RET;
-               }
-               if (focus_handle->unset_watch_callback_requested == true) {
-                       debug_warning("unset_watch_callback_requested..");
-                       goto SKIP_CB_AND_RET;
-               }
-
-               debug_msg("[CALLBACK(%p) START]", focus_handle->watch_callback);
-               (focus_handle->watch_callback)(cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type,
-                                                                       cb_data.ext_info, focus_handle->user_data);
-               debug_msg("[CALLBACK END]");
-
-SKIP_CB_AND_RET:
-#ifdef CONFIG_ENABLE_RETCB
-               {
-                       int rett = 0;
-                       int tmpfd = -1;
-                       int buf = -1;
-                       char *filename2 = g_strdup_printf("/tmp/FOCUS.%d.%d.wchr", focus_handle->focus_tid, cb_data.handle);
-                       tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
-                       if (tmpfd < 0) {
-                               char str_error[256];
-                               strerror_r(errno, str_error, sizeof(str_error));
-                               debug_warning("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)",
-                                                       tid, tmpfd, filename2, errno, str_error);
-                               g_free(filename2);
-                               g_mutex_unlock(&focus_handle->focus_lock);
-                               return G_SOURCE_CONTINUE;
-                       }
-                       buf = cb_data.handle;
-                       rett = write(tmpfd, &buf, sizeof(buf));
-                       close(tmpfd);
-                       g_free(filename2);
-                       debug_msg("[RETCB] tid(%d) finishing CB (write=%d)", tid, rett);
-               }
-#endif
-       }
-
-       if (focus_handle->is_used) {
-               debug_msg("unlock focus_lock = %p", &focus_handle->focus_lock);
-               g_mutex_unlock(&focus_handle->focus_lock);
-       }
-
-       debug_fleave();
-
-       return G_SOURCE_CONTINUE;
-}
-
-static void _focus_open_callback(int index, bool is_for_watching)
-{
-       mode_t pre_mask;
-       char *filename;
-
-       debug_fenter();
-
-       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
-               debug_error("Invalid focus handle index [%d]", index);
-               return;
-       }
-
-       if (is_for_watching) {
-               filename = g_strdup_printf("/tmp/FOCUS.%d.%d.wch",
-                                                               g_focus_sound_handle[index].focus_tid,
-                                                               g_focus_sound_handle[index].handle);
-       } else {
-               filename = g_strdup_printf("/tmp/FOCUS.%d.%d",
-                                                               g_focus_sound_handle[index].focus_tid,
-                                                               g_focus_sound_handle[index].handle);
-       }
-       pre_mask = umask(0);
-       if (mknod(filename, S_IFIFO|0666, 0))
-               debug_error("mknod() failure, errno(%d)", errno);
-       umask(pre_mask);
-       g_focus_sound_handle[index].focus_fd = open(filename, O_RDWR|O_NONBLOCK);
-       if (g_focus_sound_handle[index].focus_fd == -1) {
-               debug_error("Open fail : index(%d), file open error(%d)", index, errno);
-       } else {
-               debug_log("Open success : index(%d), filename(%s), fd(%d)",
-                               index, filename, g_focus_sound_handle[index].focus_fd);
-       }
-       g_free(filename);
-       filename = NULL;
-
-#ifdef CONFIG_ENABLE_RETCB
-       char *filename2;
-
-       if (is_for_watching) {
-               filename2 = g_strdup_printf("/tmp/FOCUS.%d.%d.wchr",
-                                                                       g_focus_sound_handle[index].focus_tid,
-                                                                       g_focus_sound_handle[index].handle);
-       } else {
-               filename2 = g_strdup_printf("/tmp/FOCUS.%d.%dr",
-                                                                       g_focus_sound_handle[index].focus_tid,
-                                                                       g_focus_sound_handle[index].handle);
-       }
-       pre_mask = umask(0);
-       if (mknod(filename2, S_IFIFO | 0666, 0))
-               debug_error("mknod() failure, errno(%d)", errno);
-       umask(pre_mask);
-       g_free(filename2);
-       filename2 = NULL;
-#endif
-       debug_fleave();
-
-}
-
-void _focus_close_callback(int index, bool is_for_watching)
-{
-       char *filename = NULL;
-
-       debug_fenter();
-
-       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
-               debug_error("Invalid focus handle index [%d]", index);
-               return;
-       }
-
-       if (g_focus_sound_handle[index].focus_fd < 0) {
-               debug_error("Close fail : index(%d)", index);
-       } else {
-               close(g_focus_sound_handle[index].focus_fd);
-               debug_log("Close Success : index(%d)", index);
-       }
-
-       if (is_for_watching) {
-               filename = g_strdup_printf("/tmp/FOCUS.%d.%d.wch",
-                                                               g_focus_sound_handle[index].focus_tid,
-                                                               g_focus_sound_handle[index].handle);
-       } else {
-               filename = g_strdup_printf("/tmp/FOCUS.%d.%d",
-                                                               g_focus_sound_handle[index].focus_tid,
-                                                               g_focus_sound_handle[index].handle);
-       }
-       if (remove(filename)) {
-               debug_warning("remove(%s) failure (focus_server probably removed it in advance), errno(%d)",
-                                       filename, errno);
-       }
-       g_free(filename);
-       filename = NULL;
-
-#ifdef CONFIG_ENABLE_RETCB
-       char *filename2;
-
-       if (is_for_watching) {
-               filename2 = g_strdup_printf("/tmp/FOCUS.%d.%d.wchr",
-                                                                       g_focus_sound_handle[index].focus_tid,
-                                                                       g_focus_sound_handle[index].handle);
-       } else {
-               filename2 = g_strdup_printf("/tmp/FOCUS.%d.%dr",
-                                                                       g_focus_sound_handle[index].focus_tid,
-                                                                       g_focus_sound_handle[index].handle);
-       }
-       if (remove(filename2)) {
-               debug_warning("remove(%s) failure (focus_server probably removed it in advance), errno(%d)",
-                                       filename2, errno);
-       }
-       g_free(filename2);
-       filename2 = NULL;
-
-       debug_fleave();
-#endif
-
-}
-
-static GSourceFuncs event_funcs = {
-       .prepare = _focus_fd_prepare,
-       .check = _focus_fd_check,
-       .dispatch = _focus_fd_dispatch,
-       .finalize = _focus_fd_finalize,
-};
-
-static bool _focus_add_sound_callback(int index, focus_callback_handler_t focus_cb_handler)
-{
-       FocusSource *fsrc = NULL;
-       GSource *src = NULL;
-       guint fsrc_id = 0;
-
-       debug_fenter();
-
-       g_mutex_init(&g_focus_sound_handle[index].focus_lock);
-
-       src = g_source_new(&event_funcs, sizeof(FocusSource));
-       if (!src) {
-               debug_error("failed to g_source_new for focus source");
-               goto ERROR;
-       }
-
-       fsrc = (FocusSource*) src;
-
-       fsrc->poll_fd.fd = g_focus_sound_handle[index].focus_fd;
-       fsrc->poll_fd.events = (gushort)(POLLIN | POLLPRI);
-       g_source_add_poll(src, &fsrc->poll_fd);
-
-       g_source_set_callback(src, focus_cb_handler, (gpointer)&g_focus_sound_handle[index], NULL);
-
-       debug_warning("fsrc(%p), src_funcs(%p), pollfd(%p), fd(%d)",
-                               fsrc, &event_funcs, &fsrc->poll_fd, fsrc->poll_fd.fd);
-
-       fsrc_id = g_source_attach(src, g_main_loop_get_context(g_focus_sound_handle[index].focus_loop));
-       if (!fsrc_id) {
-               debug_error("failed to attach the source to context");
-               goto ERROR;
-       }
-       g_source_unref(src);
-
-       g_focus_sound_handle[index].fsrc = fsrc;
-
-       debug_fleave();
-       return true;
-
-ERROR:
-       if (src)
-               g_source_unref(src);
-
-       return false;
-}
-
-static bool _focus_remove_sound_callback(int index)
-{
-       focus_sound_info_t *h = NULL;
-
-       debug_fenter();
-
-       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
-               debug_error("Invalid focus handle index [%d]", index);
-               return false;
-       }
-
-       h = &g_focus_sound_handle[index];
-       if (h->fsrc) {
-               g_source_destroy((GSource *)h->fsrc);
-               h->fsrc = NULL;
-       }
-
-       h->focus_callback = NULL;
-       h->watch_callback = NULL;
-
-       g_mutex_clear(&h->focus_lock);
-
-       debug_fleave();
-
-       return true;
-}
-
-static void _focus_add_callback(int index, bool is_for_watching)
-{
-       debug_fenter();
-
-       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
-               debug_error("Invalid focus handle index [%d]", index);
-               return;
-       }
-
-       if (!is_for_watching) {
-               if (!_focus_add_sound_callback(index, _focus_callback_handler))
-                       debug_error("failed to _focus_add_sound_callback(%p)", _focus_callback_handler);
-       } else {
-               if (!_focus_add_sound_callback(index, _focus_watch_callback_handler))
-                       debug_error("failed to _focus_add_sound_callback(%p)", _focus_watch_callback_handler);
-       }
-       debug_fleave();
-}
-
-static void _focus_remove_callback(int index)
-{
-       debug_fenter();
-       if (!_focus_remove_sound_callback(index))
-               debug_error("failed to __focus_remove_sound_callback()");
-       debug_fleave();
-}
-
-static void _focus_init_callback(int index, bool is_for_watching)
-{
-       debug_fenter();
-       _focus_open_callback(index, is_for_watching);
-       _focus_add_callback(index, is_for_watching);
-       debug_fleave();
-}
-
-static void _focus_deinit_callback(int index, bool is_for_watching)
-{
-       debug_fenter();
-       _focus_remove_callback(index);
-       _focus_close_callback(index, is_for_watching);
-       debug_fleave();
-}
-
-#define INTERVAL_MS 20
-static int _focus_loop_is_running_timed_wait(GMainLoop *focus_loop, int timeout_ms)
-{
-       int reduced_time_ms = timeout_ms;
-       if (!focus_loop || timeout_ms < 0) {
-               debug_error("invalid argument, focus_loop(%p), timeout_ms(%d)", focus_loop, timeout_ms);
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
-
-       do {
-               if (g_main_loop_is_running(focus_loop))
-                       return MM_ERROR_NONE;
-
-               usleep(INTERVAL_MS * 1000);
-               if (reduced_time_ms < timeout_ms)
-                       debug_warning("reduced_time_ms(%d)", reduced_time_ms);
-       } while ((reduced_time_ms -= INTERVAL_MS) >= 0);
-
-       debug_error("focus_loop is not running for timeout_ms(%d), focus_loop(%p) ", timeout_ms, focus_loop);
-
-       return MM_ERROR_SOUND_INTERNAL;
-}
-
-#define LOOP_RUNNING_WAIT_TIME_MS 5000
-static int _focus_init_context(int index)
-{
-       int ret = MM_ERROR_NONE;
-       GMainContext *focus_context;
-
-       debug_fenter();
-
-       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
-               debug_error("index(%d) is not valid", index);
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
-
-       focus_context = g_main_context_new();
-       g_focus_sound_handle[index].focus_loop = g_main_loop_new(focus_context, FALSE);
-       g_main_context_unref(focus_context);
-       if (g_focus_sound_handle[index].focus_loop == NULL) {
-               debug_error("could not create mainloop..");
-               goto ERROR;
-       }
-
-       g_focus_sound_handle[index].focus_cb_thread = g_thread_new("focus-cb-thread",
-                                                                       _focus_thread_func,
-                                                                       g_focus_sound_handle[index].focus_loop);
-       if (g_focus_sound_handle[index].focus_cb_thread == NULL) {
-               debug_error("could not create thread..");
-               goto ERROR;
-       }
-
-       debug_warning("focus cb thread[%p] with mainloop[%p] is created for index(%d)",
-                               g_focus_sound_handle[index].focus_cb_thread, g_focus_sound_handle[index].focus_loop, index);
-
-       if ((ret = _focus_loop_is_running_timed_wait(g_focus_sound_handle[index].focus_loop, LOOP_RUNNING_WAIT_TIME_MS))) {
-               debug_error("failed to _focus_loop_is_running_timed_wait(), ret[0x%x]", ret);
-               goto ERROR;
-       }
-
-       debug_fleave();
-
-       return MM_ERROR_NONE;
-
-ERROR:
-       if (g_focus_sound_handle[index].focus_loop) {
-               g_main_loop_unref(g_focus_sound_handle[index].focus_loop);
-               g_focus_sound_handle[index].focus_loop = NULL;
-       }
-       return MM_ERROR_SOUND_INTERNAL;
-}
-
-static void _focus_deinit_context(int index)
-{
-       debug_fenter();
-
-       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
-               debug_error("index(%d) is not valid", index);
-               return;
-       }
-
-       if (!g_focus_sound_handle[index].focus_loop || !g_focus_sound_handle[index].focus_cb_thread) {
-               debug_error("focus_loop[%p] or focus_cb_thread[%p] is null",
-                               g_focus_sound_handle[index].focus_loop, g_focus_sound_handle[index].focus_cb_thread);
-               return;
-       }
-
-       g_main_loop_quit(g_focus_sound_handle[index].focus_loop);
-       g_thread_join(g_focus_sound_handle[index].focus_cb_thread);
-       debug_warning("after thread join, thread[%p], mainloop[%p] for index(%d)",
-                       g_focus_sound_handle[index].focus_cb_thread, g_focus_sound_handle[index].focus_loop, index);
-       g_main_loop_unref(g_focus_sound_handle[index].focus_loop);
-       g_focus_sound_handle[index].focus_loop = NULL;
-       g_focus_sound_handle[index].focus_cb_thread = NULL;
-
-       debug_fleave();
-}
-
-int mm_sound_client_get_unique_id(int *id)
-{
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       if (!id)
-               ret = MM_ERROR_INVALID_ARGUMENT;
-       else
-               ret = mm_sound_proxy_get_unique_id(id);
-
-       debug_fleave();
-
-       return ret;
-}
-
 int mm_sound_client_is_focus_cb_thread(GThread *mine, bool *result)
 {
        int ret = MM_ERROR_NONE;
@@ -1642,36 +849,29 @@ int mm_sound_client_is_focus_cb_thread(GThread *mine, bool *result)
        return ret;
 }
 
-int mm_sound_client_register_focus(int id, int pid, const char *stream_type,
-                                                               mm_sound_focus_changed_cb callback, void* user_data)
+int mm_sound_client_register_focus(int pid, const char *stream_type,
+                                                               mm_sound_focus_changed_cb callback, void* user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
-       int instance;
-       int index = 0;
+       int index = -1;
 
        debug_fenter();
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       instance = pid;
-
-       for (index = 0; index < FOCUS_HANDLE_MAX - 1; index++) {
-               if (g_focus_sound_handle[index].is_used == false) {
-                       g_focus_sound_handle[index].is_used = true;
-                       break;
-               }
+       if (focus_find_empty_index(&index)) {
+               ret = MM_ERROR_SOUND_INTERNAL;
+               goto cleanup;
        }
 
-       g_focus_sound_handle[index].focus_tid = instance;
-       g_focus_sound_handle[index].handle = id;
+       g_focus_sound_handle[index].focus_pid = pid;
        g_focus_sound_handle[index].focus_callback = callback;
        g_focus_sound_handle[index].user_data = user_data;
        g_focus_sound_handle[index].auto_reacquire = true;
 
-       ret = mm_sound_proxy_register_focus(id, pid, stream_type, callback, user_data);
+       ret = mm_sound_proxy_register_focus(index, stream_type, id);
        if (ret == MM_ERROR_NONE) {
-               debug_msg("Success to register focus");
-               g_need_emergent_exit = TRUE;
-               if (_focus_init_context(index)) {
+               debug_msg("Success to register focus, client_fd[%d], id[%d]", g_focus_sound_handle[index].client_fd, *id);
+               if (focus_init_context(index)) {
                        ret = MM_ERROR_SOUND_INTERNAL;
                        goto cleanup;
                }
@@ -1680,7 +880,7 @@ int mm_sound_client_register_focus(int id, int pid, const char *stream_type,
                goto cleanup;
        }
 
-       _focus_init_callback(index, false);
+       focus_init_callback(index, false);
 
 cleanup:
        if (ret)
@@ -1695,19 +895,17 @@ cleanup:
 int mm_sound_client_unregister_focus(int id)
 {
        int ret = MM_ERROR_NONE;
-       int instance;
        int index = -1;
 
        debug_fenter();
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       index = _focus_find_index_by_handle(id);
+       index = focus_find_index_by_handle(id);
        if (index == -1) {
                debug_error("Could not find index");
                ret = MM_ERROR_INVALID_ARGUMENT;
                goto cleanup;
        }
-       instance = g_focus_sound_handle[index].focus_tid;
 
        if (!g_mutex_trylock(&g_focus_sound_handle[index].focus_lock)) {
                debug_warning("maybe focus_callback is being called, try one more time..");
@@ -1716,7 +914,7 @@ int mm_sound_client_unregister_focus(int id)
                        debug_msg("finally got focus_lock");
        }
 
-       ret = mm_sound_proxy_unregister_focus(instance, id);
+       ret = mm_sound_proxy_unregister_focus(index);
        if (ret == MM_ERROR_NONE)
                debug_msg("Success to unregister focus");
        else
@@ -1724,13 +922,13 @@ int mm_sound_client_unregister_focus(int id)
 
        g_mutex_unlock(&g_focus_sound_handle[index].focus_lock);
 
-       _focus_deinit_callback(index, false);
+       focus_deinit_callback(index, false);
        g_focus_sound_handle[index].focus_fd = 0;
-       g_focus_sound_handle[index].focus_tid = 0;
+       g_focus_sound_handle[index].focus_pid = 0;
+       g_focus_sound_handle[index].client_fd = 0;
        g_focus_sound_handle[index].handle = 0;
        g_focus_sound_handle[index].is_used = false;
-       _focus_deinit_context(index);
-
+       focus_deinit_context(index);
 
 cleanup:
        MMSOUND_LEAVE_CRITICAL_SECTION(&g_index_mutex);
@@ -1741,7 +939,6 @@ cleanup:
 int mm_sound_client_set_focus_reacquisition(int id, bool reacquisition)
 {
        int ret = MM_ERROR_NONE;
-       int instance;
        int index = -1;
        bool result;
 
@@ -1749,20 +946,19 @@ int mm_sound_client_set_focus_reacquisition(int id, bool reacquisition)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       index = _focus_find_index_by_handle(id);
+       index = focus_find_index_by_handle(id);
        if (index == -1) {
                debug_error("Could not find index");
                ret = MM_ERROR_INVALID_ARGUMENT;
                goto cleanup;
        }
-       instance = g_focus_sound_handle[index].focus_tid;
 
        ret = mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
        if (ret) {
                debug_error("mm_sound_client_is_focus_cb_thread failed");
                goto cleanup;
        } else if (!result) {
-               ret = mm_sound_proxy_set_focus_reacquisition(instance, id, reacquisition);
+               ret = mm_sound_proxy_set_focus_reacquisition(index, reacquisition);
                if (ret == MM_ERROR_NONE) {
                        debug_msg("Success to set focus reacquisition to [%d]", reacquisition);
                } else {
@@ -1796,7 +992,7 @@ int mm_sound_client_get_focus_reacquisition(int id, bool *reacquisition)
 
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       index = _focus_find_index_by_handle(id);
+       index = focus_find_index_by_handle(id);
        if (index == -1) {
                debug_error("Could not find index");
                ret = MM_ERROR_INVALID_ARGUMENT;
@@ -1815,45 +1011,37 @@ cleanup:
 int mm_sound_client_get_acquired_focus_stream_type(int focus_type, char **stream_type, int *option, char **ext_info)
 {
        int ret = MM_ERROR_NONE;
-       char *stream_type_str = NULL;
-       char *ext_info_str = NULL;
 
        debug_fenter();
 
-       ret = mm_sound_proxy_get_acquired_focus_stream_type(focus_type, &stream_type_str, option, &ext_info_str);
-       if (ret == MM_ERROR_NONE) {
+       ret = mm_sound_proxy_get_acquired_focus_stream_type(focus_type, stream_type, option, ext_info);
+       if (ret == MM_ERROR_NONE)
                debug_msg("Success to get stream type of acquired focus, stream_type(%s), ext_info(%s)",
-                               stream_type_str, ext_info_str);
-               *stream_type = strdup(stream_type_str);
-               *ext_info = strdup(ext_info_str);
-               g_free(stream_type_str);
-               g_free(ext_info_str);
-       } else {
+                               *stream_type, *ext_info);
+       else
                debug_error("Error occurred : 0x%x", ret);
-       }
 
        debug_fleave();
+
        return ret;
 }
 
 int mm_sound_client_acquire_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
-       int instance;
        int index = -1;
 
        debug_fenter();
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       index = _focus_find_index_by_handle(id);
+       index = focus_find_index_by_handle(id);
        if (index == -1) {
                debug_error("Could not find index");
                ret = MM_ERROR_INVALID_ARGUMENT;
                goto cleanup;
        }
-       instance = g_focus_sound_handle[index].focus_tid;
 
-       ret = mm_sound_proxy_acquire_focus(instance, id, type, option, ext_info);
+       ret = mm_sound_proxy_acquire_focus(index, type, option, ext_info);
        if (ret == MM_ERROR_NONE)
                debug_msg("Success to acquire focus");
        else
@@ -1868,21 +1056,19 @@ cleanup:
 int mm_sound_client_release_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
-       int instance;
        int index = -1;
 
        debug_fenter();
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       index = _focus_find_index_by_handle(id);
+       index = focus_find_index_by_handle(id);
        if (index == -1) {
                debug_error("Could not find index");
                ret = MM_ERROR_INVALID_ARGUMENT;
                goto cleanup;
        }
-       instance = g_focus_sound_handle[index].focus_tid;
 
-       ret = mm_sound_proxy_release_focus(instance, id, type, option, ext_info);
+       ret = mm_sound_proxy_release_focus(index, type, option, ext_info);
        if (ret == MM_ERROR_NONE)
                debug_msg("Success to release focus");
        else
@@ -1906,14 +1092,41 @@ int mm_sound_client_update_stream_focus_status(int id, unsigned int status)
        return ret;
 }
 
-int mm_sound_client_deliver_focus(int pid, int src_id, int dst_id, mm_sound_focus_type_e focus_type)
+int mm_sound_client_deliver_focus(int src_id, int dst_id, mm_sound_focus_type_e focus_type)
 {
        int ret = MM_ERROR_NONE;
+       int src_index;
+       int dst_index;
+
        debug_fenter();
 
-       if ((ret = mm_sound_proxy_deliver_focus(pid, src_id, dst_id, focus_type)) != MM_ERROR_NONE)
+       MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
+
+       src_index = focus_find_index_by_handle(src_id);
+       if (src_index == -1) {
+               debug_error("Could not find src index");
+               ret = MM_ERROR_INVALID_ARGUMENT;
+               goto cleanup;
+       }
+       dst_index = focus_find_index_by_handle(dst_id);
+       if (dst_index == -1) {
+               debug_error("Could not find dst index");
+               ret = MM_ERROR_INVALID_ARGUMENT;
+               goto cleanup;
+       }
+       if (g_focus_sound_handle[src_index].focus_pid != g_focus_sound_handle[dst_index].focus_pid) {
+               debug_error("pid[%d/%d] are not same for dst/src",
+                                       g_focus_sound_handle[src_index].focus_pid,
+                                       g_focus_sound_handle[dst_index].focus_pid);
+               ret = MM_ERROR_SOUND_INTERNAL;
+               goto cleanup;
+       }
+
+       if ((ret = mm_sound_proxy_deliver_focus(src_index, dst_index, focus_type)) != MM_ERROR_NONE)
                debug_error("failed to deliver focus, ret[0x%x]", ret);
 
+cleanup:
+       MMSOUND_LEAVE_CRITICAL_SECTION(&g_index_mutex);
        debug_fleave();
        return ret;
 }
@@ -1922,42 +1135,30 @@ int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e focu
                                                                                        mm_sound_focus_changed_watch_cb callback, void* user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
-       int instance;
-       int index = 0;
+       int index = -1;
 
        debug_fenter();
 
        if (!id)
                return MM_ERROR_INVALID_ARGUMENT;
 
-       instance = pid;
-
-       ret = mm_sound_proxy_get_unique_id(id);
-       if (ret)
-               return ret;
-
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       for (index = 0; index < FOCUS_HANDLE_MAX - 1; index++) {
-               if (g_focus_sound_handle[index].is_used == false) {
-                       g_focus_sound_handle[index].is_used = true;
-                       break;
-               }
+       if (focus_find_empty_index(&index)) {
+               ret = MM_ERROR_SOUND_INTERNAL;
+               goto cleanup;
        }
 
-       g_focus_sound_handle[index].focus_tid = instance;
-       g_focus_sound_handle[index].handle = *id;
+       g_focus_sound_handle[index].focus_pid = pid;
        g_focus_sound_handle[index].watch_callback = callback;
        g_focus_sound_handle[index].user_data = user_data;
        g_focus_sound_handle[index].unset_watch_callback_requested = false;
 
-       ret = mm_sound_proxy_set_focus_watch_callback(pid, g_focus_sound_handle[index].handle, focus_type,
-                                                                                               callback, user_data);
-
+       ret = mm_sound_proxy_add_focus_watch_callback(index, focus_type);
        if (ret == MM_ERROR_NONE) {
-               debug_msg("Success to watch focus");
-               g_need_emergent_exit = TRUE;
-               if (_focus_init_context(index)) {
+               *id = g_focus_sound_handle[index].handle;
+               debug_msg("Success to add watch focus cb, id(%d)", *id);
+               if (focus_init_context(index)) {
                        ret = MM_ERROR_SOUND_INTERNAL;
                        goto cleanup;
                }
@@ -1966,7 +1167,7 @@ int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e focu
                goto cleanup;
        }
 
-       _focus_init_callback(index, true);
+       focus_init_callback(index, true);
 
 cleanup:
        if (ret)
@@ -1985,7 +1186,7 @@ int mm_sound_client_request_unset_focus_watch_callback(int id)
        debug_fenter();
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       index = _focus_watch_find_index_by_handle(id);
+       index = focus_watch_find_index_by_handle(id);
        if (index == -1) {
                debug_error("Could not find index");
                ret = MM_ERROR_INVALID_ARGUMENT;
@@ -2007,7 +1208,7 @@ int mm_sound_client_unset_focus_watch_callback(int id)
        debug_fenter();
        MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_index_mutex, MM_ERROR_SOUND_INTERNAL);
 
-       index = _focus_watch_find_index_by_handle(id);
+       index = focus_watch_find_index_by_handle(id);
        if (index == -1) {
                debug_error("Could not find index");
                ret = MM_ERROR_INVALID_ARGUMENT;
@@ -2018,22 +1219,21 @@ int mm_sound_client_unset_focus_watch_callback(int id)
 
        g_focus_sound_handle[index].is_used = false;
 
-       ret = mm_sound_proxy_unset_focus_watch_callback(g_focus_sound_handle[index].focus_tid,
-                                                                                                       g_focus_sound_handle[index].handle);
-
+       ret = mm_sound_proxy_remove_focus_watch_callback(index);
        if (ret == MM_ERROR_NONE)
-               debug_msg("Success to unwatch focus");
+               debug_msg("Success to remove watch focus cb, id(%d)", g_focus_sound_handle[index].handle);
        else
                debug_error("Error occurred : 0x%x", ret);
 
 
        g_mutex_unlock(&g_focus_sound_handle[index].focus_lock);
 
-       _focus_deinit_callback(index, true);
+       focus_deinit_callback(index, true);
        g_focus_sound_handle[index].focus_fd = 0;
-       g_focus_sound_handle[index].focus_tid = 0;
+       g_focus_sound_handle[index].focus_pid = 0;
+       g_focus_sound_handle[index].client_fd = 0;
        g_focus_sound_handle[index].handle = 0;
-       _focus_deinit_context(index);
+       focus_deinit_context(index);
 
 cleanup:
        MMSOUND_LEAVE_CRITICAL_SECTION(&g_index_mutex);
@@ -2097,8 +1297,6 @@ int mm_sound_client_execute_focus_func_in_main_context(focus_idle_event_type_e t
 
        return MM_ERROR_NONE;
 }
-#endif
-
 
 int mm_sound_client_add_test_callback(mm_sound_test_cb func, void* user_data, unsigned int *subs_id)
 {
@@ -2123,7 +1321,6 @@ int mm_sound_client_remove_test_callback(unsigned int subs_id)
        return ret;
 }
 
-
 int mm_sound_client_test(int a, int b, int* getv)
 {
        int ret = MM_ERROR_NONE;
index 86f677d..21e8a82 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <stdlib.h>
 #include <unistd.h>
-
 #include <mm_debug.h>
 
 #include "include/mm_sound.h"
 } \
 
 EXPORT_API
-int mm_sound_focus_get_id(int *id)
-{
-       int ret = MM_ERROR_NONE;
-
-       debug_fenter();
-
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
-
-       ret = mm_sound_client_get_unique_id(id);
-       if (ret)
-               debug_error("Failed to mm_sound_client_get_unique_id(), ret[0x%x]", ret);
-
-       debug_fleave();
-
-       return ret;
-}
-
-EXPORT_API
 int mm_sound_focus_is_cb_thread(bool *result)
 {
        int ret = MM_ERROR_NONE;
@@ -77,7 +58,7 @@ int mm_sound_focus_is_cb_thread(bool *result)
 }
 
 EXPORT_API
-int mm_sound_register_focus(int id, const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data)
+int mm_sound_register_focus(const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
 
@@ -85,12 +66,12 @@ int mm_sound_register_focus(int id, const char *stream_type, mm_sound_focus_chan
 
        RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
 
-       if (id < 0 || callback == NULL) {
+       if (id == NULL || callback == NULL) {
                debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_register_focus(id, getpid(), stream_type, callback, user_data);
+       ret = mm_sound_client_register_focus(getpid(), stream_type, callback, user_data, id);
        if (ret)
                debug_error("Could not register focus, ret[0x%x]", ret);
 
@@ -107,7 +88,7 @@ int mm_sound_unregister_focus(int id)
 
        debug_fenter();
 
-       if (id < 0) {
+       if (id <= 0) {
                debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
@@ -320,7 +301,7 @@ int mm_sound_deliver_focus(int src_id, int dst_id, mm_sound_focus_type_e focus_t
 {
        int ret = MM_ERROR_NONE;
 
-       if ((ret = mm_sound_client_deliver_focus(getpid(), src_id, dst_id, focus_type)))
+       if ((ret = mm_sound_client_deliver_focus(src_id, dst_id, focus_type)))
                debug_error("failed to mm_sound_client_deliver_focus(), ret[0x%x]", ret);
 
        return ret;
diff --git a/mm_sound_focus_private.c b/mm_sound_focus_private.c
new file mode 100644 (file)
index 0000000..271a5e5
--- /dev/null
@@ -0,0 +1,627 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <pthread.h>
+#include <glib.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <mm_debug.h>
+#include <mm_error.h>
+#include "include/mm_sound_focus_private.h"
+
+static gpointer _focus_thread_func(gpointer data)
+{
+       unsigned int thread_id = (unsigned int)pthread_self();
+       GMainLoop *focus_loop = (GMainLoop*)data;
+
+       debug_warning(">>> thread id(%u), mainloop[%p]", thread_id, focus_loop);
+       if (focus_loop)
+               g_main_loop_run(focus_loop);
+       debug_warning("<<< quit : thread id(%u), mainloop[%p]", thread_id, focus_loop);
+
+       return NULL;
+}
+
+static gboolean _focus_fd_prepare(GSource *source, gint *timeout)
+{
+#ifdef __DEBUG__
+       debug_warning("[ PREPARE : %p, (%p, %d)", source, timeout, timeout ? *timeout : -1);
+#endif
+       return FALSE;
+}
+
+static gboolean _focus_fd_check(GSource * source)
+{
+       FocusSource* fsource = (FocusSource *)source;
+
+       if (!fsource) {
+               debug_error("GSource is null");
+               return FALSE;
+       }
+#ifdef __DEBUG__
+       debug_warning("CHECK : %p, 0x%x ]", source, fsource->pollfd.revents);
+#endif
+       if (fsource->poll_fd.revents & (POLLIN | POLLPRI))
+               return TRUE;
+       else
+               return FALSE;
+}
+
+static gboolean _focus_fd_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
+{
+       debug_warning("*** DISPATCH : %p, (%p, %p)", source, callback, user_data);
+       return callback(user_data);
+}
+
+static void _focus_fd_finalize(GSource *source)
+{
+       debug_warning("### FINALIZE : %p", source);
+}
+
+static gboolean _focus_callback_handler(gpointer user_data)
+{
+       focus_sound_info_t *focus_handle = (focus_sound_info_t *)user_data;
+       GPollFD *poll_fd;
+       int count;
+       int tid = 0;
+       focus_cb_data_lib cb_data;
+
+       debug_log(">>> thread id(%u)", (unsigned int)pthread_self());
+
+       if (!focus_handle) {
+               debug_error("focus_handle is null");
+               return G_SOURCE_CONTINUE;
+       }
+       poll_fd = &focus_handle->fsrc->poll_fd;
+       debug_log("focus_handle(%p), poll_fd(%p)", focus_handle, poll_fd);
+
+       memset(&cb_data, 0, sizeof(focus_cb_data_lib));
+
+       if (poll_fd->revents & (POLLIN | POLLPRI)) {
+               int changed_state = -1;
+
+               count = read(poll_fd->fd, &cb_data, sizeof(cb_data));
+               if (count < 0) {
+                       char str_error[256];
+                       strerror_r(errno, str_error, sizeof(str_error));
+                       debug_error("GpollFD read fail, errno=%d(%s)", errno, str_error);
+                       return G_SOURCE_CONTINUE;
+               }
+               changed_state = cb_data.state;
+
+               g_mutex_lock(&focus_handle->focus_lock);
+
+               tid = focus_handle->focus_pid;
+
+               if (changed_state != -1) {
+                       debug_msg("Got and start CB : TID(%d), handle(%d), type(%d), state(%d,(DEACTIVATED(0)/ACTIVATED(1)), trigger(%s)",
+                                       tid, cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type);
+                       if (focus_handle->focus_callback == NULL) {
+                                       debug_error("focus callback is null..");
+                                       g_mutex_unlock(&focus_handle->focus_lock);
+                                       return G_SOURCE_CONTINUE;
+                       }
+                       debug_msg("[CALLBACK(%p) START]", focus_handle->focus_callback);
+                       (focus_handle->focus_callback)(cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type,
+                                                                               cb_data.option, cb_data.ext_info, focus_handle->user_data);
+                       debug_msg("[CALLBACK END]");
+               }
+               {
+                       int rett = 0;
+                       int tmpfd = -1;
+                       unsigned int buf = 0;
+                       char *filename2 = g_strdup_printf("/tmp/FOCUS.%d.%dr", focus_handle->focus_pid, cb_data.handle);
+                       tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
+                       if (tmpfd < 0) {
+                               char str_error[256];
+                               strerror_r(errno, str_error, sizeof(str_error));
+                               debug_warning("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)",
+                                                       tid, tmpfd, filename2, errno, str_error);
+                               g_free(filename2);
+                               g_mutex_unlock(&focus_handle->focus_lock);
+                               return G_SOURCE_CONTINUE;
+                       }
+                       /* buf contains data as below,
+                        * |<--12bits--><--4bits (reacquisition)--><--16bits (handle)-->| */
+                       buf = (unsigned int)((0x0000ffff & cb_data.handle) | (focus_handle->auto_reacquire << 16));
+                       rett = write(tmpfd, &buf, sizeof(buf));
+                       close(tmpfd);
+                       g_free(filename2);
+                       debug_msg("[RETCB] tid(%d) finishing CB (write=%d)", tid, rett);
+               }
+       }
+
+       g_mutex_unlock(&focus_handle->focus_lock);
+
+       debug_fleave();
+
+       return G_SOURCE_CONTINUE;
+}
+
+static gboolean _focus_watch_callback_handler(gpointer user_data)
+{
+       focus_sound_info_t *focus_handle = (focus_sound_info_t *)user_data;
+       GPollFD *poll_fd;
+       int count;
+       int tid = 0;
+       focus_cb_data_lib cb_data;
+
+       debug_log(">>> thread id(%u)", (unsigned int)pthread_self());
+
+       if (!focus_handle) {
+               debug_error("focus_handle is null");
+               return G_SOURCE_CONTINUE;
+       }
+       poll_fd = &focus_handle->fsrc->poll_fd;
+       debug_log("focus_handle(%p), poll_fd(%p)", focus_handle, poll_fd);
+
+       memset(&cb_data, 0, sizeof(focus_cb_data_lib));
+
+       if (poll_fd->revents & (POLLIN | POLLPRI)) {
+               count = read(poll_fd->fd, &cb_data, sizeof(cb_data));
+               if (count < 0) {
+                       char str_error[256];
+                       strerror_r(errno, str_error, sizeof(str_error));
+                       debug_error("GpollFD read fail, errno=%d(%s)", errno, str_error);
+                       return G_SOURCE_CONTINUE;
+               }
+
+               if (!focus_handle->is_used) {
+                       debug_warning("unsetting watch calllback has been already requested");
+                       goto SKIP_CB_AND_RET;
+               }
+
+               g_mutex_lock(&focus_handle->focus_lock);
+
+               tid = focus_handle->focus_pid;
+
+               debug_msg("Got and start CB : TID(%d), handle(%d), type(%d), state(%d,(DEACTIVATED(0)/ACTIVATED(1)), trigger(%s)",
+                               tid, cb_data.handle,  cb_data.type, cb_data.state, cb_data.stream_type);
+
+               if (focus_handle->watch_callback == NULL) {
+                       debug_warning("watch callback is null..");
+                       goto SKIP_CB_AND_RET;
+               }
+               if (focus_handle->unset_watch_callback_requested == true) {
+                       debug_warning("unset_watch_callback_requested..");
+                       goto SKIP_CB_AND_RET;
+               }
+
+               debug_msg("[CALLBACK(%p) START]", focus_handle->watch_callback);
+               (focus_handle->watch_callback)(cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type,
+                                                                       cb_data.ext_info, focus_handle->user_data);
+               debug_msg("[CALLBACK END]");
+
+SKIP_CB_AND_RET:
+               {
+                       int rett = 0;
+                       int tmpfd = -1;
+                       int buf = -1;
+                       char *filename2 = g_strdup_printf("/tmp/FOCUS.%d.%d.wchr", focus_handle->focus_pid, cb_data.handle);
+                       tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
+                       if (tmpfd < 0) {
+                               char str_error[256];
+                               strerror_r(errno, str_error, sizeof(str_error));
+                               debug_warning("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)",
+                                                       tid, tmpfd, filename2, errno, str_error);
+                               g_free(filename2);
+                               g_mutex_unlock(&focus_handle->focus_lock);
+                               return G_SOURCE_CONTINUE;
+                       }
+                       buf = cb_data.handle;
+                       rett = write(tmpfd, &buf, sizeof(buf));
+                       close(tmpfd);
+                       g_free(filename2);
+                       debug_msg("[RETCB] tid(%d) finishing CB (write=%d)", tid, rett);
+               }
+       }
+
+       if (focus_handle->is_used) {
+               debug_msg("unlock focus_lock = %p", &focus_handle->focus_lock);
+               g_mutex_unlock(&focus_handle->focus_lock);
+       }
+
+       debug_fleave();
+
+       return G_SOURCE_CONTINUE;
+}
+
+#define INTERVAL_MS 20
+static int _focus_loop_is_running_timed_wait(GMainLoop *focus_loop, int timeout_ms)
+{
+       int reduced_time_ms = timeout_ms;
+       if (!focus_loop || timeout_ms < 0) {
+               debug_error("invalid argument, focus_loop(%p), timeout_ms(%d)", focus_loop, timeout_ms);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       do {
+               if (g_main_loop_is_running(focus_loop))
+                       return MM_ERROR_NONE;
+
+               usleep(INTERVAL_MS * 1000);
+               if (reduced_time_ms < timeout_ms)
+                       debug_warning("reduced_time_ms(%d)", reduced_time_ms);
+       } while ((reduced_time_ms -= INTERVAL_MS) >= 0);
+
+       debug_error("focus_loop is not running for timeout_ms(%d), focus_loop(%p) ", timeout_ms, focus_loop);
+
+       return MM_ERROR_SOUND_INTERNAL;
+}
+
+static void _focus_open_callback(int index, bool is_for_watching)
+{
+       mode_t pre_mask;
+       char *filename;
+
+       debug_fenter();
+
+       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
+               debug_error("Invalid focus handle index [%d]", index);
+               return;
+       }
+
+       if (is_for_watching) {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%d.wch",
+                                                               g_focus_sound_handle[index].focus_pid,
+                                                               g_focus_sound_handle[index].handle);
+       } else {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%d",
+                                                               g_focus_sound_handle[index].focus_pid,
+                                                               g_focus_sound_handle[index].handle);
+       }
+       pre_mask = umask(0);
+       if (mknod(filename, S_IFIFO|0666, 0))
+               debug_error("mknod() failure, errno(%d)", errno);
+       umask(pre_mask);
+       g_focus_sound_handle[index].focus_fd = open(filename, O_RDWR|O_NONBLOCK);
+       if (g_focus_sound_handle[index].focus_fd == -1) {
+               debug_error("Open fail : index(%d), file open error(%d)", index, errno);
+       } else {
+               debug_log("Open success : index(%d), filename(%s), fd(%d)",
+                               index, filename, g_focus_sound_handle[index].focus_fd);
+       }
+       g_free(filename);
+       filename = NULL;
+
+       if (is_for_watching) {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%d.wchr",
+                                                                       g_focus_sound_handle[index].focus_pid,
+                                                                       g_focus_sound_handle[index].handle);
+       } else {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%dr",
+                                                                       g_focus_sound_handle[index].focus_pid,
+                                                                       g_focus_sound_handle[index].handle);
+       }
+       pre_mask = umask(0);
+       if (mknod(filename, S_IFIFO | 0666, 0))
+               debug_error("mknod() failure, errno(%d)", errno);
+       umask(pre_mask);
+       g_free(filename);
+       filename = NULL;
+
+       debug_fleave();
+}
+
+void _focus_close_callback(int index, bool is_for_watching)
+{
+       char *filename = NULL;
+
+       debug_fenter();
+
+       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
+               debug_error("Invalid focus handle index [%d]", index);
+               return;
+       }
+
+       if (g_focus_sound_handle[index].focus_fd < 0) {
+               debug_error("Close fail : index(%d)", index);
+       } else {
+               close(g_focus_sound_handle[index].focus_fd);
+               debug_log("Close Success : index(%d)", index);
+       }
+
+       if (is_for_watching) {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%d.wch",
+                                                               g_focus_sound_handle[index].focus_pid,
+                                                               g_focus_sound_handle[index].handle);
+       } else {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%d",
+                                                               g_focus_sound_handle[index].focus_pid,
+                                                               g_focus_sound_handle[index].handle);
+       }
+       if (remove(filename)) {
+               debug_warning("remove(%s) failure (focus_server probably removed it in advance), errno(%d)",
+                                       filename, errno);
+       }
+       g_free(filename);
+       filename = NULL;
+
+       if (is_for_watching) {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%d.wchr",
+                                                                       g_focus_sound_handle[index].focus_pid,
+                                                                       g_focus_sound_handle[index].handle);
+       } else {
+               filename = g_strdup_printf("/tmp/FOCUS.%d.%dr",
+                                                                       g_focus_sound_handle[index].focus_pid,
+                                                                       g_focus_sound_handle[index].handle);
+       }
+       if (remove(filename)) {
+               debug_warning("remove(%s) failure (focus_server probably removed it in advance), errno(%d)",
+                                       filename, errno);
+       }
+       g_free(filename);
+       filename = NULL;
+
+       debug_fleave();
+}
+
+static GSourceFuncs event_funcs = {
+       .prepare = _focus_fd_prepare,
+       .check = _focus_fd_check,
+       .dispatch = _focus_fd_dispatch,
+       .finalize = _focus_fd_finalize,
+};
+
+static bool _focus_add_sound_callback(int index, focus_callback_handler_t focus_cb_handler)
+{
+       FocusSource *fsrc = NULL;
+       GSource *src = NULL;
+       guint fsrc_id = 0;
+
+       debug_fenter();
+
+       g_mutex_init(&g_focus_sound_handle[index].focus_lock);
+
+       src = g_source_new(&event_funcs, sizeof(FocusSource));
+       if (!src) {
+               debug_error("failed to g_source_new for focus source");
+               goto ERROR;
+       }
+
+       fsrc = (FocusSource*) src;
+
+       fsrc->poll_fd.fd = g_focus_sound_handle[index].focus_fd;
+       fsrc->poll_fd.events = (gushort)(POLLIN | POLLPRI);
+       g_source_add_poll(src, &fsrc->poll_fd);
+
+       g_source_set_callback(src, focus_cb_handler, (gpointer)&g_focus_sound_handle[index], NULL);
+
+       debug_warning("fsrc(%p), src_funcs(%p), pollfd(%p), fd(%d)",
+                               fsrc, &event_funcs, &fsrc->poll_fd, fsrc->poll_fd.fd);
+
+       fsrc_id = g_source_attach(src, g_main_loop_get_context(g_focus_sound_handle[index].focus_loop));
+       if (!fsrc_id) {
+               debug_error("failed to attach the source to context");
+               goto ERROR;
+       }
+       g_source_unref(src);
+
+       g_focus_sound_handle[index].fsrc = fsrc;
+
+       debug_fleave();
+       return true;
+
+ERROR:
+       if (src)
+               g_source_unref(src);
+
+       return false;
+}
+
+static bool _focus_remove_sound_callback(int index)
+{
+       focus_sound_info_t *h = NULL;
+
+       debug_fenter();
+
+       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
+               debug_error("Invalid focus handle index [%d]", index);
+               return false;
+       }
+
+       h = &g_focus_sound_handle[index];
+       if (h->fsrc) {
+               g_source_destroy((GSource *)h->fsrc);
+               h->fsrc = NULL;
+       }
+
+       h->focus_callback = NULL;
+       h->watch_callback = NULL;
+
+       g_mutex_clear(&h->focus_lock);
+
+       debug_fleave();
+
+       return true;
+}
+
+static void _focus_add_callback(int index, bool is_for_watching)
+{
+       debug_fenter();
+
+       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
+               debug_error("Invalid focus handle index [%d]", index);
+               return;
+       }
+
+       if (!is_for_watching) {
+               if (!_focus_add_sound_callback(index, _focus_callback_handler))
+                       debug_error("failed to _focus_add_sound_callback(%p)", _focus_callback_handler);
+       } else {
+               if (!_focus_add_sound_callback(index, _focus_watch_callback_handler))
+                       debug_error("failed to _focus_add_sound_callback(%p)", _focus_watch_callback_handler);
+       }
+       debug_fleave();
+}
+
+static void _focus_remove_callback(int index)
+{
+       debug_fenter();
+       if (!_focus_remove_sound_callback(index))
+               debug_error("failed to __focus_remove_sound_callback()");
+       debug_fleave();
+}
+
+int focus_find_empty_index(int *index)
+{
+       int i = 0;
+
+       if (!index)
+               return -1;
+
+       for (i = 0; i < FOCUS_HANDLE_MAX; i++) {
+               if (g_focus_sound_handle[i].is_used == false) {
+                       g_focus_sound_handle[i].is_used = true;
+                       debug_log("use index[%d]", i);
+                       break;
+               }
+       }
+       if (i == FOCUS_HANDLE_MAX) {
+               debug_error("could not find empty slot, it is full");
+               return -1;
+       }
+
+       *index = i;
+
+       return 0;
+}
+
+int focus_find_index_by_handle(int handle)
+{
+       int i = 0;
+       for (i = 0; i < FOCUS_HANDLE_MAX; i++) {
+               if (g_focus_sound_handle[i].focus_callback && handle == g_focus_sound_handle[i].handle) {
+                       /* debug_msg("found index(%d) for handle(%d)", i, handle);*/
+                       return (handle == FOCUS_HANDLE_INIT_VAL) ? -1 : i;
+               }
+       }
+       return -1;
+}
+
+int focus_watch_find_index_by_handle(int handle)
+{
+       int i = 0;
+       for (i = 0; i < FOCUS_HANDLE_MAX; i++) {
+               if (g_focus_sound_handle[i].watch_callback && handle == g_focus_sound_handle[i].handle) {
+                       /* debug_msg("found index(%d) for watch handle(%d)", i, handle);*/
+                       return (handle == FOCUS_HANDLE_INIT_VAL) ? -1 : i;
+               }
+       }
+       return -1;
+}
+
+#define LOOP_RUNNING_WAIT_TIME_MS 200
+int focus_init_context(int index)
+{
+       int ret = MM_ERROR_NONE;
+       GMainContext *focus_context;
+
+       debug_fenter();
+
+       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
+               debug_error("index(%d) is not valid", index);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       focus_context = g_main_context_new();
+       g_focus_sound_handle[index].focus_loop = g_main_loop_new(focus_context, FALSE);
+       g_main_context_unref(focus_context);
+       if (g_focus_sound_handle[index].focus_loop == NULL) {
+               debug_error("could not create mainloop..");
+               goto ERROR;
+       }
+
+       g_focus_sound_handle[index].focus_cb_thread = g_thread_new("focus-cb-thread",
+                                                                       _focus_thread_func,
+                                                                       g_focus_sound_handle[index].focus_loop);
+       if (g_focus_sound_handle[index].focus_cb_thread == NULL) {
+               debug_error("could not create thread..");
+               goto ERROR;
+       }
+
+       debug_warning("focus cb thread[%p] with mainloop[%p] is created for index(%d)",
+                               g_focus_sound_handle[index].focus_cb_thread, g_focus_sound_handle[index].focus_loop, index);
+
+       if ((ret = _focus_loop_is_running_timed_wait(g_focus_sound_handle[index].focus_loop, LOOP_RUNNING_WAIT_TIME_MS))) {
+               debug_error("failed to _focus_loop_is_running_timed_wait(), ret[0x%x]", ret);
+               goto ERROR;
+       }
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+
+ERROR:
+       if (g_focus_sound_handle[index].focus_loop) {
+               g_main_loop_unref(g_focus_sound_handle[index].focus_loop);
+               g_focus_sound_handle[index].focus_loop = NULL;
+       }
+       return MM_ERROR_SOUND_INTERNAL;
+}
+
+void focus_deinit_context(int index)
+{
+       debug_fenter();
+
+       if (index < 0 || index >= FOCUS_HANDLE_MAX) {
+               debug_error("index(%d) is not valid", index);
+               return;
+       }
+
+       if (!g_focus_sound_handle[index].focus_loop || !g_focus_sound_handle[index].focus_cb_thread) {
+               debug_error("focus_loop[%p] or focus_cb_thread[%p] is null",
+                               g_focus_sound_handle[index].focus_loop, g_focus_sound_handle[index].focus_cb_thread);
+               return;
+       }
+
+       g_main_loop_quit(g_focus_sound_handle[index].focus_loop);
+       g_thread_join(g_focus_sound_handle[index].focus_cb_thread);
+       debug_warning("after thread join, thread[%p], mainloop[%p] for index(%d)",
+                       g_focus_sound_handle[index].focus_cb_thread, g_focus_sound_handle[index].focus_loop, index);
+       g_main_loop_unref(g_focus_sound_handle[index].focus_loop);
+       g_focus_sound_handle[index].focus_loop = NULL;
+       g_focus_sound_handle[index].focus_cb_thread = NULL;
+
+       debug_fleave();
+}
+
+void focus_init_callback(int index, bool is_for_watching)
+{
+       debug_fenter();
+       _focus_open_callback(index, is_for_watching);
+       _focus_add_callback(index, is_for_watching);
+       debug_fleave();
+}
+
+void focus_deinit_callback(int index, bool is_for_watching)
+{
+       debug_fenter();
+       _focus_remove_callback(index);
+       _focus_close_callback(index, is_for_watching);
+       debug_fleave();
+}
index 16fce67..1e7c0db 100644 (file)
 #include "include/mm_sound_common.h"
 #include "include/mm_sound_focus_socket.h"
 
-#define FILL_SOCKET_PARAM(x_param, x_func_name, x_instance, x_id, x_focus_type, x_option, x_ext_info, x_is_in_thread) \
+#define _FILL_SOCKET_PARAM(x_param, x_func_name, x_pid) \
 do { \
        MMSOUND_STRNCPY(x_param.func_name, x_func_name, MM_SOUND_NAME_NUM); \
-       x_param.pid = x_instance; \
+       x_param.pid = x_pid; \
+} while (0) \
+
+#define _FILL_SOCKET_PARAM_WITH_HANDLE(x_param, x_func_name, x_pid, x_id) \
+do { \
+       _FILL_SOCKET_PARAM(x_param, x_func_name, x_pid); \
        x_param.handle_id = x_id; \
+} while (0) \
+
+#define FILL_SOCKET_PARAM_REGISTER(x_param, x_func_name, x_pid, x_stream_type) \
+do { \
+       _FILL_SOCKET_PARAM(x_param, x_func_name, x_pid); \
+       MMSOUND_STRNCPY(x_param.stream_type, x_stream_type, MM_SOUND_NAME_NUM); \
+} while (0) \
+
+#define FILL_SOCKET_PARAM_UNREGISTER(x_param, x_func_name, x_pid, x_id) \
+do { \
+       _FILL_SOCKET_PARAM_WITH_HANDLE(x_param, x_func_name, x_pid, x_id); \
+} while (0) \
+
+#define FILL_SOCKET_PARAM_ADD_WATCH(x_param, x_func_name, x_pid, x_focus_type) \
+do { \
+       _FILL_SOCKET_PARAM(x_param, x_func_name, x_pid); \
        x_param.focus_type = x_focus_type; \
-       x_param.option = x_option; \
-       MMSOUND_STRNCPY(x_param.ext_info, x_ext_info, MM_SOUND_NAME_NUM); \
-       x_param.is_in_thread = x_is_in_thread; \
 } while (0) \
 
-static int _convert_error_from_string(const char *error_string)
-{
-       int ret = MM_ERROR_NONE;
+#define FILL_SOCKET_PARAM_REMOVE_WATCH(x_param, x_func_name, x_pid, x_id) \
+do { \
+       _FILL_SOCKET_PARAM_WITH_HANDLE(x_param, x_func_name, x_pid, x_id); \
+} while (0) \
 
-       if (error_string == NULL) {
-               debug_error("error_string is null");
-               return MM_ERROR_INVALID_ARGUMENT;
-       }
+#define FILL_SOCKET_PARAM_SET_REACQUISITION(x_param, x_func_name, x_pid, x_id, x_reacquisition) \
+do { \
+       _FILL_SOCKET_PARAM_WITH_HANDLE(x_param, x_func_name, x_pid, x_id); \
+       x_param.reacquisition = x_reacquisition; \
+} while (0) \
 
-       if (!strncmp(error_string, FOCUS_ERROR_NONE, MAX_ERROR_LEN))
-               ret = MM_ERROR_NONE;
-       else if (!strncmp(error_string, FOCUS_ERROR_INVALID_PARAMETER, MAX_ERROR_LEN))
-               ret = MM_ERROR_INVALID_ARGUMENT;
-       else if (!strncmp(error_string, FOCUS_ERROR_POLICY, MAX_ERROR_LEN))
-               ret = MM_ERROR_POLICY_BLOCKED;
-       else if (!strncmp(error_string, FOCUS_ERROR_INVALID_STATE, MAX_ERROR_LEN))
-               ret = MM_ERROR_SOUND_INVALID_STATE;
-       else if (!strncmp(error_string, FOCUS_ERROR_INTERNAL, MAX_ERROR_LEN))
-               ret = MM_ERROR_SOUND_INTERNAL;
-       else
-               ret = MM_ERROR_SOUND_INTERNAL;
+#define FILL_SOCKET_PARAM_DELIVER(x_param, x_func_name, x_pid, x_src_id, x_dst_id, x_focus_type) \
+do { \
+       _FILL_SOCKET_PARAM_WITH_HANDLE(x_param, x_func_name, x_pid, x_src_id); \
+       x_param.handle_id_dst = x_dst_id; \
+       x_param.focus_type = x_focus_type; \
+} while (0) \
 
-       debug_msg("error_string[%s], ret[0x%x]", error_string, ret);
+#define FILL_SOCKET_PARAM_GET_ACQUIRED(x_param, x_func_name, x_focus_type) \
+do { \
+       MMSOUND_STRNCPY(x_param.func_name, x_func_name, MM_SOUND_NAME_NUM); \
+       x_param.focus_type = x_focus_type; \
+} while (0) \
 
-       return ret;
-}
+#define FILL_SOCKET_PARAM(x_param, x_func_name, x_pid, x_id, x_focus_type, x_option, x_ext_info, x_is_in_thread) \
+do { \
+       _FILL_SOCKET_PARAM_WITH_HANDLE(x_param, x_func_name, x_pid, x_id); \
+       x_param.focus_type = x_focus_type; \
+       x_param.option = x_option; \
+       MMSOUND_STRNCPY(x_param.ext_info, x_ext_info, MM_SOUND_NAME_NUM); \
+       x_param.is_in_thread = x_is_in_thread; \
+} while (0) \
 
 static int _get_client_socket_fd(int *fd)
 {
@@ -115,10 +139,9 @@ static int _connect_socket_fd(int fd)
        return MM_ERROR_NONE;
 }
 
-static int _send_data_to_server(int fd, _mm_sound_mgr_focus_socket_param_t *data)
+static int _send_data_to_server(int fd, _mm_sound_focus_socket_param_t *data, _mm_sound_focus_socket_result_t *result)
 {
        char str_error[MAX_ERROR_LEN] = {'\0',};
-       char ret_buf[MAX_ERROR_LEN] = {'\0',};
        int rval = 0;
 
        if (fd < 0 || data == NULL) {
@@ -126,80 +149,196 @@ static int _send_data_to_server(int fd, _mm_sound_mgr_focus_socket_param_t *data
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       if (write(fd, data, sizeof(_mm_sound_mgr_focus_socket_param_t)) < 0) {
+       if (write(fd, data, sizeof(_mm_sound_focus_socket_param_t)) < 0) {
                strerror_r(errno, str_error, sizeof(str_error));
                debug_error("failed to write(), err: %s", str_error);
                return MM_ERROR_SOUND_INTERNAL;
        }
 
        /* return message from server */
-       if ((rval = read(fd, ret_buf, sizeof(ret_buf))) < 0) {
+       if ((rval = read(fd, result, sizeof(_mm_sound_focus_socket_result_t))) < 0) {
                strerror_r(errno, str_error, sizeof(str_error));
                debug_error("failed to read(), err: %s", str_error);
                return MM_ERROR_SOUND_INTERNAL;
        }
 
-       debug_log("rval[%d], ret_buf[%s]", rval, ret_buf);
+       debug_log("func_name[%s], rval[%d], ret[0x%x]", data->func_name, rval, result->ret);
 
-       return _convert_error_from_string(ret_buf);
+       return result->ret;
 }
 
 EXPORT_API
-int mm_sound_focus_socket_acquire(int instance, int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread)
+int mm_sound_focus_socket_register(int pid, const char *stream_type, int *client_fd, int *server_fd)
 {
        int ret = MM_ERROR_NONE;
-       int fd = -1;
-       _mm_sound_mgr_focus_socket_param_t data;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
 
        debug_fenter();
 
-       if (instance <= 0 || id < 0 || option < 0) {
-               debug_error("invalid parameter, instance[%d], id[%d], option[%d]", instance, id, option);
+       if (!stream_type || !client_fd || !server_fd)
                return MM_ERROR_INVALID_ARGUMENT;
+
+       if ((ret = _get_client_socket_fd(client_fd))) {
+               debug_error("failed to _get_client_socket_fd()");
+               return MM_ERROR_SOUND_INTERNAL;
        }
-       if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
-               debug_error("focus type[%d] is not valid", focus_type);
-               return MM_ERROR_INVALID_ARGUMENT;
+       if ((ret = _connect_socket_fd(*client_fd))) {
+               debug_error("failed to _connect_socket_fd()");
+               close(*client_fd);
+               return MM_ERROR_SOUND_INTERNAL;
        }
 
-       if ((ret = _get_client_socket_fd(&fd))) {
+       /* get accepted fd from server */
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM_REGISTER(data, FOCUS_FUNC_NAME_REGISTER, pid, stream_type);
+       if ((ret = _send_data_to_server(*client_fd, &data, &result)) < 0) {
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
+               close(*client_fd);
+               return ret;
+       }
+
+       debug_msg("CONNECTED : client fd[%d], server fd[%d]", *client_fd, result.handle_id);
+       *server_fd = result.handle_id;
+
+       debug_fleave();
+
+       return ret;
+}
+
+EXPORT_API
+int mm_sound_focus_socket_unregister(int pid, int client_fd, int server_fd)
+{
+       int ret = MM_ERROR_NONE;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
+
+       debug_fenter();
+
+       debug_msg("DISCONNECTING : client fd[%d], server fd[%d]", client_fd, server_fd);
+
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM_UNREGISTER(data, FOCUS_FUNC_NAME_UNREGISTER, pid, server_fd);
+       if ((ret = _send_data_to_server(client_fd, &data, &result)))
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
+
+       close(client_fd);
+
+       debug_fleave();
+
+       return ret;
+}
+
+EXPORT_API
+int mm_sound_focus_socket_add_watch_cb(int pid, mm_sound_focus_type_e focus_type, int *client_fd, int *server_fd)
+{
+       int ret = MM_ERROR_NONE;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
+
+       debug_fenter();
+
+       if (!client_fd || !server_fd)
+               return MM_ERROR_INVALID_ARGUMENT;
+
+       if ((ret = _get_client_socket_fd(client_fd))) {
                debug_error("failed to _get_client_socket_fd()");
                return MM_ERROR_SOUND_INTERNAL;
        }
-       if ((ret = _connect_socket_fd(fd))) {
+       if ((ret = _connect_socket_fd(*client_fd))) {
                debug_error("failed to _connect_socket_fd()");
-               close(fd);
+               close(*client_fd);
                return MM_ERROR_SOUND_INTERNAL;
        }
 
-       memset(&data, 0x00, sizeof(_mm_sound_mgr_focus_socket_param_t));
-       FILL_SOCKET_PARAM(data, FOCUS_FUNC_NAME_ACQUIRE, instance, id, focus_type,
-                                       option, ext_info, is_in_thread);
-
-       if ((ret = _send_data_to_server(fd, &data))) {
+       /* get accepted fd from server */
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM_ADD_WATCH(data, FOCUS_FUNC_NAME_ADD_WATCH, pid, focus_type);
+       if ((ret = _send_data_to_server(*client_fd, &data, &result)) < 0) {
                debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
-               close(fd);
+               close(*client_fd);
                return ret;
        }
 
-       close(fd);
+       debug_msg("ADDED WATCH CB : client fd[%d], server fd[%d]", *client_fd, result.handle_id);
+       *server_fd = result.handle_id;
 
        debug_fleave();
 
-       return MM_ERROR_NONE;
+       return ret;
 }
 
 EXPORT_API
-int mm_sound_focus_socket_release(int instance, int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread)
+int mm_sound_focus_socket_remove_watch_cb(int pid, int client_fd, int server_fd)
 {
        int ret = MM_ERROR_NONE;
-       int fd = -1;
-       _mm_sound_mgr_focus_socket_param_t data;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
 
        debug_fenter();
 
-       if (instance <= 0 || id < 0 || option < 0) {
-               debug_error("invalid parameter, instance[%d], id[%d], option[%d]", instance, id, option);
+       debug_msg("REMOVING WATCH CB : client fd[%d], server fd[%d]", client_fd, server_fd);
+
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM_REMOVE_WATCH(data, FOCUS_FUNC_NAME_REMOVE_WATCH, pid, server_fd);
+       if ((ret = _send_data_to_server(client_fd, &data, &result)))
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
+
+       close(client_fd);
+
+       debug_fleave();
+
+       return ret;
+}
+
+EXPORT_API
+int mm_sound_focus_socket_acquire(int pid, int client_fd, int server_fd, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread)
+{
+       int ret = MM_ERROR_NONE;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
+
+       debug_fenter();
+
+       if (pid <= 0 || client_fd < 0 || server_fd < 0 || option < 0) {
+               debug_error("invalid parameter, pid[%d], fd[%d/%d], option[%d]",
+                                       pid, client_fd, server_fd, option);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
+               debug_error("focus type[%d] is not valid", focus_type);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM(data, FOCUS_FUNC_NAME_ACQUIRE, pid, server_fd, focus_type,
+                                       option, ext_info, is_in_thread);
+
+       if ((ret = _send_data_to_server(client_fd, &data, &result)))
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
+
+       debug_fleave();
+
+       return ret;
+}
+
+EXPORT_API
+int mm_sound_focus_socket_release(int pid, int client_fd, int server_fd, mm_sound_focus_type_e focus_type, int option, const char *ext_info, bool is_in_thread)
+{
+       int ret = MM_ERROR_NONE;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
+
+       debug_fenter();
+
+       if (pid <= 0 || client_fd < 0 || server_fd < 0 || option < 0) {
+               debug_error("invalid parameter, pid[%d], fd[%d/%d], option[%d]",
+                                       pid, client_fd, server_fd, option);
                return MM_ERROR_INVALID_ARGUMENT;
        }
        if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
@@ -207,6 +346,87 @@ int mm_sound_focus_socket_release(int instance, int id, mm_sound_focus_type_e fo
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM(data, FOCUS_FUNC_NAME_RELEASE, pid, server_fd, focus_type,
+                                       option, ext_info, is_in_thread);
+
+       if ((ret = _send_data_to_server(client_fd, &data, &result)))
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
+
+       debug_fleave();
+
+       return ret;
+}
+
+
+EXPORT_API
+int mm_sound_focus_socket_set_reacquisition(int pid, int client_fd, int server_fd, bool reacquisition)
+{
+       int ret = MM_ERROR_NONE;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
+
+       debug_fenter();
+
+       if (pid <= 0 || client_fd < 0 || server_fd < 0) {
+               debug_error("invalid parameter, pid[%d], fd[%d/%d]", pid, client_fd, server_fd);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM_SET_REACQUISITION(data, FOCUS_FUNC_NAME_SET_REACQUISITON, pid, server_fd, reacquisition);
+
+       if ((ret = _send_data_to_server(client_fd, &data, &result)))
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
+
+       debug_fleave();
+
+       return ret;
+}
+
+EXPORT_API
+int mm_sound_focus_socket_deliver(int pid, int src_client_fd, int src_server_fd, int dst_client_fd, int dst_server_fd, mm_sound_focus_type_e focus_type)
+{
+       int ret = MM_ERROR_NONE;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
+
+       debug_fenter();
+
+       if (pid <= 0 || src_client_fd < 0 || src_server_fd < 0 || dst_client_fd < 0 || dst_server_fd < 0) {
+               debug_error("invalid parameter, pid[%d], src_fd[%d/%d], dst_fd[%d/%d]",
+                                       pid, src_client_fd, src_server_fd, dst_client_fd, dst_server_fd);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM_DELIVER(data, FOCUS_FUNC_NAME_DELIVER, pid, src_server_fd, dst_server_fd, focus_type);
+
+       if ((ret = _send_data_to_server(dst_client_fd, &data, &result)))
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
+
+       debug_fleave();
+
+       return ret;
+}
+
+EXPORT_API
+int mm_sound_focus_socket_get_acquired_focus_stream_type(mm_sound_focus_type_e focus_type, char **stream_type, int *option, char **ext_info)
+{
+       int ret = MM_ERROR_NONE;
+       int fd = 0;
+       _mm_sound_focus_socket_param_t data;
+       _mm_sound_focus_socket_result_t result;
+
+       debug_fenter();
+
+       if (!stream_type) {
+               debug_error("invalid parameter, stream_type[%p]", stream_type);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
        if ((ret = _get_client_socket_fd(&fd))) {
                debug_error("failed to _get_client_socket_fd()");
                return MM_ERROR_SOUND_INTERNAL;
@@ -217,16 +437,22 @@ int mm_sound_focus_socket_release(int instance, int id, mm_sound_focus_type_e fo
                return MM_ERROR_SOUND_INTERNAL;
        }
 
-       memset(&data, 0x00, sizeof(_mm_sound_mgr_focus_socket_param_t));
-       FILL_SOCKET_PARAM(data, FOCUS_FUNC_NAME_RELEASE, instance, id, focus_type,
-                                       option, ext_info, is_in_thread);
+       memset(&data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
+       memset(&result, 0x00, sizeof(_mm_sound_focus_socket_result_t));
+       FILL_SOCKET_PARAM_GET_ACQUIRED(data, FOCUS_FUNC_NAME_GET_ACQUIRED_INFO, focus_type);
 
-       if ((ret = _send_data_to_server(fd, &data))) {
-               debug_error("failed to _send_data_to_server()");
+       if ((ret = _send_data_to_server(fd, &data, &result))) {
+               debug_error("failed to _send_data_to_server(), ret[0x%x]", ret);
                close(fd);
-               return MM_ERROR_SOUND_INTERNAL;
+               return ret;
        }
 
+       debug_msg("stream_type[%s], option[%d], ext_info[%s]", result.stream_type, result.option, result.ext_info);
+
+       *stream_type = strdup(result.stream_type);
+       *ext_info = strdup(result.ext_info);
+       *option = result.option;
+
        close(fd);
 
        debug_fleave();
index cc958c2..2fdd73a 100644 (file)
@@ -13,6 +13,9 @@
 #include "include/mm_sound_dbus.h"
 #include "include/mm_sound_intf.h"
 #include "include/mm_sound_focus_socket.h"
+#include "include/mm_sound_focus_private.h"
+
+extern focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
 
 struct callback_data {
        void *user_cb;
@@ -961,134 +964,58 @@ int mm_sound_proxy_remove_play_sound_end_callback(unsigned subs_id)
        return ret;
 }
 
-int mm_sound_proxy_emergent_exit(int exit_pid)
+int mm_sound_proxy_register_focus(int index, const char *stream_type, int *id)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL;
+       int pid = g_focus_sound_handle[index].focus_pid;
+       int client_fd = 0;
 
 #ifndef TIZEN_TV
        debug_fenter();
 #endif
-
-       params = g_variant_new("(i)", exit_pid);
-       if (params) {
-               if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_EMERGENT_EXIT, params)) != MM_ERROR_NONE) {
-#ifndef TIZEN_TV
-                       debug_error("dbus emergent exit failed");
-#endif
-                       goto cleanup;
-               }
+       ret = mm_sound_focus_socket_register(pid, stream_type, &client_fd, id);
+       if (ret) {
+               debug_error("failed to mm_sound_focus_socket_register(), ret[0x%x]", ret);
        } else {
-#ifndef TIZEN_TV
-               debug_error("Construct Param for emergent exit signal failed");
-#endif
-               ret = MM_ERROR_SOUND_INTERNAL;
+               g_focus_sound_handle[index].client_fd = client_fd;
+               g_focus_sound_handle[index].handle = *id;
        }
 
-cleanup:
-
-#ifndef TIZEN_TV
-       debug_fleave();
-#endif
-       return ret;
-}
-
-/*------------------------------------------ FOCUS --------------------------------------------------*/
-#ifdef USE_FOCUS
-
-int mm_sound_proxy_get_unique_id(int *id)
-{
-       int ret = MM_ERROR_NONE;
-       int res = 0;
-       GVariant *result = NULL;
-
-       debug_fenter();
-
-       if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_UNIQUE_ID, NULL, &result)) != MM_ERROR_NONE)
-               debug_error("dbus get unique id failed");
-
-       if (result) {
-               g_variant_get(result, "(i)", &res);
-               *id = res;
-               debug_msg("got unique id(%d)", *id);
-               g_variant_unref(result);
-       }
-
-       debug_fleave();
-
-       return ret;
-}
-
-int mm_sound_proxy_register_focus(int id, int instance, const char *stream_type, mm_sound_focus_changed_cb callback, void* userdata)
-{
-       int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
-
-       debug_fenter();
-
-       params = g_variant_new("(iis)", instance, id, stream_type);
-       if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_REGISTER_FOCUS, params, &result)) != MM_ERROR_NONE)
-                       debug_error("dbus register focus failed");
-       } else {
-               debug_error("Construct Param for method call failed");
-       }
-
-       if (ret != MM_ERROR_NONE)
-               g_variant_get(result, "(i)",  &ret);
-       if (result)
-               g_variant_unref(result);
-
        debug_fleave();
 
        return ret;
-
 }
 
-int mm_sound_proxy_unregister_focus(int instance, int id)
+int mm_sound_proxy_unregister_focus(int index)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
+       int pid = g_focus_sound_handle[index].focus_pid;
+       int client_fd = g_focus_sound_handle[index].client_fd;
+       int id = g_focus_sound_handle[index].handle;
 
        debug_fenter();
 
-       params = g_variant_new("(ii)", instance, id);
-       if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNREGISTER_FOCUS, params, &result)) != MM_ERROR_NONE)
-                       debug_error("dbus unregister focus failed");
-       } else {
-               debug_error("Construct Param for method call failed");
-       }
-
-       if (ret != MM_ERROR_NONE)
-               g_variant_get(result, "(i)",  &ret);
-       if (result)
-               g_variant_unref(result);
+       ret = mm_sound_focus_socket_unregister(pid, client_fd, id);
+       if (ret)
+               debug_error("failed to mm_sound_focus_socket_unregister(), client_fd[%d], id[%d], ret[0x%x]", client_fd, id, ret);
 
        debug_fleave();
 
        return ret;
 }
 
-int mm_sound_proxy_set_focus_reacquisition(int instance, int id, bool reacquisition)
+int mm_sound_proxy_set_focus_reacquisition(int index, bool reacquisition)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
+       int pid = g_focus_sound_handle[index].focus_pid;
+       int client_fd = g_focus_sound_handle[index].client_fd;
+       int id = g_focus_sound_handle[index].handle;
 
        debug_fenter();
 
-       params = g_variant_new("(iib)", instance, id, reacquisition);
-       if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_SET_FOCUS_REACQUISITION, params, &result)) != MM_ERROR_NONE)
-                       debug_error("dbus set focus reacquisition failed");
-       } else {
-               debug_error("Construct Param for method call failed");
-       }
-
-       if (ret != MM_ERROR_NONE)
-               g_variant_get(result, "(i)",  &ret);
-       if (result)
-               g_variant_unref(result);
+       ret = mm_sound_focus_socket_set_reacquisition(pid, client_fd, id, reacquisition);
+       if (ret)
+               debug_error("failed to mm_sound_focus_socket_set_reacquisition(), ret[0x%x]", ret);
 
        debug_fleave();
        return ret;
@@ -1097,43 +1024,36 @@ int mm_sound_proxy_set_focus_reacquisition(int instance, int id, bool reacquisit
 int mm_sound_proxy_get_acquired_focus_stream_type(int focus_type, char **stream_type, int *option, char **ext_info)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
 
        debug_fenter();
 
-       if (!(params = g_variant_new("(i)", focus_type))) {
-               debug_error("Construct Param for method call failed");
-               return MM_ERROR_SOUND_INTERNAL;
-       }
-
-       if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE, params, &result)) == MM_ERROR_NONE) {
-               if (result) {
-                       g_variant_get(result, "(sis)", stream_type, option, ext_info);
-                       g_variant_unref(result);
-               }
-       } else {
-               debug_error("dbus get stream type of acquired focus failed");
-       }
+       ret = mm_sound_focus_socket_get_acquired_focus_stream_type(focus_type, stream_type, option, ext_info);
+       if (ret)
+               debug_error("failed to mm_sound_focus_socket_get_acquired_focus_stream_type(), ret[0x%x]", ret);
 
        debug_fleave();
        return ret;
 }
 
-int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info)
+int mm_sound_proxy_acquire_focus(int index, mm_sound_focus_type_e type, int option, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
        bool is_in_focus_cb_thread = false;
+       int pid = g_focus_sound_handle[index].focus_pid;
+       int client_fd = g_focus_sound_handle[index].client_fd;
+       int id = g_focus_sound_handle[index].handle;
 
        debug_fenter();
 
        mm_sound_client_is_focus_cb_thread(g_thread_self(), &is_in_focus_cb_thread);
-       if (is_in_focus_cb_thread) {
-               if ((ret = mm_sound_focus_socket_acquire(instance, id, type, option, ext_info ? ext_info : "", true)))
+       if (!is_in_focus_cb_thread) {
+               if ((ret = mm_sound_focus_socket_acquire(pid, client_fd, id,
+                                                                                               type, option, ext_info ? ext_info : "", true)))
                        debug_error("failed to mm_sound_focus_socket_acquire(), ret[0x%x]", ret);
        } else {
                GVariant *params = NULL, *result = NULL;
 
-               params = g_variant_new("(iiiis)", instance, id, type, option, ext_info ? ext_info : "");
+               params = g_variant_new("(iiiis)", pid, id, type, option, ext_info ? ext_info : "");
                if (params) {
                        if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_ACQUIRE_FOCUS, params, &result)) != MM_ERROR_NONE)
                                debug_error("dbus acquire focus failed");
@@ -1151,21 +1071,24 @@ int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e typ
        return ret;
 }
 
-int mm_sound_proxy_release_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info)
+int mm_sound_proxy_release_focus(int index, mm_sound_focus_type_e type, int option, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
        bool is_in_focus_cb_thread = false;
+       int pid = g_focus_sound_handle[index].focus_pid;
+       int client_fd = g_focus_sound_handle[index].client_fd;
+       int id = g_focus_sound_handle[index].handle;
 
        debug_fenter();
 
        mm_sound_client_is_focus_cb_thread(g_thread_self(), &is_in_focus_cb_thread);
-       if (is_in_focus_cb_thread) {
-               if ((ret = mm_sound_focus_socket_release(instance, id, type, option, ext_info ? ext_info : "", true)))
+       if (!is_in_focus_cb_thread) {
+               if ((ret = mm_sound_focus_socket_release(pid, client_fd, id, type, option, ext_info ? ext_info : "", true)))
                        debug_error("failed to mm_sound_focus_socket_release(), ret[0x%x]", ret);
        } else {
                GVariant *params = NULL, *result = NULL;
 
-               params = g_variant_new("(iiiis)", instance, id, type, option, ext_info ? ext_info : "");
+               params = g_variant_new("(iiiis)", pid, id, type, option, ext_info ? ext_info : "");
                if (params) {
                        if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_RELEASE_FOCUS, params, &result)) != MM_ERROR_NONE)
                                debug_error("dbus release focus failed");
@@ -1214,89 +1137,65 @@ int mm_sound_proxy_update_stream_focus_status(int focus_id, unsigned int status)
        return ret;
 }
 
-int mm_sound_proxy_deliver_focus(int pid, int src_id, int dst_id, mm_sound_focus_type_e focus_type)
+int mm_sound_proxy_deliver_focus(int src_index, int dst_index, mm_sound_focus_type_e focus_type)
 {
        int ret = MM_ERROR_NONE;
-       char *reply = NULL;
-       GVariant *params = NULL, *result = NULL;
+       int pid = g_focus_sound_handle[src_index].focus_pid;
+       int src_client_fd = g_focus_sound_handle[src_index].client_fd;
+       int src_server_fd = g_focus_sound_handle[src_index].handle;
+       int dst_client_fd = g_focus_sound_handle[dst_index].client_fd;
+       int dst_server_fd = g_focus_sound_handle[dst_index].handle;
 
        debug_fenter();
 
-       params = g_variant_new("(iiii)", pid, src_id, dst_id, focus_type);
-       if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_DELIVER_FOCUS, params, &result)) != MM_ERROR_NONE) {
-                       debug_error("dbus deliver focus failed");
-                       if (result) {
-                               g_variant_get(result, "(&s)", &reply);
-                               debug_log("reply : %s", reply);
-                               if (strcmp(reply, "STREAM_MANAGER_RETURN_OK"))
-                                       ret = MM_ERROR_SOUND_INTERNAL;
-                       }
-               }
-       } else {
-               debug_error("Construct Param for method call failed");
-               return MM_ERROR_SOUND_INTERNAL;
-       }
-
-       if (result)
-               g_variant_unref(result);
+       ret = mm_sound_focus_socket_deliver(pid, src_client_fd, src_server_fd, dst_client_fd, dst_server_fd, focus_type);
+       if (ret)
+               debug_error("failed to mm_sound_focus_socket_deliver(), ret[0x%x]", ret);
 
        debug_fleave();
        return ret;
 }
 
-int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, void* userdata)
+int mm_sound_proxy_add_focus_watch_callback(int index, mm_sound_focus_type_e type)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
+       int pid = g_focus_sound_handle[index].focus_pid;
+       int id = 0;
+       int client_fd = 0;
 
        debug_fenter();
 
-       params = g_variant_new("(iii)", instance, handle, type);
-       if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE)
-                       debug_error("dbus set watch focus failed");
+       ret = mm_sound_focus_socket_add_watch_cb(pid, type, &client_fd, &id);
+       if (ret) {
+               debug_error("failed to mm_sound_focus_socket_add_watch_cb(), ret[0x%x]", ret);
        } else {
-               debug_error("Construct Param for method call failed");
+               g_focus_sound_handle[index].handle = id;
+               g_focus_sound_handle[index].client_fd = client_fd;
        }
 
-       if (ret != MM_ERROR_NONE)
-               g_variant_get(result, "(i)",  &ret);
-       if (result)
-               g_variant_unref(result);
        debug_fleave();
 
        return ret;
-
 }
 
-int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle)
+int mm_sound_proxy_remove_focus_watch_callback(int index)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
+       int pid = g_focus_sound_handle[index].focus_pid;
+       int client_fd = g_focus_sound_handle[index].client_fd;
+       int id = g_focus_sound_handle[index].handle;
 
        debug_fenter();
 
-       params = g_variant_new("(ii)", focus_tid, handle);
-       if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNWATCH_FOCUS, params, &result)) != MM_ERROR_NONE)
-                       debug_error("dbus unset watch focus failed");
-       } else {
-               debug_error("Construct Param for method call failed");
-       }
-       if (ret != MM_ERROR_NONE)
-               g_variant_get(result, "(i)",  &ret);
-       if (result)
-               g_variant_unref(result);
+       ret = mm_sound_focus_socket_remove_watch_cb(pid, client_fd, id);
+       if (ret)
+               debug_error("failed to mm_sound_focus_socket_remove_watch_cb(), ret[0x%x]", ret);
 
        debug_fleave();
 
        return ret;
 }
 
-#endif /* USE_FOCUS */
-/*------------------------------------------ FOCUS --------------------------------------------------*/
-
 int mm_sound_proxy_initialize(void)
 {
        int ret = MM_ERROR_NONE;
index 82f21e7..ab317b0 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-sound
 Summary:    MMSound Package contains client lib and sound_server binary
-Version:    0.12.19
+Version:    0.12.20
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
@@ -76,7 +76,7 @@ CFLAGS="%{optflags} -fvisibility=hidden -D_TIZEN_PUBLIC_ -DEXPORT_API=\"__attrib
        --enable-prelink \
        --enable-lwipc \
 %endif
-       --prefix=/usr --enable-pulse --enable-focus
+       --prefix=/usr --enable-pulse
 
 make %{?_smp_mflags}
 
@@ -149,6 +149,8 @@ ln -sf ../focus-server.path %{buildroot}%{_unitdir}/multi-user.target.wants/focu
 %{_libdir}/libmmfsound.so
 %{_libdir}/libmmfsoundcommon.so
 %{_includedir}/mmf/mm_sound_private.h
+%exclude %{_includedir}/mmf/mm_sound_focus_socket.h
+%exclude %{_includedir}/mmf/mm_sound_focus_private.h
 %exclude %{_includedir}/mmf/mm_sound_pa_client.h
 
 %files sdk-devel
@@ -157,6 +159,7 @@ ln -sf ../focus-server.path %{buildroot}%{_unitdir}/multi-user.target.wants/focu
 %{_includedir}/mmf/mm_sound_focus.h
 %{_includedir}/mmf/mm_sound_device.h
 %exclude %{_includedir}/mmf/mm_sound_focus_socket.h
+%exclude %{_includedir}/mmf/mm_sound_focus_private.h
 %exclude %{_includedir}/mmf/mm_sound_pa_client.h
 %{_libdir}/pkgconfig/mm-keysound.pc
 %{_libdir}/pkgconfig/mm-bootsound.pc
index bd2605d..059ac19 100644 (file)
@@ -65,9 +65,6 @@ static GDBusConnection* conn_g;
 static void handle_method_play_file_start_with_stream_info(GDBusMethodInvocation* invocation);
 static void handle_method_play_file_stop(GDBusMethodInvocation* invocation);
 static void handle_method_play_dtmf_with_stream_info(GDBusMethodInvocation* invocation);
-#ifdef FOCUS_INTEGRATION
-static void handle_method_clear_focus(GDBusMethodInvocation* invocation);
-#endif
 static void handle_method_test(GDBusMethodInvocation* invocation);
 
 /* Currently , Just using method's name and handler */
@@ -317,34 +314,6 @@ send_reply:
        debug_fleave();
 }
 
-#ifdef FOCUS_INTEGRATION
-static void handle_method_clear_focus(GDBusMethodInvocation* invocation)
-{
-       int ret = MM_ERROR_NONE;
-       int pid = 0;
-       GVariant *params = NULL;
-
-       debug_fenter();
-
-       if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
-               debug_error("Parameter for Method is NULL");
-               ret = MM_ERROR_SOUND_INTERNAL;
-               goto send_reply;
-       }
-
-       g_variant_get(params, "(i)", &pid);
-       ret = _MMSoundMgrIpcClearFocus(pid);
-
-send_reply:
-       if (ret == MM_ERROR_NONE)
-               _method_call_return_value(invocation, g_variant_new("()"));
-       else
-               _method_call_return_error(invocation, ret);
-
-       debug_fleave();
-}
-#endif
-
 static void handle_method_call(GDBusConnection *connection,
                                                        const gchar *sender,
                                                        const gchar *object_path,
index 765503a..e9bec97 100755 (executable)
@@ -54,6 +54,7 @@ enum {
        CURRENT_STATUS_DIRNAME = 3,
 };
 
+int g_focus_id = 0;
 int g_menu_state = CURRENT_STATUS_MAINMENU;
 volume_type_t g_volume_type = VOLUME_TYPE_MEDIA;
 unsigned int g_volume_value;
@@ -161,26 +162,17 @@ void device_state_changed_cb(MMSoundDevice_t device_h, mm_sound_device_state_e n
                        device_type, id, io_direction, state, name, vendor_id, product_id);
 }
 
-void focus_cb0(int index, mm_sound_focus_type_e type, mm_sound_focus_state_e state, const char *reason_for_change, int option, const char *ext_info, void *user_data)
+void focus_cb(int index, mm_sound_focus_type_e type, mm_sound_focus_state_e state, const char *reason_for_change, int option, const char *ext_info, void *user_data)
 {
        char *_state = NULL;
        if (state == FOCUS_IS_RELEASED)
                _state = "RELEASED";
        else
                _state = "ACQUIRED";
-       debug_log("*** focus_cb0 is called, index[%d], focus_type[%d], state[%s], reason_for_change[%s], option[0x%x], ext_info[%s], user_data[%s]",
-                       index, type, _state, reason_for_change, option, ext_info, (char*)user_data);
-}
-void focus_cb1(int index, mm_sound_focus_type_e type, mm_sound_focus_state_e state, const char *reason_for_change, int option, const char *ext_info, void *user_data)
-{
-       char *_state = NULL;
-       if (state == FOCUS_IS_RELEASED)
-               _state = "RELEASED";
-       else
-               _state = "ACQUIRED";
-       debug_log("*** focus_cb1 is called, index[%d], focus_type[%d], state[%s], reason_for_change[%s], option[0x%x], ext_info[%s], user_data[%s]",
+       debug_log("*** focus_cb is called, index[%d], focus_type[%d], state[%s], reason_for_change[%s], option[0x%x], ext_info[%s], user_data[%s]",
                        index, type, _state, reason_for_change, option, ext_info, (char*)user_data);
 }
+
 void focus_watch_cb(int index, mm_sound_focus_type_e type, mm_sound_focus_state_e state, const char *reason_for_change, const char *ext_info, void *user_data)
 {
        char *_state = NULL;
@@ -243,7 +235,6 @@ static void displaymenu()
                g_print("==================================================================\n");
                g_print("       Focus APIs\n");
                g_print("==================================================================\n");
-               g_print("GU : Get Focus id\n");
                g_print("SF : Set Focus Callback\t");
                g_print("UF : Unset Focus Callback\n");
                g_print("DF : Disable Auto Focus Reacquirement\t");
@@ -317,20 +308,11 @@ static void interpret(char *cmd)
 
        switch (g_menu_state) {
        case CURRENT_STATUS_MAINMENU:
-               if (strncmp(cmd, "GU", 2) == 0) {
-                       int id = 0;
-                       ret = mm_sound_focus_get_id(&id);
-                       if (ret < 0)
-                               debug_log("mm_sound_focus_get_id() failed with 0x%x", ret);
-                       else
-                               debug_log("id : %d", id);
-
-               } else if (strncmp(cmd, "SF", 2) == 0) {
+               if (strncmp(cmd, "SF", 2) == 0) {
                        int ret = 0;
                        char input_string[128];
-                       char flag_1, flag_2;
-                       int id = 2;
-                       char *stream_type = "media";
+                       char select;
+                       char *stream_type = NULL;
                        const char *user_data = "this is user data";
 
                        fflush(stdin);
@@ -343,68 +325,44 @@ static void interpret(char *cmd)
                        g_print("7. Ringtone Call\n");
                        g_print("8. VOIP\n");
                        g_print("0. Voice Recognition\n");
-                       g_print("> select id and stream type: (eg. 0 3)");
+                       g_print("> stream type: ");
 
                        if (fgets(input_string, sizeof(input_string)-1, stdin)) {
-                               flag_1 = input_string[0];
-                               flag_2 = input_string[2];
+                               select = input_string[0];
 
-                               if (flag_1 == '0')
-                                       id = 0;
-                               else if (flag_1 == '1')
-                                       id = 1;
-                               else if (flag_1 == '2')
-                                       id = 2;
-
-                               if (flag_2 == '1')
+                               if (select == '1')
                                        stream_type = "media";
-                               else if (flag_2 == '2')
+                               else if (select == '2')
                                        stream_type = "alarm";
-                               else if (flag_2 == '3')
+                               else if (select == '3')
                                        stream_type = "notification";
-                               else if (flag_2 == '4')
+                               else if (select == '4')
                                        stream_type = "emergency";
-                               else if (flag_2 == '5')
+                               else if (select == '5')
                                        stream_type = "voice-information";
-                               else if (flag_2 == '6')
+                               else if (select == '6')
                                        stream_type = "ringtone";
-                               else if (flag_2 == '7')
+                               else if (select == '7')
                                        stream_type = "ringtone-call";
-                               else if (flag_2 == '8')
+                               else if (select == '8')
                                        stream_type = "voip";
-                               else if (flag_2 == '0')
+                               else if (select == '0')
                                        stream_type = "voice-recognition";
 
-                               ret = mm_sound_register_focus(id, stream_type, (id == 0) ? focus_cb0 : focus_cb1, (void*)user_data);
+                               ret = mm_sound_register_focus(stream_type, focus_cb, (void*)user_data, &g_focus_id);
                                if (ret)
                                        g_print("failed to mm_sound_register_focus(), ret[0x%x]\n", ret);
                                else
-                                       g_print("id[%d], stream_type[%s], callback fun[%p]\n", id, stream_type, (id == 0) ? focus_cb0 : focus_cb1);
-
+                                       g_print("id[%d], stream_type[%s], callback fun[%p]\n", g_focus_id, stream_type, focus_cb);
                        } else {
                                g_print("### fgets return  NULL\n");
                        }
                } else if (strncmp(cmd, "UF", 2) == 0) {
                        int ret = 0;
-                       char input_string[128];
-                       char flag_1;
-                       int id = 2;
-                       fflush(stdin);
-                       g_print("> select id:");
-                       if (fgets(input_string, sizeof(input_string)-1, stdin)) {
-                               flag_1 = input_string[0];
-                               if (flag_1 == '0')
-                                       id = 0;
-                               else if (flag_1 == '1')
-                                       id = 1;
-                               else if (flag_1 == '2')
-                                       id = 2;
-                               ret = mm_sound_unregister_focus(id);
-                               if (ret)
-                                       g_print("failed to mm_sound_unregister_focus(), ret[0x%x]\n", ret);
-                       } else {
-                               g_print("### fgets return  NULL\n");
-                       }
+
+                       ret = mm_sound_unregister_focus(g_focus_id);
+                       if (ret)
+                               g_print("failed to mm_sound_unregister_focus(), ret[0x%x]\n", ret);
                } else if (strncmp(cmd, "DF", 2) == 0) {
                        int ret = 0;
                        char input_string[128];
@@ -437,14 +395,12 @@ static void interpret(char *cmd)
                        } else {
                                g_print("### fgets return  NULL\n");
                        }
-               }
-
-               else if (strncmp(cmd, "AF", 2) == 0) {
+               } else if (strncmp(cmd, "AF", 2) == 0) {
                        int ret = 0;
                        char input_string[128];
                        char flag_1, flag_2;
                        int id = 0;
-                       mm_sound_focus_type_e type = FOCUS_FOR_PLAYBACK;
+                       mm_sound_focus_type_e type = FOCUS_FOR_BOTH;
                        fflush(stdin);
                        g_print("1. focus for playback\n");
                        g_print("2. focus for recording\n");
@@ -458,15 +414,12 @@ static void interpret(char *cmd)
                                        id = 0;
                                else if (flag_1 == '1')
                                        id = 1;
-                               else
-                                       id = 2;
 
                                if (flag_2 == '1')
                                        type = FOCUS_FOR_PLAYBACK;
                                else if (flag_2 == '2')
                                        type = FOCUS_FOR_CAPTURE;
-                               else
-                                       type = FOCUS_FOR_BOTH;
+
                                ret = mm_sound_acquire_focus(id, type, "additional_info. for acquire");
                                if (ret)
                                        g_print("failed to mm_sound_acquire_focus(), ret[0x%x]\n", ret);
@@ -479,8 +432,8 @@ static void interpret(char *cmd)
                        int ret = 0;
                        char input_string[128];
                        char flag_1, flag_2;
-                       int id = 0;
-                       mm_sound_focus_type_e type = FOCUS_FOR_PLAYBACK;
+                       int id = 2;
+                       mm_sound_focus_type_e type = FOCUS_FOR_BOTH;
                        fflush(stdin);
                        g_print("1. focus for playback\n");
                        g_print("2. focus for recording\n");
@@ -494,15 +447,12 @@ static void interpret(char *cmd)
                                        id = 0;
                                else if (flag_1 == '1')
                                        id = 1;
-                               else
-                                       id = 2;
 
                                if (flag_2 == '1')
                                        type = FOCUS_FOR_PLAYBACK;
                                else if (flag_2 == '2')
                                        type = FOCUS_FOR_CAPTURE;
-                               else
-                                       type = FOCUS_FOR_BOTH;
+
                                ret = mm_sound_release_focus(id, type, "additional_info. for release");
                                if (ret)
                                        g_print("failed to mm_sound_release_focus(), ret[0x%x]\n", ret);
@@ -515,7 +465,7 @@ static void interpret(char *cmd)
                        int ret = 0;
                        char input_string[128];
                        char flag_1;
-                       int type = 0;
+                       int type = 1;
                        const char *user_data = "this is user data for watch";
 
                        fflush(stdin);
@@ -533,8 +483,7 @@ static void interpret(char *cmd)
                                        type = 2;
                                else if (flag_1 == '3')
                                        type = 3;
-                               else
-                                       type = 1;
+
                                ret = mm_sound_set_focus_watch_callback(type, focus_watch_cb, (void*)user_data, &g_focus_watch_index);
                                if (ret)
                                        g_print("failed to mm_sound_set_focus_watch_callback(), ret[0x%x]\n", ret);