Add protection code for focus-callback creation
[platform/core/multimedia/libmm-sound.git] / mm_sound_client.c
index fe9cef3..87a6bf8 100644 (file)
@@ -598,7 +598,7 @@ static bool device_is_match_direction(int direction, int mask)
                return true;
        if ((mask & MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG) && (direction & MM_SOUND_DEVICE_IO_DIRECTION_OUT))
                return true;
-       if ((mask & MM_SOUND_DEVICE_IO_DIRECTION_BOTH_FLAG) && (direction & MM_SOUND_DEVICE_IO_DIRECTION_BOTH))
+       if ((mask & MM_SOUND_DEVICE_IO_DIRECTION_BOTH_FLAG) && (direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH))
                return true;
 
        return false;
@@ -1043,9 +1043,12 @@ int mm_sound_client_unset_session_interrupt_callback(void)
 
 static gpointer _focus_thread_func(gpointer data)
 {
-       debug_log(">>> thread func..ID of this thread(%u)\n", (unsigned int)pthread_self());
-       g_main_loop_run(g_focus_loop);
-       debug_log("<<< quit thread func..\n");
+       unsigned int thread_id = (unsigned int)pthread_self();
+       debug_warning(">>> thread func..ID of this thread(%u), mainloop(%p)", thread_id, g_focus_loop);
+       if (g_focus_loop)
+               g_main_loop_run(g_focus_loop);
+
+       debug_warning("<<< quit thread func..(%u), mainloop(%p)", thread_id, g_focus_loop);
        return NULL;
 }
 
@@ -1226,6 +1229,11 @@ static gboolean _focus_watch_callback_handler(gpointer d)
                        return FALSE;
                }
 
+               if (!g_focus_sound_handle[focus_index].is_used) {
+                       debug_warning("unsetting watch calllback has been already requested");
+                       goto SKIP_CB_AND_RET;
+               }
+
                debug_msg("lock focus_lock = %p", &g_focus_sound_handle[focus_index].focus_lock);
                g_mutex_lock(&g_focus_sound_handle[focus_index].focus_lock);
 
@@ -1245,6 +1253,7 @@ static gboolean _focus_watch_callback_handler(gpointer d)
                        }
                }
 
+SKIP_CB_AND_RET:
 #ifdef CONFIG_ENABLE_RETCB
                {
                        int rett = 0;
@@ -1269,12 +1278,13 @@ static gboolean _focus_watch_callback_handler(gpointer d)
 #endif
        }
 
-       debug_msg("unlock focus_lock = %p", &g_focus_sound_handle[focus_index].focus_lock);
-       g_mutex_unlock(&g_focus_sound_handle[focus_index].focus_lock);
+       if (g_focus_sound_handle[focus_index].is_used) {
+               debug_msg("unlock focus_lock = %p", &g_focus_sound_handle[focus_index].focus_lock);
+               g_mutex_unlock(&g_focus_sound_handle[focus_index].focus_lock);
+       }
 
        debug_fleave();
 
-
        return TRUE;
 }
 
@@ -1596,24 +1606,36 @@ int mm_sound_client_register_focus(int id, int pid, const char *stream_type, mm_
                        GMainContext* focus_context = g_main_context_new ();
                        g_focus_loop = g_main_loop_new (focus_context, FALSE);
                        g_main_context_unref(focus_context);
-                       g_focus_thread = g_thread_new("focus-callback-thread", _focus_thread_func, NULL);
+                       if (g_focus_loop == NULL) {
+                               debug_error("could not create mainloop..");
+                               ret = MM_ERROR_SOUND_INTERNAL;
+                               goto cleanup;
+                       }
+
+                       g_focus_thread = g_thread_new("focus-cb-thread", _focus_thread_func, NULL);
                        if (g_focus_thread == NULL) {
-                               debug_error ("could not create thread..");
+                               debug_error("could not create thread..");
                                g_main_loop_unref(g_focus_loop);
-                               g_focus_sound_handle[index].is_used = false;
                                ret = MM_ERROR_SOUND_INTERNAL;
                                goto cleanup;
                        }
+               } else {
+                       debug_warning("focus thread(%p) with mainloop(%p) exists, skip thread creation",
+                                               g_focus_thread, g_focus_loop);
                }
        } else {
                debug_error("[Client] Error occurred : 0x%x \n",ret);
-               g_focus_sound_handle[index].is_used = false;
                goto cleanup;
        }
 
        _focus_init_callback(index, false);
 
 cleanup:
+
+       if (ret) {
+               g_focus_sound_handle[index].is_used = false;
+       }
+
        MMSOUND_LEAVE_CRITICAL_SECTION(&g_index_mutex);
        debug_fleave();
 
@@ -1690,13 +1712,13 @@ int mm_sound_client_set_focus_reacquisition(int id, bool reacquisition)
        } else if (!result) {
                ret = mm_sound_proxy_set_foucs_reacquisition(instance, id, reacquisition);
                if (ret == MM_ERROR_NONE) {
-                       debug_msg("[Client] Success to set focus reacquisition\n");
+                       debug_msg("[Client] Success to set focus reacquisition to [%d]\n", reacquisition);
                } else {
                        debug_error("[Client] Error occurred : 0x%x \n",ret);
                        goto cleanup;
                }
        } else {
-               debug_warning("[Client] Inside the focus cb thread, bypassing dbus method call");
+               debug_warning("[Client] Inside the focus cb thread, set focus reacquisition to [%d]\n", reacquisition);
        }
 
        g_focus_sound_handle[index].auto_reacquire = reacquisition;
@@ -1857,13 +1879,22 @@ int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e focu
                        GMainContext* focus_context = g_main_context_new ();
                        g_focus_loop = g_main_loop_new (focus_context, FALSE);
                        g_main_context_unref(focus_context);
-                       g_focus_thread = g_thread_new("focus-callback-thread", _focus_thread_func, NULL);
+                       if (g_focus_loop == NULL) {
+                               debug_error("could not create mainloop..");
+                               ret = MM_ERROR_SOUND_INTERNAL;
+                               goto cleanup;
+                       }
+
+                       g_focus_thread = g_thread_new("focus-cb-thread", _focus_thread_func, NULL);
                        if (g_focus_thread == NULL) {
                                debug_error ("could not create thread..");
                                g_main_loop_unref(g_focus_loop);
                                ret = MM_ERROR_SOUND_INTERNAL;
                                goto cleanup;
                        }
+               } else {
+                       debug_warning("focus thread(%p) with mainloop(%p) exists, skip thread creation",
+                                               g_focus_thread, g_focus_loop);
                }
        } else {
                debug_error("[Client] Error occurred : 0x%x",ret);
@@ -1899,6 +1930,8 @@ int mm_sound_client_unset_focus_watch_callback(int id)
 
        g_mutex_lock(&g_focus_sound_handle[index].focus_lock);
 
+       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, g_focus_sound_handle[index].is_for_session);
 
        if (ret == MM_ERROR_NONE)
@@ -1913,7 +1946,6 @@ int mm_sound_client_unset_focus_watch_callback(int id)
        g_focus_sound_handle[index].focus_fd = 0;
        g_focus_sound_handle[index].focus_tid = 0;
        g_focus_sound_handle[index].handle = 0;
-       g_focus_sound_handle[index].is_used = false;
 cleanup:
        MMSOUND_LEAVE_CRITICAL_SECTION(&g_index_mutex);
        debug_fleave();