Add support for acquiring/releasing focus within focus callback 10/129310/6
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 12 May 2017 05:41:19 +0000 (14:41 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 29 May 2017 02:15:34 +0000 (11:15 +0900)
Added socket infrastructure for new IPC.
Added signal handler to deinitialize resources.

[Version] 0.11.1
[Issue Type] Enhancement

Change-Id: Ia497cc7e651221cc5dcfeb58518194c877cf7458
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
15 files changed:
Makefile.am
focus_server/Makefile.am
focus_server/include/mm_sound_mgr_focus.h
focus_server/include/mm_sound_mgr_focus_ipc.h
focus_server/include/mm_sound_mgr_focus_socket.h [new file with mode: 0644]
focus_server/mm_sound_focus_server.c
focus_server/mm_sound_mgr_focus.c
focus_server/mm_sound_mgr_focus_dbus.c
focus_server/mm_sound_mgr_focus_ipc.c
focus_server/mm_sound_mgr_focus_socket.c [new file with mode: 0644]
include/mm_sound_focus_socket.h [new file with mode: 0644]
mm_sound_focus.c
mm_sound_focus_socket.c [new file with mode: 0644]
mm_sound_proxy.c
packaging/libmm-sound.spec

index 6498203..d3a162c 100644 (file)
@@ -22,8 +22,10 @@ libmmfsound_la_SOURCES = mm_sound.c \
                        mm_sound_device.c \
                        mm_sound_pa_client.c
 if USE_FOCUS
-includelibmmfsound_HEADERS += include/mm_sound_focus.h
-libmmfsound_la_SOURCES += mm_sound_focus.c
+includelibmmfsound_HEADERS += include/mm_sound_focus.h \
+                               include/mm_sound_focus_socket.h
+libmmfsound_la_SOURCES += mm_sound_focus.c \
+                               mm_sound_focus_socket.c
 endif
 
 libmmfsound_la_DEPENDENCIES = common/libmmfsoundcommon.la
index 296ff34..28bc745 100644 (file)
@@ -1,6 +1,7 @@
 bin_PROGRAMS = focus_server
 focus_server_SOURCES = mm_sound_mgr_focus_ipc.c \
                                                mm_sound_mgr_focus_dbus.c \
+                                               mm_sound_mgr_focus_socket.c \
                                                mm_sound_focus_server.c \
                                                mm_sound_mgr_focus.c
 
index 1572103..4d4d144 100644 (file)
@@ -58,6 +58,7 @@ typedef struct {
        void *callback;
        void *cbdata;
        bool reacquisition;
+       bool is_in_thread;
 
        /* It will be removed when the session concept is completely left out*/
        bool is_for_session;
index fc9ef7a..1fd875f 100644 (file)
@@ -27,8 +27,8 @@
 int __mm_sound_mgr_focus_ipc_register_focus(int client_pid, int handle_id, const char* stream_type, bool is_for_session);
 int __mm_sound_mgr_focus_ipc_set_focus_reacquisition(int pid, int handle_id, bool reacquisition, bool is_for_session);
 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_for_session);
-int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_for_session);
+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, bool is_for_session);
+int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_in_thread, bool is_for_session);
 int __mm_sound_mgr_focus_ipc_watch_focus(int pid, int handle_id, int focus_type, bool is_for_session, bool is_for_monitor);
 int __mm_sound_mgr_focus_ipc_unwatch_focus(int pid, int handle_id);
 int __mm_sound_mgr_focus_ipc_unregister_focus(int pid, int handle_id, bool is_for_session);
diff --git a/focus_server/include/mm_sound_mgr_focus_socket.h b/focus_server/include/mm_sound_mgr_focus_socket.h
new file mode 100644 (file)
index 0000000..9768c48
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __MM_SOUND_MGR_FOCUS_SOCKET_H__
+#define __MM_SOUND_MGR_FOCUS_SOCKET_H__
+
+int MMSoundMgrFocusSocketInit(int *fd);
+void MMSoundMgrFocusSocketFini(int fd);
+int MMSoundMgrFocusSocketReadyToWork(int fd);
+
+
+#endif /* __MM_SOUND_MGR_FOCUS_SOCKET_H__ */
index 931f00d..f836b3c 100644 (file)
@@ -38,6 +38,7 @@
 #include "../include/mm_sound_common.h"
 #include "include/mm_sound_mgr_focus.h"
 #include "include/mm_sound_mgr_focus_dbus.h"
+#include "include/mm_sound_mgr_focus_socket.h"
 
 #define USE_SYSTEM_SERVER_PROCESS_MONITORING
 
@@ -138,6 +139,87 @@ static void _generate_ready_file(const char *path)
        }
 }
 
+int g_socket_fd = -1;
+struct sigaction _int_old_action;
+struct sigaction _abrt_old_action;
+struct sigaction _segv_old_action;
+struct sigaction _term_old_action;
+struct sigaction _sys_old_action;
+struct sigaction _xcpu_old_action;
+static void _signal_handler(int signo)
+{
+       debug_warning("ENTER, sig.num(%d)", signo);
+
+       MMSoundMgrFocusDbusFini();
+       MMSoundMgrFocusFini();
+       MMSoundMgrFocusSocketFini(g_socket_fd);
+
+       /* signal block -------------- */
+       sigset_t old_mask, all_mask;
+       sigfillset(&all_mask);
+       sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
+
+       sigprocmask(SIG_SETMASK, &old_mask, NULL);
+       /* signal unblock ------------ */
+
+       switch (signo) {
+       case SIGINT:
+               sigaction(SIGINT, &_int_old_action, NULL);
+               raise(signo);
+               break;
+       case SIGABRT:
+               sigaction(SIGABRT, &_abrt_old_action, NULL);
+               raise(signo);
+               break;
+       case SIGSEGV:
+               sigaction(SIGSEGV, &_segv_old_action, NULL);
+               raise(signo);
+               break;
+       case SIGTERM:
+               sigaction(SIGTERM, &_term_old_action, NULL);
+               raise(signo);
+               break;
+       case SIGSYS:
+               sigaction(SIGSYS, &_sys_old_action, NULL);
+               raise(signo);
+               break;
+       case SIGXCPU:
+               sigaction(SIGXCPU, &_xcpu_old_action, NULL);
+               raise(signo);
+               break;
+       default:
+               break;
+       }
+       debug_warning("LEAVE");
+}
+
+static void _signal_initialize(void)
+{
+       struct sigaction _action;
+       _action.sa_handler = _signal_handler;
+       _action.sa_flags = SA_NOCLDSTOP;
+
+       sigemptyset(&_action.sa_mask);
+
+       sigaction(SIGINT, &_action, &_int_old_action);
+       sigaction(SIGABRT, &_action, &_abrt_old_action);
+       sigaction(SIGSEGV, &_action, &_segv_old_action);
+       sigaction(SIGTERM, &_action, &_term_old_action);
+       sigaction(SIGSYS, &_action, &_sys_old_action);
+       sigaction(SIGXCPU, &_action, &_xcpu_old_action);
+
+}
+
+static void _signal_finalize(void)
+{
+       sigaction(SIGINT, &_int_old_action, NULL);
+       sigaction(SIGABRT, &_abrt_old_action, NULL);
+       sigaction(SIGSEGV, &_segv_old_action, NULL);
+       sigaction(SIGTERM, &_term_old_action, NULL);
+       sigaction(SIGSYS, &_sys_old_action, NULL);
+       sigaction(SIGXCPU, &_xcpu_old_action, NULL);
+}
+
 int main(int argc, char **argv)
 {
        sem_t *sem = NULL;
@@ -145,12 +227,15 @@ int main(int argc, char **argv)
 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
        int pid;
 #endif
+       int socket_fd = -1;
 
        if (_get_option(argc, argv, &serveropt))
                return 1;
 
        debug_warning("focus_server [%d] init \n", getpid());
 
+       _signal_initialize();
+
        if (serveropt.startserver) {
                sem = _sem_create_n_wait();
        }
@@ -181,8 +266,17 @@ int main(int argc, char **argv)
        }
 #endif
        if (serveropt.startserver) {
+               if (MMSoundMgrFocusSocketInit(&socket_fd)) {
+                       debug_error("focus_server [%d] terminating, due to the error of socket init.\n", getpid());
+                       return 0;
+               }
+               if (MMSoundMgrFocusSocketReadyToWork(socket_fd)) {
+                       debug_error("focus_server [%d] terminating, due to the error of thread init.\n", getpid());
+                       return 0;
+               }
                MMSoundMgrFocusDbusInit();
                MMSoundMgrFocusInit();
+               g_socket_fd = socket_fd;
        }
 
        debug_warning("focus_server [%d] initialization complete...now, start running!!\n", getpid());
@@ -221,8 +315,11 @@ int main(int argc, char **argv)
        if (serveropt.startserver) {
                MMSoundMgrFocusDbusFini();
                MMSoundMgrFocusFini();
+               MMSoundMgrFocusSocketFini(socket_fd);
        }
 
+       _signal_finalize();
+
        debug_warning("focus_server [%d] exit ----------------- END \n", getpid());
 
        return 0;
index e0532de..bee6098 100644 (file)
@@ -1042,7 +1042,8 @@ int mm_sound_mgr_focus_request_acquire(const _mm_sound_mgr_focus_param_t *param)
 
        debug_fenter();
 
-       MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
+       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);
@@ -1073,14 +1074,15 @@ int mm_sound_mgr_focus_request_acquire(const _mm_sound_mgr_focus_param_t *param)
                        continue;
                if (param->request_type == FOCUS_TYPE_BOTH || node->status == FOCUS_STATUS_ACTIVATED_BOTH ||
                        (node->status & param->request_type)) {
-                       if (node->status > FOCUS_STATUS_DEACTIVATED) {
-                               if ((my_node->priority < node->priority)) {
-                                       ret = MM_ERROR_POLICY_BLOCKED;
-                                       need_to_trigger_cb = false;
-                                       break;
-                               } else {
-                                       need_to_trigger_cb = true;
-                               }
+                       if (node->status <= FOCUS_STATUS_DEACTIVATED)
+                               continue;
+
+                       if ((my_node->priority < node->priority)) {
+                               ret = MM_ERROR_POLICY_BLOCKED;
+                               need_to_trigger_cb = false;
+                               break;
+                       } else {
+                               need_to_trigger_cb = true;
                        }
                }
        }
@@ -1096,19 +1098,19 @@ int mm_sound_mgr_focus_request_acquire(const _mm_sound_mgr_focus_param_t *param)
                                continue;
                        if (param_s->request_type == FOCUS_TYPE_BOTH || node->status == FOCUS_STATUS_ACTIVATED_BOTH ||
                                (node->status & param_s->request_type)) {
-                               if (node->status > FOCUS_STATUS_DEACTIVATED) {
-                                       if (my_node->priority >= node->priority) {
-                                               /* do callback for interruption */
-                                               if ((ret = _mm_sound_mgr_focus_do_callback(FOCUS_COMMAND_RELEASE, node, param_s))) {
-                                                       debug_error("Fail to _focus_do_callback for COMMAND RELEASE to node[%x], ret[0x%x]\n", node, ret);
-                                                       /* but, keep going */
-                                                       ret = MM_ERROR_NONE;
-                                               }
-                                               if (!strncmp(my_node->stream_type, node->stream_type, MAX_STREAM_TYPE_LEN)) {
-                                                       need_to_trigger_watch_cb = false;
-                                               }
-                                               need_to_trigger_monitor_cb = false;
+                               if (node->status <= FOCUS_STATUS_DEACTIVATED)
+                                       continue;
+                               if (my_node->priority >= node->priority) {
+                                       /* do callback for interruption */
+                                       if ((ret = _mm_sound_mgr_focus_do_callback(FOCUS_COMMAND_RELEASE, node, param_s))) {
+                                               debug_error("Fail to _focus_do_callback for COMMAND RELEASE to node[%x], ret[0x%x]\n", node, ret);
+                                               /* but, keep going */
+                                               ret = MM_ERROR_NONE;
                                        }
+                                       if (!strncmp(my_node->stream_type, node->stream_type, MAX_STREAM_TYPE_LEN)) {
+                                               need_to_trigger_watch_cb = false;
+                                       }
+                                       need_to_trigger_monitor_cb = false;
                                }
                        }
                }
@@ -1143,7 +1145,8 @@ int mm_sound_mgr_focus_request_acquire(const _mm_sound_mgr_focus_param_t *param)
        _mm_sound_mgr_focus_list_dump();
        _mm_sound_mgr_focus_watch_list_dump ();
 FINISH:
-       MMSOUND_LEAVE_CRITICAL_SECTION(&g_focus_node_list_mutex);
+       if (!param->is_in_thread)
+               MMSOUND_LEAVE_CRITICAL_SECTION(&g_focus_node_list_mutex);
 
        debug_fleave();
        return ret;
@@ -1162,7 +1165,8 @@ int mm_sound_mgr_focus_request_release(const _mm_sound_mgr_focus_param_t *param)
 
        debug_fenter();
 
-       MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_focus_node_list_mutex, MM_ERROR_SOUND_INTERNAL);
+       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);
@@ -1255,7 +1259,8 @@ int mm_sound_mgr_focus_request_release(const _mm_sound_mgr_focus_param_t *param)
        _mm_sound_mgr_focus_list_dump();
        _mm_sound_mgr_focus_watch_list_dump ();
 FINISH:
-       MMSOUND_LEAVE_CRITICAL_SECTION(&g_focus_node_list_mutex);
+       if (!param->is_in_thread)
+               MMSOUND_LEAVE_CRITICAL_SECTION(&g_focus_node_list_mutex);
 
        debug_fleave();
        return ret;
index b89e4c3..0da1e67 100644 (file)
@@ -396,7 +396,8 @@ static void handle_method_acquire_focus(GDBusMethodInvocation* invocation)
        }
 
        g_variant_get(params, "(iiiisb)", &pid, &handle_id, &focus_type, &option, &ext_info, &is_for_session);
-       ret = __mm_sound_mgr_focus_ipc_acquire_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, focus_type, option, ext_info, is_for_session);
+       ret = __mm_sound_mgr_focus_ipc_acquire_focus((is_for_session) ? pid : _get_sender_pid(invocation),
+                                                    handle_id, focus_type, option, ext_info, false, is_for_session);
 
 send_reply:
        if (ret == MM_ERROR_NONE) {
@@ -425,7 +426,8 @@ static void handle_method_release_focus(GDBusMethodInvocation* invocation)
        }
 
        g_variant_get(params, "(iiiisb)", &pid, &handle_id, &focus_type, &option, &ext_info, &is_for_session);
-       ret = __mm_sound_mgr_focus_ipc_release_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, focus_type, option, ext_info, is_for_session);
+       ret = __mm_sound_mgr_focus_ipc_release_focus((is_for_session) ? pid : _get_sender_pid(invocation),
+                                                    handle_id, focus_type, option, ext_info, false, is_for_session);
 
 send_reply:
        if (ret == MM_ERROR_NONE) {
@@ -521,7 +523,6 @@ static void handle_method_call(GDBusConnection *connection,
        }
 }
 
-
 static GVariant* handle_get_property(GDBusConnection *connection,
                                                                        const gchar *sender,
                                                                        const gchar *object_path,
@@ -731,6 +732,3 @@ void MMSoundMgrFocusDbusFini(void)
 
        debug_leave();
 }
-
-
-
index 8a7ec1b..554723c 100644 (file)
@@ -99,7 +99,7 @@ int __mm_sound_mgr_focus_ipc_get_acquired_focus_stream_type(int focus_type, char
 }
 
 // method -> callback
-int __mm_sound_mgr_focus_ipc_acquire_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_for_session)
+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, bool is_for_session)
 {
        _mm_sound_mgr_focus_param_t param;
        int ret = MM_ERROR_NONE;
@@ -109,6 +109,7 @@ int __mm_sound_mgr_focus_ipc_acquire_focus(int pid, int handle_id, int focus_typ
        param.handle_id = handle_id;
        param.request_type = focus_type;
        param.option = option;
+       param.is_in_thread = is_in_thread;
        param.is_for_session = is_for_session;
        MMSOUND_STRNCPY(param.ext_info, ext_info, MM_SOUND_NAME_NUM);
 
@@ -118,7 +119,7 @@ int __mm_sound_mgr_focus_ipc_acquire_focus(int pid, int handle_id, int focus_typ
 }
 
 // method -> callback
-int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_for_session)
+int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_in_thread, bool is_for_session)
 {
        _mm_sound_mgr_focus_param_t param;
        int ret = MM_ERROR_NONE;
@@ -128,6 +129,7 @@ int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_typ
        param.handle_id = handle_id;
        param.request_type = focus_type;
        param.option = option;
+       param.is_in_thread = is_in_thread;
        param.is_for_session = is_for_session;
        MMSOUND_STRNCPY(param.ext_info, ext_info, MM_SOUND_NAME_NUM);
 
diff --git a/focus_server/mm_sound_mgr_focus_socket.c b/focus_server/mm_sound_mgr_focus_socket.c
new file mode 100644 (file)
index 0000000..8075892
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <mm_error.h>
+#include <mm_debug.h>
+
+#include <gio/gio.h>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "../include/mm_sound_focus_socket.h"
+#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);
+
+enum {
+       FOCUS_FUNCTION_ACQUIRE,
+       FOCUS_FUNCTION_RELEASE,
+       FOCUS_FUNCTION_MAX,
+};
+
+typedef struct mm_sound_focus_function_intf {
+       const char *name;
+       focus_function_handler handler;
+} mm_sound_focus_function_intf_t;
+
+static mm_sound_focus_function_intf_t functions[FOCUS_FUNCTION_MAX] = {
+       [FOCUS_FUNCTION_ACQUIRE] = {
+               .name = FOCUS_FUNC_NAME_ACQUIRE,
+               .handler = handle_acquire_focus
+       },
+       [FOCUS_FUNCTION_RELEASE] = {
+               .name = FOCUS_FUNC_NAME_RELEASE,
+               .handler = handle_release_focus
+       },
+};
+
+static const char* convert_error_string_from_int(int error)
+{
+       switch (error) {
+       case MM_ERROR_NONE:
+               return FOCUS_ERROR_NONE;
+
+       case MM_ERROR_INVALID_ARGUMENT:
+               return FOCUS_ERROR_INVALID_PARAMETER;
+
+       case MM_ERROR_POLICY_BLOCKED:
+       case MM_ERROR_POLICY_INTERNAL:
+               return FOCUS_ERROR_POLICY;
+
+       case MM_ERROR_SOUND_INVALID_STATE:
+               return FOCUS_ERROR_INVALID_STATE;
+
+       case MM_ERROR_SOUND_INTERNAL:
+               return FOCUS_ERROR_INTERNAL;
+
+       default:
+               return FOCUS_ERROR_INTERNAL;
+       }
+}
+
+static int handle_acquire_focus(_mm_sound_mgr_focus_socket_param_t *param)
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       ret = __mm_sound_mgr_focus_ipc_acquire_focus(param->pid, param->handle_id, param->focus_type,
+                                                    param->option, param->ext_info, true, param->is_for_session);
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int handle_release_focus(_mm_sound_mgr_focus_socket_param_t *param)
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       ret = __mm_sound_mgr_focus_ipc_release_focus(param->pid, param->handle_id, param->focus_type,
+                                                    param->option, param->ext_info, true, param->is_for_session);
+
+       debug_fleave();
+
+       return ret;
+}
+
+static int focus_functions_handler(_mm_sound_mgr_focus_socket_param_t *param)
+{
+       int i = 0;
+       int ret = MM_ERROR_SOUND_INTERNAL;
+
+       if (param == NULL)
+               return MM_ERROR_SOUND_INTERNAL;
+
+       debug_log("param[%p], function_name[%s]", 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);
+       }
+
+       return ret;
+}
+
+static void *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;
+       int rval = 0;
+       char ret_buf[MAX_ERROR_LEN] = {'\0',};
+
+       if (data == NULL) {
+               debug_error("invalid data\n");
+               pthread_exit(NULL);
+       }
+
+       fd = (int)data;
+
+       if (listen(fd, 5)) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               debug_error("failed to listen(), err: %s", str_error);
+               goto LEAVE;
+       }
+       debug_log("listen for fd [%d] success", fd);
+
+       do {
+               accepted_fd = accept(fd, NULL, NULL);
+               if (accepted_fd == -1) {
+                       strerror_r(errno, str_error, sizeof(str_error));
+                       debug_error("failed to accept(), err: %s", str_error);
+                       goto LEAVE;
+               }
+
+               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..\n");
+                       debug_log(" : pid[%d], handle_id[%d], focus_type[%d]\n", read_data.pid, read_data.handle_id, read_data.focus_type);
+                       debug_log(" : option[%d], ext_info[%s], is_for_session[%d]\n", read_data.option, read_data.ext_info, read_data.is_for_session);
+
+                       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\n", 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));
+               }
+
+               close(accepted_fd);
+       } while (1);
+
+LEAVE:
+       close(fd);
+       pthread_exit(NULL);
+}
+
+int MMSoundMgrFocusSocketInit(int *fd)
+{
+       int socket_fd;
+       struct sockaddr_un addr_un;
+       char str_error[128] = {'\0',};
+
+       if (fd == NULL) {
+               debug_error("input param fd is null\n");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (socket_fd < 0) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               debug_error("failed to socket(), err: %s\n", str_error);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       debug_log("focus server socket fd [%d]", socket_fd);
+
+       memset(&addr_un, 0, sizeof(addr_un));
+       addr_un.sun_family = AF_UNIX;
+       strncpy(addr_un.sun_path, FOCUS_SERVER_SOCK, sizeof(addr_un.sun_path));
+
+       if (bind(socket_fd, (struct sockaddr *)&addr_un, sizeof(addr_un))) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               debug_error("failed to bind(), err: %s\n", str_error);
+               if (errno == EADDRINUSE) {
+                       unlink(FOCUS_SERVER_SOCK);
+                       debug_msg("unlink socket and bind again...\n");
+                       if (bind(socket_fd, (struct sockaddr *)&addr_un, sizeof(addr_un))) {
+                               strerror_r(errno, str_error, sizeof(str_error));
+                               debug_error("failed to bind() again, err: %s\n", str_error);
+                               close(socket_fd);
+                               return MM_ERROR_SOUND_INTERNAL;
+                       }
+               } else {
+                       close(socket_fd);
+                       return MM_ERROR_SOUND_INTERNAL;
+               }
+       }
+
+       debug_log("focus server socket binding success");
+
+       *fd = socket_fd;
+
+       debug_leave();
+
+       return MM_ERROR_NONE;
+}
+
+void MMSoundMgrFocusSocketFini(int fd)
+{
+       debug_enter();
+
+       if (g_focus_work_thread_id) {
+               unlink(FOCUS_SERVER_SOCK);
+               shutdown(fd,SHUT_RDWR);
+               close(fd);
+               pthread_join(g_focus_work_thread_id, NULL);
+               debug_msg("pthread join well");
+               g_focus_work_thread_id = 0;
+       }
+
+       debug_leave();
+}
+
+int MMSoundMgrFocusSocketReadyToWork(int fd)
+{
+       debug_enter();
+
+       if (fd < 0) {
+               debug_error("input param fd [%d] is not valid\n", fd);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       debug_log("fd [%d]\n", fd);
+       if (pthread_create(&g_focus_work_thread_id, NULL, (void *)thread_func, (void *)fd)) {
+               debug_error("failed to start work thread");
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       debug_leave();
+
+       return MM_ERROR_NONE;
+}
diff --git a/include/mm_sound_focus_socket.h b/include/mm_sound_focus_socket.h
new file mode 100644 (file)
index 0000000..c4c6e16
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef        __MM_SOUND_FOCUS_SOCKET_H__
+#define        __MM_SOUND_FOCUS_SOCKET_H__
+
+#ifdef __cplusplus
+       extern "C" {
+#endif
+
+#include "include/mm_sound.h"
+#include "include/mm_sound_focus.h"
+
+#define FOCUS_SERVER_SOCK "/tmp/.focus_server.socket"
+#define MAX_ERROR_LEN 64
+
+typedef struct {
+       char func_name[MM_SOUND_NAME_NUM];
+       int pid;
+       int handle_id;
+       mm_sound_focus_type_e focus_type;
+       int option;
+       char ext_info[MM_SOUND_NAME_NUM];
+       bool is_in_thread;                 /* Called within focus callback thread */
+       bool is_for_session;               /* will be removed when the session concept is completely left out*/
+} _mm_sound_mgr_focus_socket_param_t;
+
+/* Function names */
+#define FOCUS_FUNC_NAME_ACQUIRE          "AcquireFocus"
+#define FOCUS_FUNC_NAME_RELEASE          "ReleaseFocus"
+
+/* Error defines */
+#define FOCUS_ERROR_NONE                 "error_none"
+#define FOCUS_ERROR_INVALID_PARAMETER    "error_invalid_parameter"
+#define FOCUS_ERROR_POLICY               "error_policy"
+#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, bool is_for_session);
+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, bool is_for_session);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_SOUND_FOCUS_SOCKET_H__ */
+
index 1887456..ffcd894 100644 (file)
@@ -334,8 +334,6 @@ int mm_sound_acquire_focus_with_option(int id, mm_sound_focus_type_e focus_type,
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
-
        if (id < 0) {
                debug_error("id is not valid\n");
                return MM_ERROR_INVALID_ARGUMENT;
@@ -368,8 +366,6 @@ int mm_sound_release_focus_with_option(int id, mm_sound_focus_type_e focus_type,
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
-
        if (id < 0) {
                debug_error("id is not valid\n");
                return MM_ERROR_INVALID_ARGUMENT;
diff --git a/mm_sound_focus_socket.c b/mm_sound_focus_socket.c
new file mode 100644 (file)
index 0000000..5bbffdc
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <mm_debug.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "include/mm_sound.h"
+#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, x_is_for_session) \
+do { \
+       MMSOUND_STRNCPY(x_param.func_name, x_func_name, MM_SOUND_NAME_NUM); \
+       x_param.pid = x_instance; \
+       x_param.handle_id = 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; \
+       x_param.is_for_session = x_is_for_session; \
+} while(0) \
+
+static int _convert_error_from_string(const char *error_string)
+{
+       int ret = MM_ERROR_NONE;
+
+       if (error_string == NULL) {
+               debug_error("error_string is null\n");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       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;
+
+       debug_msg("error_string[%s], ret[0x%x]\n", error_string, ret);
+
+       return ret;
+}
+
+static int _get_client_socket_fd(int *fd)
+{
+       int socket_fd;
+       char str_error[128] = {'\0',};
+
+       if (fd == NULL) {
+               debug_error("input param fd is null\n");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (socket_fd < 0) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               debug_error("failed to socket(), err: %s", str_error);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       debug_log("focus client socket fd[%d]", socket_fd);
+
+       *fd = socket_fd;
+
+       return MM_ERROR_NONE;
+}
+
+static int _connect_socket_fd(int fd)
+{
+       struct sockaddr_un addr_un;
+       char str_error[128] = {'\0',};
+
+       if (fd < 0) {
+               debug_error("invalid fd[%d]\n", fd);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       memset(&addr_un, 0, sizeof(addr_un));
+       addr_un.sun_family = AF_UNIX;
+       strncpy(addr_un.sun_path, FOCUS_SERVER_SOCK, sizeof(addr_un.sun_path));
+
+       if (connect(fd, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0) {
+               strerror_r(errno, str_error, sizeof(str_error));
+               debug_error("failed to connect() to %s, err: %s", addr_un.sun_path, fd, str_error);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       debug_log("connected successfully, fd[%d]", fd);
+
+       return MM_ERROR_NONE;
+}
+
+static int _send_data_to_server(int fd, _mm_sound_mgr_focus_socket_param_t *data)
+{
+       char str_error[MAX_ERROR_LEN] = {'\0',};
+       char ret_buf[MAX_ERROR_LEN] = {'\0',};
+       int rval = 0;
+
+       if (fd < 0 || data == NULL) {
+               debug_error("invalid parameter, fd[%d], data[%p]", fd, data);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (write(fd, data, sizeof(_mm_sound_mgr_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) {
+               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);
+
+       return _convert_error_from_string(ret_buf);
+}
+
+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, bool is_for_session)
+{
+       int ret = MM_ERROR_NONE;
+       int fd = -1;
+       _mm_sound_mgr_focus_socket_param_t data;
+
+       debug_fenter();
+
+       if (instance <= 0 || id < 0 || option < 0) {
+               debug_error("invalid parameter, instance[%d], id[%d], option[%d]", instance, id, 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;
+       }
+
+       if ((ret = _get_client_socket_fd(&fd))) {
+               debug_error("failed to _get_client_socket_fd()\n");
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+       if ((ret = _connect_socket_fd(fd))) {
+               debug_error("failed to _connect_socket_fd()\n");
+               close(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, is_for_session);
+
+       if ((ret = _send_data_to_server(fd, &data))) {
+               debug_error("failed to _send_data_to_server(), ret[0x%x]\n", ret);
+               close(fd);
+               return ret;
+       }
+
+       close(fd);
+
+       debug_fleave();
+
+       return MM_ERROR_NONE;
+}
+
+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, bool is_for_session)
+{
+       int ret = MM_ERROR_NONE;
+       int fd = -1;
+       _mm_sound_mgr_focus_socket_param_t data;
+
+       debug_fenter();
+
+       if (instance <= 0 || id < 0 || option < 0) {
+               debug_error("invalid parameter, instance[%d], id[%d], option[%d]", instance, id, option);
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
+               debug_error("focus type is not valid\n");
+               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;
+       }
+       if ((ret = _connect_socket_fd(fd))) {
+               debug_error("failed to _connect_socket_fd()");
+               close(fd);
+               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, is_for_session);
+
+       if ((ret = _send_data_to_server(fd, &data))) {
+               debug_error("failed to _send_data_to_server()");
+               close(fd);
+               return MM_ERROR_SOUND_INTERNAL;
+       }
+
+       close(fd);
+
+       debug_fleave();
+
+       return ret;
+}
index 7ff503d..d36e7ea 100644 (file)
@@ -8,6 +8,7 @@
 #include "include/mm_sound_common.h"
 #include "include/mm_sound_dbus.h"
 #include "include/mm_sound_intf.h"
+#include "include/mm_sound_focus_socket.h"
 
 struct callback_data {
        void *user_cb;
@@ -45,9 +46,8 @@ static int _notify_subscription(audio_event_t event, uint32_t subs_id, gboolean
                return MM_ERROR_SOUND_INTERNAL;
        }
 
-       if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_CLIENT_SUBSCRIBED, params))) {
+       if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_CLIENT_SUBSCRIBED, params)))
                debug_error("dbus send signal for client subscribed failed");
-       }
 
        debug_fleave();
        return ret;
@@ -248,9 +248,8 @@ int mm_sound_proxy_remove_test_callback(unsigned subs_id)
        int ret = MM_ERROR_NONE;
        debug_fenter();
 
-       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
+       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
                debug_error("remove test callback failed");
-       }
 
        debug_fleave();
        return ret;
@@ -458,9 +457,8 @@ int mm_sound_proxy_remove_device_info_changed_callback(unsigned subs_id)
        int ret = MM_ERROR_NONE;
        debug_fenter();
 
-       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
+       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
                debug_error("remove device info changed callback failed");
-       }
 
        debug_fleave();
        return ret;
@@ -489,9 +487,8 @@ int mm_sound_proxy_remove_device_state_changed_callback(unsigned subs_id)
        int ret = MM_ERROR_NONE;
        debug_fenter();
 
-       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
+       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
                debug_error("remove device state changed callback failed");
-       }
 
        debug_fleave();
        return ret;
@@ -558,9 +555,8 @@ int mm_sound_proxy_remove_volume_changed_callback(unsigned subs_id)
        int ret = MM_ERROR_NONE;
        debug_fenter();
 
-       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
+       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
                debug_error("Remove Volume changed callback failed");
-       }
 
        debug_fleave();
        return ret;
@@ -691,7 +687,7 @@ int mm_sound_proxy_play_tone(int tone, int repeat, int volume, int volume_config
        debug_fenter();
 
        params = g_variant_new("(iiiiiiibsi)", tone, repeat, volume, volume_config, session_type,
-                     session_options, client_pid , _enable_session, stream_type, stream_index);
+                              session_options, client_pid , _enable_session, stream_type, stream_index);
        if (params) {
                if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_DTMF, params, &result)) != MM_ERROR_NONE) {
                        debug_error("dbus play tone failed");
@@ -868,9 +864,8 @@ int mm_sound_proxy_clear_focus(int pid)
 
        debug_fenter();
 
-       if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_CLEAR_FOCUS, g_variant_new("(i)", pid), &result)) != MM_ERROR_NONE) {
+       if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_CLEAR_FOCUS, g_variant_new("(i)", pid), &result)) != MM_ERROR_NONE)
                debug_error("dbus clear focus failed");
-       }
 
        if (result)
                g_variant_unref(result);
@@ -903,9 +898,8 @@ int mm_sound_proxy_remove_play_sound_end_callback(unsigned subs_id)
        int ret = MM_ERROR_NONE;
        debug_fenter();
 
-       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
+       if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
                debug_error("Remove Play File End callback failed");
-       }
 
        debug_fleave();
        return ret;
@@ -946,9 +940,8 @@ int mm_sound_proxy_get_unique_id(int *id)
 
        debug_fenter();
 
-       if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_UNIQUE_ID, NULL, &result)) != MM_ERROR_NONE) {
+       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);
@@ -971,9 +964,8 @@ int mm_sound_proxy_register_focus(int id, int instance, const char *stream_type,
 
        params = g_variant_new("(iisb)", instance, id, stream_type, is_for_session);
        if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_REGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
+               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");
        }
@@ -998,9 +990,8 @@ int mm_sound_proxy_unregister_focus(int instance, int id, bool is_for_session)
 
        params = g_variant_new("(iib)", instance, id, is_for_session);
        if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNREGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
+               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");
        }
@@ -1024,9 +1015,8 @@ int mm_sound_proxy_set_focus_reacquisition(int instance, int id, bool reacquisit
 
        params = g_variant_new("(iibb)", instance, id, reacquisition, is_for_session);
        if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_SET_FOCUS_REACQUISITION, params, &result)) != MM_ERROR_NONE) {
+               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");
        }
@@ -1068,23 +1058,30 @@ int mm_sound_proxy_get_acquired_focus_stream_type(int focus_type, char **stream_
 int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info, bool is_for_session)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
+       bool is_in_focus_cb_thread = false;
 
        debug_fenter();
 
-       params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
-       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");
-               }
+       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, is_for_session)))
+                       debug_error("failed to mm_sound_focus_socket_acquire(), ret[0x%x]", ret);
        } else {
-               debug_error("Construct Param for method call failed");
-       }
+               GVariant *params = NULL, *result = NULL;
 
-       if (ret != MM_ERROR_NONE)
-               g_variant_get(result, "(i)",  &ret);
-       if (result)
-               g_variant_unref(result);
+               params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
+               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");
+               } 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;
@@ -1093,23 +1090,30 @@ int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e typ
 int mm_sound_proxy_release_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info, bool is_for_session)
 {
        int ret = MM_ERROR_NONE;
-       GVariant *params = NULL, *result = NULL;
+       bool is_in_focus_cb_thread = false;
 
        debug_fenter();
 
-       params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
-       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");
-               }
+       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, is_for_session)))
+                       debug_error("failed to mm_sound_focus_socket_release(), ret[0x%x]", ret);
        } else {
-               debug_error("Construct Param for method call failed");
-       }
+               GVariant *params = NULL, *result = NULL;
 
-       if (ret != MM_ERROR_NONE)
-               g_variant_get(result, "(i)",  &ret);
-       if (result)
-               g_variant_unref(result);
+               params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
+               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");
+               } 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;
@@ -1160,9 +1164,8 @@ int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_f
 
        params = g_variant_new("(iiibb)", instance, handle, type, is_for_session, is_for_monitor);
        if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
+               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");
-               }
        } else {
                debug_error("Construct Param for method call failed");
        }
@@ -1186,9 +1189,8 @@ int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle, bool is
 
        params = g_variant_new("(iib)", focus_tid, handle, is_for_session);
        if (params) {
-               if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNWATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
+               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");
        }
index fdea431..b2d362c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-sound
 Summary:    MMSound Package contains client lib and sound_server binary
-Version:    0.10.116
+Version:    0.11.1
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
@@ -151,6 +151,7 @@ ln -sf ../focus-server.path %{buildroot}%{_unitdir}/multi-user.target.wants/focu
 %{_includedir}/mmf/mm_sound.h
 %{_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_pa_client.h
 %{_libdir}/pkgconfig/mm-keysound.pc
 %{_libdir}/pkgconfig/mm-bootsound.pc