Improve focus auto reacquisition 35/52635/6 accepted/tizen/mobile/20151204.062425 accepted/tizen/tv/20151204.062503 accepted/tizen/wearable/20151204.062518 submit/tizen/20151204.015602
authorinhyeok <i_bc.kim@samsung.com>
Wed, 25 Nov 2015 08:21:31 +0000 (17:21 +0900)
committerinhyeok <i_bc.kim@samsung.com>
Tue, 1 Dec 2015 02:22:34 +0000 (11:22 +0900)
[Version] Release 0.2.274
[Profile] Common
[Issue Type] Add feature

Append its "taken info" to victim node when focus auto reacqusition is disabled.

Change-Id: I50790937efb0463999d9949b934f3750937933d2
Signed-off-by: inhyeok <i_bc.kim@samsung.com>
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_dbus.h
include/mm_sound_msg.h
mm_sound_client.c
mm_sound_client_dbus.c
packaging/libmm-sound.spec

index 4108a99..a30cfdb 100644 (file)
@@ -57,6 +57,7 @@ typedef struct {
        focus_type_e request_type;
        void *callback;
        void *cbdata;
+       bool reacquisition;
 
        bool is_for_session;    /* will be removed when the session concept is completely left out*/
 } _mm_sound_mgr_focus_param_t;
@@ -78,6 +79,7 @@ typedef struct {
        _focus_taken_by_id_t taken_by_id[NUM_OF_STREAM_IO_TYPE];
        void *callback;
        void *cbdata;
+       bool reacquisition;
 
        bool is_for_session;    /* will be removed when the session concept is completely left out*/
 
@@ -90,6 +92,7 @@ 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_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);
index 8d8eed8..cba6ee0 100644 (file)
@@ -41,6 +41,8 @@ int __mm_sound_mgr_focus_ipc_register_focus(int client_pid, int handle_id, const
 //int __mm_sound_mgr_ipc_destroy_focus_node(mm_ipc_msg_t *msg);
 int __mm_sound_mgr_focus_ipc_unregister_focus(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_acquire_focus(int pid, int handle_id, int focus_type, const char* name );
 
 int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_type, const char* name);
index 553fea7..3efb9de 100644 (file)
@@ -395,7 +395,6 @@ int _mm_sound_mgr_focus_do_callback(focus_command_e command, focus_node_t *victi
        int taken_pid = 0;
        int taken_hid = 0;
        int ret_handle = -1;
-       bool auto_reacquire = true;
        bool taken_by_session = false;
 
        focus_cb_data cb_data;
@@ -492,7 +491,7 @@ int _mm_sound_mgr_focus_do_callback(focus_command_e command, focus_node_t *victi
                        goto fail;
                }
                ret_handle = (int)(ret & 0x0000ffff);
-               auto_reacquire = (bool)((ret >> 16) & 0xf);
+               victim_node->reacquisition= (bool)((ret >> 16) & 0xf);
        }
        g_free(filename2);
        filename2 = NULL;
@@ -513,31 +512,43 @@ int _mm_sound_mgr_focus_do_callback(focus_command_e command, focus_node_t *victi
        }
        //debug_log("[RETCB] Return value 0x%x\n", buf);
 
-       if (auto_reacquire) {
-               /* update victim node */
-               if (command == FOCUS_COMMAND_RELEASE) {
-                       taken_pid = assaulter_param->pid;
-                       taken_hid = assaulter_param->handle_id;
-                       taken_by_session = assaulter_param->is_for_session;
-                       flag_for_taken_index = assaulter_param->request_type & victim_node->status;
-               } else {
-                       taken_pid = 0;
-                       taken_hid = 0;
-                       taken_by_session = false;
-                       flag_for_taken_index = assaulter_param->request_type;
-               }
+       /* update victim node */
+       if (command == FOCUS_COMMAND_RELEASE) {
+               taken_pid = assaulter_param->pid;
+               taken_hid = assaulter_param->handle_id;
+               taken_by_session = assaulter_param->is_for_session;
+               flag_for_taken_index = assaulter_param->request_type & victim_node->status;
+       } else {
+               taken_pid = 0;
+               taken_hid = 0;
+               taken_by_session = false;
+               flag_for_taken_index = assaulter_param->request_type;
+       }
 
-               for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
-                       if (flag_for_taken_index & (i+1)) {
-                               if (command == FOCUS_COMMAND_ACQUIRE && (victim_node->taken_by_id[i].pid != assaulter_param->pid || (victim_node->taken_by_id[i].handle_id != assaulter_param->handle_id && !(victim_node->taken_by_id[i].by_session & assaulter_param->is_for_session)))) {
-                                       /* skip */
-                                       debug_error("skip updating victim node");
-                                       continue;
+       for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
+               if (flag_for_taken_index & (i+1)) {
+                       if (command == FOCUS_COMMAND_ACQUIRE && (victim_node->taken_by_id[i].pid != assaulter_param->pid || (victim_node->taken_by_id[i].handle_id != assaulter_param->handle_id && !(victim_node->taken_by_id[i].by_session & assaulter_param->is_for_session)))) {
+                               /* skip */
+                               debug_error("skip updating victim node");
+                               continue;
+                       }
+                       if (!victim_node->reacquisition) {
+                               GList *list = NULL;
+                               focus_node_t *node = NULL;
+                               for (list = g_focus_node_list; list != NULL; list = list->next) {
+                                       node = (focus_node_t *)list->data;
+                                       if (node && (node->taken_by_id[i].pid == victim_node->pid)) {
+                                               UPDATE_FOCUS_TAKEN_INFO(node, taken_pid, taken_hid, taken_by_session);
+                                       } else if (!list->next) {
+                                               UPDATE_FOCUS_TAKEN_INFO(victim_node, 0, 0, false);
+                                       }
                                }
+                       } else {
                                UPDATE_FOCUS_TAKEN_INFO(victim_node, taken_pid, taken_hid, taken_by_session);
                        }
                }
        }
+
        if (ret_handle == victim_node->handle_id) {
                /* return from client is success, ret_handle will be its handle_id */
                victim_node->status = (command == FOCUS_COMMAND_RELEASE) ? (victim_node->status & ~(cb_data.type)) : (victim_node->status | cb_data.type);
@@ -777,6 +788,54 @@ FINISH:
        return ret;
 }
 
+int mm_sound_mgr_focus_set_reacquisition (const _mm_sound_mgr_focus_param_t *param)
+{
+       int ret = MM_ERROR_NONE;
+       GList *list = NULL;
+       focus_node_t *node = NULL;
+       focus_node_t *my_node = NULL;
+
+       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);
+
+       /* Find node to set reacquisition */
+       for (list = g_focus_node_list; list != NULL; list = list->next) {
+               node = (focus_node_t *)list->data;
+               if (node && !node->is_for_watch && (node->pid == param->pid) && (node->handle_id == param->handle_id)) {
+                       node->reacquisition = param->reacquisition;
+                       my_node = node;
+                       break;
+               }
+       }
+
+       /* Append my node's taken info to my victim node */
+       if(!param->reacquisition) {
+               int i;
+               for (list = g_focus_node_list; list != NULL; list = list->next) {
+                       node = (focus_node_t *)list->data;
+                       for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
+                               if (node && (node->taken_by_id[i].pid == param->pid)) {
+                                       if (my_node->taken_by_id[i].pid) {
+                                               UPDATE_FOCUS_TAKEN_INFO(node, my_node->taken_by_id[i].pid, my_node->taken_by_id[i].handle_id, my_node->taken_by_id[i].by_session);
+                                       }
+                               } else if (!list->next) {
+                                       UPDATE_FOCUS_TAKEN_INFO(my_node, 0, 0, false);
+                               }
+                       }
+               }
+       }
+
+       _mm_sound_mgr_focus_list_dump();
+       MMSOUND_LEAVE_CRITICAL_SECTION(&g_focus_node_list_mutex);
+
+       debug_fleave();
+       return ret;
+}
+
 int mm_sound_mgr_focus_request_acquire (const _mm_sound_mgr_focus_param_t *param)
 {
        int ret = MM_ERROR_NONE;
index 4298b04..f3c9aa5 100644 (file)
   "      <arg name='handle_id' type='i' direction='in'/>"
   "      <arg name='is_for_session' type='b' direction='in'/>"
   "    </method>"
+  "    <method name='SetFocusReacquisition'>"
+  "      <arg name='pid' type='i' direction='in'/>"
+  "      <arg name='handle_id' type='i' direction='in'/>"
+  "      <arg name='reacquisition' type='b' direction='in'/>"
+  "    </method>"
   "    <method name='AcquireFocus'>"
   "      <arg name='pid' type='i' direction='in'/>"
   "      <arg name='handle_id' type='i' direction='in'/>"
@@ -105,6 +110,7 @@ struct mm_sound_mgr_focus_dbus_signal{
 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_acquire_focus(GDBusMethodInvocation* invocation);
 static void handle_method_release_focus(GDBusMethodInvocation* invocation);
 static void handle_method_watch_focus(GDBusMethodInvocation* invocation);
@@ -134,6 +140,12 @@ struct mm_sound_mgr_focus_dbus_method methods[METHOD_CALL_MAX] = {
                },
                .handler = handle_method_unregister_focus
        },
+       [METHOD_CALL_SET_FOCUS_REACQUISITION] = {
+               .info = {
+                       .name = "SetFocusReacquisition",
+               },
+               .handler = handle_method_set_focus_reacquisition
+       },
        [METHOD_CALL_ACQUIRE_FOCUS] = {
                .info = {
                        .name = "AcquireFocus",
@@ -365,6 +377,34 @@ send_reply:
        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_acquire_focus(GDBusMethodInvocation* invocation)
 {
        int ret = MM_ERROR_NONE;
index e238cc2..5e1f133 100644 (file)
@@ -99,6 +99,22 @@ int __mm_sound_mgr_focus_ipc_unregister_focus(int pid, int handle_id)
 }
 
 // method -> callback
+int __mm_sound_mgr_focus_ipc_set_focus_reacquisition(int pid, int handle_id, bool reacquisition)
+{
+       _mm_sound_mgr_focus_param_t param;
+       int ret = MM_ERROR_NONE;
+
+       memset(&param, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
+       param.pid = pid;
+       param.handle_id = handle_id;
+       param.reacquisition = reacquisition;
+
+       ret = mm_sound_mgr_focus_set_reacquisition(&param);
+
+       return ret;
+}
+
+// method -> callback
 int __mm_sound_mgr_focus_ipc_acquire_focus(int pid, int handle_id, int focus_type, const char* name )
 {
        _mm_sound_mgr_focus_param_t param;
index e1d5b49..2087734 100644 (file)
@@ -47,6 +47,7 @@ int mm_sound_client_dbus_get_audio_path(mm_sound_device_in *device_in, mm_sound_
 #ifdef USE_FOCUS
 int mm_sound_client_dbus_register_focus(int id, int instance, const char *stream_type, mm_sound_focus_changed_cb callback, bool is_for_session, void* user_data);
 int mm_sound_client_dbus_unregister_focus(int instance, int id, bool is_for_session);
+int mm_sound_client_dbus_set_foucs_reacquisition(int instance, int id, bool reacquisition);
 int mm_sound_client_dbus_acquire_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session);
 int mm_sound_client_dbus_release_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session);
 int mm_sound_client_dbus_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, bool is_for_session, void *user_data);
index 9ceb859..add0e78 100644 (file)
@@ -134,6 +134,7 @@ enum {
         METHOD_CALL_GET_UNIQUE_ID,
         METHOD_CALL_REGISTER_FOCUS,
         METHOD_CALL_UNREGISTER_FOCUS,
+        METHOD_CALL_SET_FOCUS_REACQUISITION,
         METHOD_CALL_ACQUIRE_FOCUS,
         METHOD_CALL_RELEASE_FOCUS,
         METHOD_CALL_WATCH_FOCUS,
index 6a8734e..4b7cc8e 100644 (file)
@@ -1641,7 +1641,9 @@ int mm_sound_client_unregister_focus(int id)
 int mm_sound_client_set_focus_reacquisition(int id, bool reacquisition)
 {
        int ret = MM_ERROR_NONE;
+       int instance;
        int index = -1;
+       bool result;
 
        debug_fenter();
 
@@ -1650,11 +1652,29 @@ int mm_sound_client_set_focus_reacquisition(int id, bool reacquisition)
                debug_error("Could not find index");
                return MM_ERROR_INVALID_ARGUMENT;
        }
+       instance = g_focus_sound_handle[index].focus_tid;
+
+       ret = mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
+       if (ret) {
+               debug_error("[Client] mm_sound_client_is_focus_cb_thread failed");
+               goto cleanup;
+       } else if (!result) {
+               ret = mm_sound_client_dbus_set_foucs_reacquisition(instance, id, reacquisition);
+               if (ret == MM_ERROR_NONE) {
+                       debug_msg("[Client] Success to set focus reacquisition\n");
+               } else {
+                       debug_error("[Client] Error occurred : %d \n",ret);
+                       goto cleanup;
+               }
+       } else {
+               debug_warning("[Client] Inside the focus cb thread, bypassing dbus method call");
+       }
 
        g_focus_sound_handle[index].auto_reacquire = reacquisition;
 
-       debug_fleave();
+cleanup:
 
+       debug_fleave();
        return ret;
 }
 
@@ -1679,7 +1699,6 @@ int mm_sound_client_get_focus_reacquisition(int id, bool *reacquisition)
        *reacquisition = g_focus_sound_handle[index].auto_reacquire;
 
        debug_fleave();
-
        return ret;
 }
 
index 1ea6ecb..06799ac 100644 (file)
@@ -109,6 +109,9 @@ const struct mm_sound_dbus_method_info g_methods[METHOD_CALL_MAX] = {
        [METHOD_CALL_UNREGISTER_FOCUS] = {
                .name = "UnregisterFocus",
        },
+       [METHOD_CALL_SET_FOCUS_REACQUISITION] = {
+               .name = "SetFocusReacquisition",
+       },
        [METHOD_CALL_ACQUIRE_FOCUS] = {
                .name = "AcquireFocus",
        },
@@ -1354,6 +1357,31 @@ int mm_sound_client_dbus_unregister_focus(int instance, int id, bool is_for_sess
        return ret;
 }
 
+int mm_sound_client_dbus_set_foucs_reacquisition(int instance, int id, bool reacquisition)
+{
+       int ret = MM_ERROR_NONE;
+       GVariant* params = NULL, *result = NULL;
+
+       debug_fenter();
+
+       params = g_variant_new("(iib)", instance, id, reacquisition);
+       if (params) {
+               if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_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);
+
+       debug_fleave();
+       return ret;
+}
+
 int mm_sound_client_dbus_acquire_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session)
 {
        int ret = MM_ERROR_NONE;
index 9fbe3b0..75a4b69 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-sound
 Summary:    MMSound Package contains client lib and sound_server binary
-Version:    0.9.273
+Version:    0.9.274
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0