From 6f688c829ad2fa05652932c69b390c1663cd6a59 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Fri, 15 Dec 2017 18:05:12 +0900 Subject: [PATCH] Use socket for IPC of focus APIs instead of the DBus 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 --- Makefile.am | 11 +- common/mm_sound_dbus.c | 29 - configure.ac | 10 - focus_server/include/mm_sound_mgr_focus.h | 7 +- focus_server/include/mm_sound_mgr_focus_ipc.h | 4 +- focus_server/mm_sound_mgr_focus.c | 81 +-- focus_server/mm_sound_mgr_focus_dbus.c | 329 +-------- focus_server/mm_sound_mgr_focus_ipc.c | 77 +-- focus_server/mm_sound_mgr_focus_socket.c | 324 +++++++-- include/mm_sound.h | 3 - include/mm_sound_client.h | 10 +- include/mm_sound_common.h | 2 + include/mm_sound_focus.h | 5 +- include/mm_sound_focus_private.h | 76 ++ include/mm_sound_focus_socket.h | 39 +- include/mm_sound_intf.h | 9 - include/mm_sound_proxy.h | 21 +- mm_sound_client.c | 961 +++----------------------- mm_sound_focus.c | 29 +- mm_sound_focus_private.c | 627 +++++++++++++++++ mm_sound_focus_socket.c | 352 ++++++++-- mm_sound_proxy.c | 237 ++----- packaging/libmm-sound.spec | 7 +- server/mm_sound_mgr_ipc_dbus.c | 31 - testsuite/mm_sound_testsuite_simple.c | 115 +-- 25 files changed, 1555 insertions(+), 1841 deletions(-) create mode 100644 include/mm_sound_focus_private.h create mode 100644 mm_sound_focus_private.c diff --git a/Makefile.am b/Makefile.am index 3b201a9..b4d4bdd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/common/mm_sound_dbus.c b/common/mm_sound_dbus.c index db3f600..fcd43b3 100644 --- a/common/mm_sound_dbus.c +++ b/common/mm_sound_dbus.c @@ -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); } diff --git a/configure.ac b/configure.ac index 8a28a10..223fa53 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/focus_server/include/mm_sound_mgr_focus.h b/focus_server/include/mm_sound_mgr_focus.h index 7c60f5d..21dfbd8 100644 --- a/focus_server/include/mm_sound_mgr_focus.h +++ b/focus_server/include/mm_sound_mgr_focus.h @@ -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__ */ diff --git a/focus_server/include/mm_sound_mgr_focus_ipc.h b/focus_server/include/mm_sound_mgr_focus_ipc.h index 8e28cce..0698a40 100644 --- a/focus_server/include/mm_sound_mgr_focus_ipc.h +++ b/focus_server/include/mm_sound_mgr_focus_ipc.h @@ -24,8 +24,10 @@ #include -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); diff --git a/focus_server/mm_sound_mgr_focus.c b/focus_server/mm_sound_mgr_focus.c index e3d297a..746cc25 100644 --- a/focus_server/mm_sound_mgr_focus.c +++ b/focus_server/mm_sound_mgr_focus.c @@ -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, ¶m_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) diff --git a/focus_server/mm_sound_mgr_focus_dbus.c b/focus_server/mm_sound_mgr_focus_dbus.c index 98d85d6..dbf7265 100644 --- a/focus_server/mm_sound_mgr_focus_dbus.c +++ b/focus_server/mm_sound_mgr_focus_dbus.c @@ -21,29 +21,6 @@ static const gchar introspection_xml[] = "" " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " " " " " " " @@ -58,24 +35,6 @@ static const gchar introspection_xml[] = " " " " " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " " " ""; 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); diff --git a/focus_server/mm_sound_mgr_focus_ipc.c b/focus_server/mm_sound_mgr_focus_ipc.c index d300e45..1c2b811 100644 --- a/focus_server/mm_sound_mgr_focus_ipc.c +++ b/focus_server/mm_sound_mgr_focus_ipc.c @@ -29,13 +29,13 @@ #include "include/mm_sound_mgr_focus.h" #include -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(¶m, 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(¶m, 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(¶m); + + 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(¶m, 0x00, sizeof(_mm_sound_mgr_focus_param_t)); + param.pid = pid; + param.handle_id = handle_id; + + ret = mm_sound_mgr_focus_remove_watch_node(¶m); + + 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(¶m, 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(¶m); - - 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(¶m, 0x00, sizeof(_mm_sound_mgr_focus_param_t)); - param.pid = pid; - param.handle_id = handle_id; - - ret = mm_sound_mgr_focus_unset_watch_cb(¶m); - - 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(¶m, 0x00, sizeof(_mm_sound_mgr_focus_param_t)); - param.pid = pid; - - ret = mm_sound_mgr_focus_emergent_exit(¶m); - - return ret; -} - diff --git a/focus_server/mm_sound_mgr_focus_socket.c b/focus_server/mm_sound_mgr_focus_socket.c index 06e3ba9..ae5f6b7 100644 --- a/focus_server/mm_sound_mgr_focus_socket.c +++ b/focus_server/mm_sound_mgr_focus_socket.c @@ -35,16 +35,29 @@ #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; } diff --git a/include/mm_sound.h b/include/mm_sound.h index ffb2cfd..a38345a 100644 --- a/include/mm_sound.h +++ b/include/mm_sound.h @@ -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 */ diff --git a/include/mm_sound_client.h b/include/mm_sound_client.h index 3055fc8..f5d7c0a 100644 --- a/include/mm_sound_client.h +++ b/include/mm_sound_client.h @@ -24,14 +24,13 @@ #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); diff --git a/include/mm_sound_common.h b/include/mm_sound_common.h index ef977aa..4871e72 100644 --- a/include/mm_sound_common.h +++ b/include/mm_sound_common.h @@ -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: \ diff --git a/include/mm_sound_focus.h b/include/mm_sound_focus.h index 94fcff1..d725233 100644 --- a/include/mm_sound_focus.h +++ b/include/mm_sound_focus.h @@ -34,6 +34,8 @@ extern "C" { #endif +#include + 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 index 0000000..d84bb79 --- /dev/null +++ b/include/mm_sound_focus_private.h @@ -0,0 +1,76 @@ +/* + * libmm-sound + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Sangchul Lee + * + * 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__ */ diff --git a/include/mm_sound_focus_socket.h b/include/mm_sound_focus_socket.h index b3b258a..a105617 100644 --- a/include/mm_sound_focus_socket.h +++ b/include/mm_sound_focus_socket.h @@ -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" @@ -34,17 +34,35 @@ 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 } diff --git a/include/mm_sound_intf.h b/include/mm_sound_intf.h index 1ae0713..ab4a200 100644 --- a/include/mm_sound_intf.h +++ b/include/mm_sound_intf.h @@ -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, diff --git a/include/mm_sound_proxy.h b/include/mm_sound_proxy.h index 7cd9a86..f2352e6 100644 --- a/include/mm_sound_proxy.h +++ b/include/mm_sound_proxy.h @@ -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); diff --git a/mm_sound_client.c b/mm_sound_client.c index 701ca84..b732824 100644 --- a/mm_sound_client.c +++ b/mm_sound_client.c @@ -19,19 +19,11 @@ * */ -#include #include -#include -#include -#include -#include #include #include -#include - #include -#include - +#include #include #include @@ -41,26 +33,12 @@ #include "include/mm_sound_common.h" #include "include/mm_sound_device.h" #include "include/mm_sound_stream.h" - -#include -#if defined(__GSOURCE_CALLBACK__) -#include -#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; diff --git a/mm_sound_focus.c b/mm_sound_focus.c index 86f677d..21e8a82 100644 --- a/mm_sound_focus.c +++ b/mm_sound_focus.c @@ -21,7 +21,6 @@ #include #include - #include #include "include/mm_sound.h" @@ -41,24 +40,6 @@ } \ 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 index 0000000..271a5e5 --- /dev/null +++ b/mm_sound_focus_private.c @@ -0,0 +1,627 @@ +/* + * libmm-sound + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Sangchul Lee + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#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(); +} diff --git a/mm_sound_focus_socket.c b/mm_sound_focus_socket.c index 16fce67..1e7c0db 100644 --- a/mm_sound_focus_socket.c +++ b/mm_sound_focus_socket.c @@ -28,43 +28,67 @@ #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(); diff --git a/mm_sound_proxy.c b/mm_sound_proxy.c index cc958c2..2fdd73a 100644 --- a/mm_sound_proxy.c +++ b/mm_sound_proxy.c @@ -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; diff --git a/packaging/libmm-sound.spec b/packaging/libmm-sound.spec index 82f21e7..ab317b0 100644 --- a/packaging/libmm-sound.spec +++ b/packaging/libmm-sound.spec @@ -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 diff --git a/server/mm_sound_mgr_ipc_dbus.c b/server/mm_sound_mgr_ipc_dbus.c index bd2605d..059ac19 100644 --- a/server/mm_sound_mgr_ipc_dbus.c +++ b/server/mm_sound_mgr_ipc_dbus.c @@ -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, diff --git a/testsuite/mm_sound_testsuite_simple.c b/testsuite/mm_sound_testsuite_simple.c index 765503a..e9bec97 100755 --- a/testsuite/mm_sound_testsuite_simple.c +++ b/testsuite/mm_sound_testsuite_simple.c @@ -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); -- 2.7.4