focus_server: Add support for delivery focus to another node 87/133687/3
authorSangchul Lee <sc11.lee@samsung.com>
Mon, 12 Jun 2017 02:51:42 +0000 (11:51 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 15 Jun 2017 01:23:31 +0000 (10:23 +0900)
[Version] 0.11.7
[Profile] Common
[Issue Type] New feature

Change-Id: I685153d97900881e07b0c95e6c405e335da8cf99
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
14 files changed:
common/mm_sound_dbus.c
focus_server/include/mm_sound_mgr_focus.h
focus_server/include/mm_sound_mgr_focus_ipc.h
focus_server/mm_sound_mgr_focus.c
focus_server/mm_sound_mgr_focus_dbus.c
focus_server/mm_sound_mgr_focus_ipc.c
include/mm_sound_client.h
include/mm_sound_focus.h
include/mm_sound_intf.h
include/mm_sound_proxy.h
mm_sound_client.c
mm_sound_focus.c
mm_sound_proxy.c
packaging/libmm-sound.spec

index 9e63056..8687db4 100644 (file)
@@ -117,6 +117,9 @@ const mm_sound_dbus_method_info_t g_methods[AUDIO_METHOD_MAX] = {
        [AUDIO_METHOD_UNWATCH_FOCUS] = {
                .name = "UnwatchFocus",
        },
+       [AUDIO_METHOD_DELIVER_FOCUS] = {
+               .name = "DeliverFocus",
+       },
        [AUDIO_METHOD_SET_FILTER] = {
                .name = "SetFilter",
        },
index d8dfcb2..5eab71b 100644 (file)
@@ -59,6 +59,7 @@ typedef struct {
        void *cbdata;
        bool reacquisition;
        bool is_in_thread;
+       int handle_id_dst;
 
        /* It will be removed when the session concept is completely left out*/
        bool is_for_session;
@@ -96,14 +97,15 @@ typedef struct {
 
 int MMSoundMgrFocusInit(void);
 int MMSoundMgrFocusFini(void);
-int mm_sound_mgr_focus_create_node (const _mm_sound_mgr_focus_param_t *param);
-int mm_sound_mgr_focus_destroy_node (const _mm_sound_mgr_focus_param_t *param);
-int mm_sound_mgr_focus_set_reacquisition (const _mm_sound_mgr_focus_param_t *param);
+int mm_sound_mgr_focus_create_node(const _mm_sound_mgr_focus_param_t *param);
+int mm_sound_mgr_focus_destroy_node(const _mm_sound_mgr_focus_param_t *param);
+int mm_sound_mgr_focus_set_reacquisition(const _mm_sound_mgr_focus_param_t *param);
 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_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_deliver(const _mm_sound_mgr_focus_param_t *param);
 int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param);
 
 #endif /* __MM_SOUND_MGR_FOCUS_H__ */
index 1fd875f..1d67076 100644 (file)
 #include <stdbool.h>
 
 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_unregister_focus(int pid, int handle_id, 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_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);
+int __mm_sound_mgr_focus_ipc_deliver_focus(int pid, int src_handle_id, int dst_handle_id, int focus_type);
 int __mm_sound_mgr_focus_ipc_emergent_exit(int pid);
 
 #endif /* __MM_SOUND_MGR_FOCUS_IPC_H__ */
index e8f67d7..95e385b 100644 (file)
@@ -1360,6 +1360,104 @@ FINISH:
        return ret;
 }
 
+int mm_sound_mgr_focus_deliver(const _mm_sound_mgr_focus_param_t *param)
+{
+       int ret = MM_ERROR_NONE;
+       GList *list = NULL;
+       focus_node_t *src_node = NULL;
+       focus_node_t *dst_node = NULL;
+       int i = 0;
+
+       debug_fenter();
+
+       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) {
+               if (!(src_node = (focus_node_t *)list->data))
+                       continue;
+               if ((src_node->pid == param->pid) && (src_node->handle_id == param->handle_id)) {
+                       debug_log("SRC: found the node of pid[%d]/handle_id[%d] for watch focus\n",
+                                 param->pid, param->handle_id);
+                       break;
+               }
+       }
+       if (src_node == NULL) {
+               debug_error("could not find the source node of param, pid[%d]/handle_id[%d]\n",
+                           param->pid, param->handle_id);
+               ret = MM_ERROR_INVALID_ARGUMENT;
+               goto FINISH;
+       }
+
+       if (!(src_node->status & param->request_type)) {
+               debug_error("invalid request type(0x%x), src_node->status(0x%x)\n",
+                           param->request_type, src_node->status);
+               ret = MM_ERROR_SOUND_INVALID_STATE;
+               goto FINISH;
+       }
+
+       for (list = g_focus_node_list; list != NULL; list = list->next) {
+               if (!(dst_node = (focus_node_t *)list->data))
+                       continue;
+               if ((dst_node->pid == param->pid) && (dst_node->handle_id == param->handle_id_dst)) {
+                       debug_log("DST: found the destination node of param, pid[%d]/handle_id[%d]\n",
+                                 param->pid, param->handle_id_dst);
+                       break;
+               }
+       }
+       if (dst_node == NULL) {
+               debug_error("could not find the destination node of param, pid[%d]/handle_id[%d]\n",
+                           param->pid, param->handle_id_dst);
+               ret = MM_ERROR_INVALID_ARGUMENT;
+               goto FINISH;
+       }
+
+       for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
+               focus_node_t *node = NULL;
+               if (!(param->request_type & (i+1)))
+                       continue;
+
+               for (list = g_focus_node_list; list != NULL; list = list->next) {
+                       if (!(node = (focus_node_t *)list->data))
+                               continue;
+                       if ((node->taken_by_id[i].pid == src_node->pid) &&
+                           (node->taken_by_id[i].handle_id == src_node->handle_id) &&
+                           (node->taken_by_id[i].by_session == false)) {
+                               debug_log("found the node that focus was taken by this src node, update it\n",
+                                         node->pid, node->handle_id);
+                               UPDATE_FOCUS_TAKEN_INFO(by_id, node, dst_node->pid, dst_node->handle_id, false);
+                       }
+                       if ((node->taken_backup[i].pid == src_node->pid) &&
+                           (node->taken_backup[i].handle_id == src_node->handle_id) &&
+                           (node->taken_backup[i].by_session == false)) {
+                               debug_log("found the node that focus was taken by this src node and set reacquisition to false, update it\n",
+                                         node->pid, node->handle_id);
+                               UPDATE_FOCUS_TAKEN_INFO(backup, node, dst_node->pid, dst_node->handle_id, false);
+                       }
+               }
+
+               dst_node->status |= (i+1);
+               UPDATE_FOCUS_TAKEN_INFO(by_id, dst_node, 0, 0, false);
+               UPDATE_FOCUS_TAKEN_INFO(backup, dst_node, 0, 0, false);
+               MMSOUND_STRNCPY(dst_node->ext_info[i], src_node->ext_info[i], MM_SOUND_NAME_NUM);
+               dst_node->option[i] = src_node->option[i];
+
+               src_node->status &= ~(i+1);
+               memset(src_node->ext_info[i], 0x0, MM_SOUND_NAME_NUM);
+               src_node->option[i] = 0;
+       }
+
+       _mm_sound_mgr_focus_list_dump();
+
+FINISH:
+       MMSOUND_LEAVE_CRITICAL_SECTION(&g_focus_node_list_mutex);
+
+       debug_fleave();
+       return ret;
+}
+
 int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param)
 {
        int ret = MM_ERROR_NONE;
index 0da1e67..da00c31 100644 (file)
@@ -74,6 +74,12 @@ static const gchar introspection_xml[] =
   "      <arg name='handle_id' type='i' direction='in'/>"
   "      <arg name='is_for_session' type='b' direction='in'/>"
   "    </method>"
+  "    <method name='DeliverFocus'>"
+  "      <arg name='pid' type='i' direction='in'/>"
+  "      <arg name='src_handle_id' type='i' direction='in'/>"
+  "      <arg name='dst_handle_id' type='i' direction='in'/>"
+  "      <arg name='focus_type' type='i' direction='in'/>"
+  "    </method>"
   "    <method name='EmergentExitFocus'>"
   "      <arg name='pid' type='i' direction='in'/>"
   "    </method>"
@@ -103,6 +109,7 @@ 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 */
@@ -162,6 +169,12 @@ static mm_sound_dbus_method_intf_t methods[AUDIO_METHOD_MAX] = {
                        .name = "UnwatchFocus",
                },
                .handler = handle_method_unwatch_focus
+       },
+       [AUDIO_METHOD_DELIVER_FOCUS] = {
+               .info = {
+                       .name = "DeliverFocus",
+               },
+               .handler = handle_method_deliver_focus
        }
 };
 
@@ -498,6 +511,36 @@ send_reply:
        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,
index 554723c..3319daf 100644 (file)
@@ -170,6 +170,22 @@ int __mm_sound_mgr_focus_ipc_unwatch_focus(int pid, int handle_id)
        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;
+       int ret = MM_ERROR_NONE;
+
+       memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
+       param.pid = pid;
+       param.handle_id = src_handle_id;
+       param.handle_id_dst = dst_handle_id;
+       param.request_type = focus_type;
+
+       ret = mm_sound_mgr_focus_deliver(&param);
+
+       return ret;
+}
+
 int __mm_sound_mgr_focus_ipc_emergent_exit(int pid)
 {
        _mm_sound_mgr_focus_param_t param;
index 242b926..3d1c23c 100644 (file)
@@ -70,6 +70,7 @@ 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_set_focus_watch_callback(int pid, mm_sound_focus_type_e type, bool is_for_session, bool is_for_monitor, 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);
index 2fddb15..3af91e1 100644 (file)
@@ -62,6 +62,7 @@ int mm_sound_release_focus(int id, mm_sound_focus_type_e focus_type, const char
 int mm_sound_acquire_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info);
 int mm_sound_release_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info);
 int mm_sound_update_focus_status(int id, unsigned int status);
+int mm_sound_deliver_focus(int src_id, int dst_id, mm_sound_focus_type_e focus_type);
 
 typedef void (*mm_sound_focus_changed_watch_cb) (int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *ext_info, void *user_data);
 int mm_sound_set_focus_watch_callback(mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id);
index a231505..a235f2b 100644 (file)
@@ -69,6 +69,7 @@ typedef enum audio_method {
        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,
index 36cc4c0..32031c5 100644 (file)
@@ -78,6 +78,7 @@ 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 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 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, bool is_for_session, bool is_for_monitor, mm_sound_focus_changed_watch_cb callback, void *user_data);
 int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle, bool is_for_session);
 #endif
index 3df3767..de07557 100644 (file)
@@ -2074,6 +2074,18 @@ 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 ret = MM_ERROR_NONE;
+       debug_fenter();
+
+       if ((ret = mm_sound_proxy_deliver_focus(pid, src_id, dst_id, focus_type)) != MM_ERROR_NONE)
+               debug_error("[Client] failed to deliver focus, ret[0x%x]", ret);
+
+       debug_fleave();
+       return ret;
+}
+
 int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e focus_type, bool is_for_session, bool is_for_monitor,
                                              mm_sound_focus_changed_watch_cb callback, void* user_data, int *id)
 {
index ffcd894..46dbfc0 100644 (file)
@@ -404,6 +404,17 @@ int mm_sound_update_focus_status(int id, unsigned int status)
 }
 
 EXPORT_API
+int mm_sound_deliver_focus(int src_id, int dst_id, mm_sound_focus_type_e focus_type)
+{
+       int ret = MM_ERROR_NONE;
+
+       if ((ret = mm_sound_client_deliver_focus(getpid(), src_id, dst_id, focus_type)))
+               debug_error("failed to mm_sound_client_deliver_focus(), ret[0x%x]\n", ret);
+
+       return ret;
+}
+
+EXPORT_API
 int mm_sound_set_focus_watch_callback(mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
index 9eb678b..603434c 100644 (file)
@@ -1191,23 +1191,49 @@ int mm_sound_proxy_update_stream_focus_status(int focus_id, unsigned int status)
        if (params) {
                if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_UPDATE_STREAM_FOCUS_STATUS, params, &result)) != MM_ERROR_NONE) {
                        debug_error("dbus set volume by type failed");
-                       goto cleanup;
+                       if (result) {
+                               g_variant_get(result, "(&s)",  &reply);
+                               debug_log("reply : %s", reply);
+                               if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
+                                       ret = MM_ERROR_SOUND_INTERNAL;
+                       }
                }
        } else {
                debug_error("Construct Param for method call failed");
                return MM_ERROR_SOUND_INTERNAL;
        }
 
-       if (result) {
-               g_variant_get(result, "(&s)",  &reply);
-               debug_log("reply : %s", reply);
-               if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
-                       ret = MM_ERROR_SOUND_INTERNAL;
+       if (result)
+               g_variant_unref(result);
+
+       debug_fleave();
+       return ret;
+}
+
+int mm_sound_proxy_deliver_focus(int pid, int src_id, int dst_id, mm_sound_focus_type_e focus_type)
+{
+       int ret = MM_ERROR_NONE;
+       char *reply = NULL;
+       GVariant *params = NULL, *result = NULL;
+
+       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_ERROR"))
+                                       ret = MM_ERROR_SOUND_INTERNAL;
+                       }
+               }
        } else {
-               debug_error("reply null");
+               debug_error("Construct Param for method call failed");
+               return MM_ERROR_SOUND_INTERNAL;
        }
 
-cleanup:
        if (result)
                g_variant_unref(result);
 
index c229e31..b7ea416 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-sound
 Summary:    MMSound Package contains client lib and sound_server binary
-Version:    0.11.6
+Version:    0.11.7
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0