Fix improper errno handling
[platform/core/multimedia/libmm-sound.git] / mm_sound_focus.c
index d24bff3..21e8a82 100644 (file)
 
 #include <stdlib.h>
 #include <unistd.h>
-#include <stdio.h>
-#include <vconf.h>
-
 #include <mm_debug.h>
 
 #include "include/mm_sound.h"
 #include "include/mm_sound_client.h"
-#include "include/mm_sound_focus.h"
-#include "focus_server/include/mm_sound_mgr_focus.h"
 
 #define RETURN_ERROR_IF_FOCUS_CB_THREAD(x_thread) \
 { \
        ret = mm_sound_client_is_focus_cb_thread(x_thread, &result); \
        if (ret) \
                return ret; \
-       else if (result) { \
-               debug_error("it might be called in the thread of focus callback, it is not allowed\n"); \
+       if (result) { \
+               debug_error("it might be called in the thread of focus callback, it is not allowed"); \
                return MM_ERROR_SOUND_INVALID_OPERATION; \
        } \
 } \
 
 EXPORT_API
-int mm_sound_focus_set_session_interrupt_callback(mm_sound_focus_session_interrupt_cb callback, void *user_data)
+int mm_sound_focus_is_cb_thread(bool *result)
 {
        int ret = MM_ERROR_NONE;
-       debug_fenter();
-
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
 
-       if (!callback)
-               return MM_ERROR_INVALID_ARGUMENT;
+       debug_fenter();
 
-       ret = mm_sound_client_set_session_interrupt_callback (callback, user_data);
+       ret = mm_sound_client_is_focus_cb_thread(g_thread_self(), result);
+       if (!ret) {
+               if (*result)
+                       debug_msg("it might be called in the thread of focus callback");
+       }
 
        debug_fleave();
 
@@ -63,35 +58,47 @@ int mm_sound_focus_set_session_interrupt_callback(mm_sound_focus_session_interru
 }
 
 EXPORT_API
-int mm_sound_focus_unset_session_interrupt_callback(void)
+int mm_sound_register_focus(const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data, int *id)
 {
        int ret = MM_ERROR_NONE;
+
        debug_fenter();
 
        RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
 
-       ret = mm_sound_client_unset_session_interrupt_callback ();
-       if (ret) {
-               debug_error("Failed to mm_sound_client_unset_session_interrupt_callback(), ret[0x%x]\n", ret);
+       if (id == NULL || callback == NULL) {
+               debug_error("argument is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
+       ret = mm_sound_client_register_focus(getpid(), stream_type, callback, user_data, id);
+       if (ret)
+               debug_error("Could not register focus, ret[0x%x]", ret);
+
        debug_fleave();
 
        return ret;
 }
 
 EXPORT_API
-int mm_sound_focus_get_id(int *id)
+int mm_sound_unregister_focus(int id)
 {
        int ret = MM_ERROR_NONE;
+       bool result = false;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
+       if (id <= 0) {
+               debug_error("argument is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
-       ret = mm_sound_client_get_unique_id(id);
-       if (ret) {
-               debug_error("Failed to mm_sound_client_get_unique_id(), ret[0x%x]\n", ret);
+       mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
+       if (!result) {
+               if ((ret = mm_sound_client_unregister_focus(id)))
+                       debug_error("Could not unregister focus, ret = %x", ret);
+       } else {
+               ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNREGISTER_FOCUS, id);
        }
 
        debug_fleave();
@@ -100,41 +107,40 @@ int mm_sound_focus_get_id(int *id)
 }
 
 EXPORT_API
-int mm_sound_focus_is_cb_thread(bool *result)
+int mm_sound_set_focus_reacquisition(int id, bool reacquisition)
 {
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       ret = mm_sound_client_is_focus_cb_thread(g_thread_self(), result);
-       if (!ret) {
-               if (*result)
-                       debug_error("it might be called in the thread of focus callback, it is not allowed\n");
+       if (id < 0) {
+               debug_error("argument is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
+       if ((ret = mm_sound_client_set_focus_reacquisition(id, reacquisition)))
+               debug_error("Could not set focus reacquisition, ret[0x%x]", ret);
+
        debug_fleave();
 
        return ret;
 }
 
 EXPORT_API
-int mm_sound_register_focus(int id, const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data)
+int mm_sound_get_focus_reacquisition(int id, bool *reacquisition)
 {
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
-
-       if (id < 0 || callback == NULL) {
-               debug_error("argument is not valid\n");
+       if (id < 0 || !reacquisition) {
+               debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_register_focus(id, getpid(), stream_type, callback, false, user_data);
-       if (ret) {
-               debug_error("Could not register focus, ret[0x%x]\n", ret);
-       }
+       ret = mm_sound_client_get_focus_reacquisition(id, reacquisition);
+       if (ret)
+               debug_error("Could not get focus reacquisition, ret[0x%x]", ret);
 
        debug_fleave();
 
@@ -142,23 +148,20 @@ int mm_sound_register_focus(int id, const char *stream_type, mm_sound_focus_chan
 }
 
 EXPORT_API
-int mm_sound_register_focus_for_session(int id, int pid, const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data)
+int mm_sound_get_stream_type_of_acquired_focus(int focus_type, char **stream_type, int *option, char **ext_info)
 {
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
-
-       if (id < 0 || callback == NULL) {
-               debug_error("argument is not valid\n");
+       if (stream_type == NULL) {
+               debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_register_focus(id, pid, stream_type, callback, true, user_data);
-       if (ret) {
-               debug_error("Could not register focus for session, ret[0x%x]\n", ret);
-       }
+       ret = mm_sound_client_get_acquired_focus_stream_type(focus_type, stream_type, option, ext_info);
+       if (ret)
+               debug_error("Could not get acquired focus stream type, ret[0x%x]", ret);
 
        debug_fleave();
 
@@ -166,7 +169,7 @@ int mm_sound_register_focus_for_session(int id, int pid, const char *stream_type
 }
 
 EXPORT_API
-int mm_sound_unregister_focus(int id)
+int mm_sound_acquire_focus(int id, mm_sound_focus_type_e focus_type, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
 
@@ -175,22 +178,25 @@ int mm_sound_unregister_focus(int id)
        RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
 
        if (id < 0) {
-               debug_error("argument is not valid\n");
+               debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
-
-       ret = mm_sound_client_unregister_focus(id);
-       if (ret) {
-               debug_error("Could not unregister focus, ret = %x\n", ret);
+       if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
+               debug_error("argument is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
+       ret = mm_sound_client_acquire_focus(id, focus_type, 0, ext_info);
+       if (ret)
+               debug_error("Could not acquire focus, ret[0x%x]", ret);
+
        debug_fleave();
 
        return ret;
 }
 
 EXPORT_API
-int mm_sound_acquire_focus(int id, mm_sound_focus_type_e focus_type, const char *additional_info)
+int mm_sound_release_focus(int id, mm_sound_focus_type_e focus_type, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
 
@@ -199,18 +205,17 @@ int mm_sound_acquire_focus(int id, mm_sound_focus_type_e focus_type, const char
        RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
 
        if (id < 0) {
-               debug_error("argument is not valid\n");
+               debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
        if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
-               debug_error("argument is not valid\n");
+               debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_acquire_focus(id, focus_type, additional_info);
-       if (ret) {
-               debug_error("Could not acquire focus, ret[0x%x]\n", ret);
-       }
+       ret = mm_sound_client_release_focus(id, focus_type, 0, ext_info);
+       if (ret)
+               debug_error("Could not release focus, ret[0x%x]", ret);
 
        debug_fleave();
 
@@ -218,58 +223,92 @@ int mm_sound_acquire_focus(int id, mm_sound_focus_type_e focus_type, const char
 }
 
 EXPORT_API
-int mm_sound_release_focus(int id, mm_sound_focus_type_e focus_type, const char *additional_info)
+int mm_sound_acquire_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
-
        if (id < 0) {
-               debug_error("argument is not valid\n");
+               debug_error("id is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
-       if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
-               debug_error("argument is not valid\n");
+
+       if (option < 0) {
+               debug_error("option is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_release_focus(id, focus_type, additional_info);
-       if (ret) {
-               debug_error("Could not release focus, ret[0x%x]\n", ret);
+       if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
+               debug_error("focus type is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
+       ret = mm_sound_client_acquire_focus(id, focus_type, option, ext_info);
+       if (ret)
+               debug_error("Could not acquire focus, ret[0x%x]", ret);
+
        debug_fleave();
 
        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 mm_sound_release_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info)
 {
        int ret = MM_ERROR_NONE;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
+       if (id < 0) {
+               debug_error("id is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
-       if (callback == NULL || id == NULL) {
-               debug_error("argument is not valid\n");
+       if (option < 0) {
+               debug_error("option is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
-       ret = mm_sound_client_set_focus_watch_callback(getpid(), focus_type, callback, false, user_data, id);
-       if (ret) {
-               debug_error("Could not set focus watch callback, ret[0x%x]\n", ret);
+
+       if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
+               debug_error("focus type is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
        }
 
+       ret = mm_sound_client_release_focus(id, focus_type, option, ext_info);
+       if (ret)
+               debug_error("Could not release focus, ret[0x%x]", ret);
+
        debug_fleave();
 
        return ret;
 }
 
 EXPORT_API
-int mm_sound_set_focus_watch_callback_for_session(int pid, mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id)
+int mm_sound_update_focus_status(int id, unsigned int status)
+{
+       int ret = MM_ERROR_NONE;
+
+       if ((ret = mm_sound_client_update_stream_focus_status(id, status)))
+               debug_error("failed to mm_sound_client_update_stream_focus_status(), id(%d), status(%d, ret[0x%x]",
+                                       id, status, ret);
+
+       return ret;
+}
+
+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(src_id, dst_id, focus_type)))
+               debug_error("failed to mm_sound_client_deliver_focus(), ret[0x%x]", 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;
 
@@ -278,13 +317,12 @@ int mm_sound_set_focus_watch_callback_for_session(int pid, mm_sound_focus_type_e
        RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
 
        if (callback == NULL || id == NULL) {
-               debug_error("argument is not valid\n");
+               debug_error("argument is not valid");
                return MM_ERROR_INVALID_ARGUMENT;
        }
-       ret = mm_sound_client_set_focus_watch_callback(pid, focus_type, callback, true, user_data, id);
-       if (ret) {
-               debug_error("Could not set focus watch callback, ret[0x%x]\n", ret);
-       }
+       ret = mm_sound_client_set_focus_watch_callback(getpid(), focus_type, callback, user_data, id);
+       if (ret)
+               debug_error("Could not set focus watch callback, ret[0x%x]", ret);
 
        debug_fleave();
 
@@ -295,14 +333,27 @@ EXPORT_API
 int mm_sound_unset_focus_watch_callback(int id)
 {
        int ret = MM_ERROR_NONE;
+       bool result = false;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
+       if (id < 0) {
+               debug_error("argument is not valid");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       if ((ret = mm_sound_client_request_unset_focus_watch_callback(id))) {
+               debug_error("failed to mm_sound_client_request_unset_focus_watch_callback, ret[0x%x]", ret);
+               return ret;
+       }
 
-       ret = mm_sound_client_unset_focus_watch_callback(id);
-       if (ret) {
-               debug_error("Could not unset focus watch callback, id(%d), ret = %x\n", id, ret);
+       mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
+       if (!result) {
+               if ((ret = mm_sound_client_unset_focus_watch_callback(id)))
+                       debug_error("Could not unset focus watch callback, id(%d), ret[0x%x]", id, ret);
+       } else {
+               ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB, id);
+               debug_msg("mm_sound_client_execute_focus_func_in_main_context() is called, id(%d), ret[0x%x]", id, ret);
        }
 
        debug_fleave();