#include "mm_sound_device.h"
#ifdef USE_FOCUS
#include "mm_sound_focus.h"
+typedef enum {
+ IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB,
+ IDLE_EVENT_TYPE_UNREGISTER_FOCUS,
+ IDLE_EVENT_TYPE_MAX
+} focus_idle_event_type_e;
#endif
//#define MEMTYPE_TRANS_PER_MAX (1024 * 1024) /* 1MB */
int mm_sound_client_release_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info);
int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, bool is_for_session, void* user_data, int *id);
int mm_sound_client_unset_focus_watch_callback(int id);
+int mm_sound_client_execute_focus_func_in_main_context(focus_idle_event_type_e type, int data);
#endif
int mm_sound_client_add_test_callback(mm_sound_test_cb func, void* user_data, unsigned int *subs_id);
focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
focus_session_interrupt_info_t g_focus_session_interrupt_info = {NULL, NULL};
static pthread_mutex_t g_index_mutex = PTHREAD_MUTEX_INITIALIZER;
-guint g_focus_signal_handle = 0;
+static pthread_mutex_t g_event_mutex = PTHREAD_MUTEX_INITIALIZER;
+guint g_focus_signal_handle;
+guint g_idle_event_src;
#endif
gboolean g_need_emergent_exit = FALSE;
unsigned subs_id;
} play_sound_end_callback_data_t;
+typedef struct _focus_idle_event {
+ focus_idle_event_type_e type;
+ int data;
+} focus_idle_event_t;
+
void _system_signal_handler(int signo)
{
int ret = MM_ERROR_NONE;
debug_fenter();
mm_sound_proxy_initialize();
+ g_idle_event_src = 0;
struct sigaction system_action;
g_focus_thread = NULL;
}
+ if (g_idle_event_src > 0) {
+ MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_event_mutex, MM_ERROR_SOUND_INTERNAL);
+ g_source_remove(g_idle_event_src);
+ MMSOUND_LEAVE_CRITICAL_SECTION(&g_event_mutex);
+ }
+
#endif
debug_fleave();
debug_fleave();
return ret;
}
+
+static gboolean _idle_event_callback(void *data)
+{
+ focus_idle_event_t *idle_event_data = (focus_idle_event_t*)data;
+ int ret = MM_ERROR_NONE;
+
+ if (data == NULL) {
+ debug_error("data is null");
+ return FALSE;
+ }
+
+ debug_msg("idle_event_data(%p): type(%d), data(%d)",
+ idle_event_data, idle_event_data->type, idle_event_data->data);
+
+ switch (idle_event_data->type) {
+ case IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB:
+ if ((ret = mm_sound_client_unset_focus_watch_callback(idle_event_data->data)))
+ debug_error("Could not unset focus watch callback, id(%d), ret = %x\n", idle_event_data->data, ret);
+ break;
+ case IDLE_EVENT_TYPE_UNREGISTER_FOCUS:
+ if ((ret = mm_sound_client_unregister_focus(idle_event_data->data)))
+ debug_error("Could not unregister focus, id(%d), ret = %x\n", idle_event_data->data, ret);
+ break;
+ default:
+ debug_warning("invalid type(%d)", idle_event_data->type);
+ break;
+ }
+
+ g_free(idle_event_data);
+
+ g_idle_event_src = 0;
+
+ MMSOUND_LEAVE_CRITICAL_SECTION(&g_event_mutex);
+
+ return FALSE;
+}
+
+int mm_sound_client_execute_focus_func_in_main_context(focus_idle_event_type_e type, int data)
+{
+ focus_idle_event_t *idle_event_data = NULL;
+
+ if (IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB > type || IDLE_EVENT_TYPE_MAX < type)
+ return MM_ERROR_INVALID_ARGUMENT;
+
+ MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_event_mutex, MM_ERROR_SOUND_INTERNAL);
+
+ idle_event_data = g_new0(focus_idle_event_t, 1);
+ idle_event_data->type = type;
+ idle_event_data->data = data;
+
+ g_idle_event_src = g_idle_add_full(G_PRIORITY_HIGH,
+ (GSourceFunc)_idle_event_callback,
+ (gpointer)idle_event_data,
+ NULL);
+
+ return MM_ERROR_NONE;
+}
#endif
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\n");
return MM_ERROR_INVALID_ARGUMENT;
}
- ret = mm_sound_client_unregister_focus(id);
- if (ret) {
- debug_error("Could not unregister focus, ret = %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\n", ret);
+ } else {
+ ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNREGISTER_FOCUS, id);
}
debug_fleave();
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\n");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
- 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 = %x\n", id, ret);
+ } else {
+ ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB, id);
}
debug_fleave();