return ret;
}
-static int _mm_sound_mgr_focus_do_watch_callback(focus_type_e focus_type, focus_command_e command, focus_node_t *my_node, const _mm_sound_mgr_focus_param_t *param)
+static bool _check_session_node_exist(int pid)
+{
+ 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->pid != pid)
+ continue;
+ if (node->is_for_monitor)
+ continue;
+ if (node->is_for_session)
+ return true;
+ }
+
+ debug_msg("session node for pid[%d] does not exist", pid);
+
+ return false;
+}
+
+static void _invoke_watch_callback(focus_node_t *node, focus_node_t *my_node, focus_type_e focus_type, focus_command_e command, const _mm_sound_mgr_focus_param_t *param)
{
+ int ret = -1;
+ int pret = 0;
+ struct pollfd pfd;
char *filename = NULL;
char *filename2 = NULL;
struct timeval time;
int endtime = 0;
int fd_FOCUS_R = -1;
int fd_FOCUS = -1;
- int ret = -1;
- struct pollfd pfd;
- int pret = 0;
+ focus_cb_data cb_data;
+
+ if (!node || !my_node) {
+ debug_error("[CB] invalid argument, node[%p], my_node[%p]\n", node, my_node);
+ return;
+ }
+
+ memset(&cb_data, 0, sizeof(focus_cb_data));
+ cb_data.pid = node->pid;
+ cb_data.handle = node->handle_id;
+ cb_data.type = focus_type & node->status;
+ cb_data.state = (command == FOCUS_COMMAND_ACQUIRE) ? !FOCUS_STATUS_DEACTIVATED : FOCUS_STATUS_DEACTIVATED;
+ MMSOUND_STRNCPY(cb_data.stream_type, my_node->stream_type, MAX_STREAM_TYPE_LEN);
+ MMSOUND_STRNCPY(cb_data.ext_info, param->ext_info, MM_SOUND_NAME_NUM);
+
+ /* Set start time */
+ gettimeofday(&time, NULL);
+ starttime = time.tv_sec * 1000000 + time.tv_usec;
+
+ /**************************************
+ *
+ * Open callback cmd pipe
+ *
+ **************************************/
+ filename = __get_focus_pipe_path(cb_data.pid, cb_data.handle, NULL, true);
+ if (filename == NULL) {
+ debug_error("[CB] failed to get watch pipe");
+ goto RELEASE;
+ }
+ if ((fd_FOCUS = open(filename, O_WRONLY|O_NONBLOCK)) == -1) {
+ char str_error[256];
+ strerror_r(errno, str_error, sizeof(str_error));
+ debug_error("[CB] failed to open watch pipe (%s, err:%s)\n", filename, str_error);
+ goto RELEASE;
+ }
+
+ /******************************************
+ *
+ * Open callback result pipe
+ * before writing callback cmd to pipe
+ *
+ ******************************************/
+ filename2 = __get_focus_pipe_path(cb_data.pid, cb_data.handle, "r", true);
+ if (filename2 == NULL) {
+ debug_error("[RETCB] failed to get watch return pipe");
+ goto RELEASE;
+ }
+ if ((fd_FOCUS_R= open(filename2, O_RDONLY|O_NONBLOCK)) == -1) {
+ char str_error[256];
+ strerror_r(errno, str_error, sizeof(str_error));
+ debug_error("[RETCB] failed to open watch return pipe (%s, err:%s)\n", filename2, str_error);
+ goto RELEASE;
+ }
+
+ /*******************************************
+ * Write Callback msg
+ *******************************************/
+ if (write(fd_FOCUS, &cb_data ,sizeof(cb_data)) == -1) {
+ char str_error[256];
+ strerror_r(errno, str_error, sizeof(str_error));
+ debug_error("[CB] failed to write (err:%s)\n", str_error);
+ goto RELEASE;
+ }
+
+ /*********************************************
+ *
+ * Wait callback result msg
+ *
+ ********************************************/
+ pfd.fd = fd_FOCUS_R;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ debug_msg("[RETCB] wait WATCH CALLBACK (client pid=%d, cmd=%d, timeout=%d(ms))\n", cb_data.pid, command, CALLBACK_TIMEOUT);
+ pret = poll(&pfd, 1, CALLBACK_TIMEOUT);
+ if (pret < 0) {
+ debug_error("[RETCB] poll failed (%d)\n", pret);
+ goto RELEASE;
+ }
+ if (pfd.revents & POLLIN) {
+ if (read(fd_FOCUS_R, &ret, sizeof(ret)) == -1) {
+ char str_error[256];
+ strerror_r(errno, str_error, sizeof(str_error));
+ debug_error("[RETCB] failed to read (err:%s)\n", str_error);
+ goto RELEASE;
+ }
+ }
+
+ /* Calculate endtime and display*/
+ gettimeofday(&time, NULL);
+ endtime = time.tv_sec * 1000000 + time.tv_usec;
+ debug_msg("[RETCB] WATCH CALLBACK returned (cbtimelab=%d(ms), client pid=%d, return handle=%d)\n", ((endtime-starttime)/1000), cb_data.pid, ret);
+
+ /**************************************
+ *
+ * Close callback result pipe
+ *
+ **************************************/
+RELEASE:
+ g_free(filename);
+ filename = NULL;
+
+ g_free(filename2);
+ filename2 = NULL;
+
+ if (fd_FOCUS != -1) {
+ close(fd_FOCUS);
+ fd_FOCUS = -1;
+ }
+ if (fd_FOCUS_R != -1) {
+ close(fd_FOCUS_R);
+ fd_FOCUS_R = -1;
+ }
+}
+/* session backward compatibility for monitor handle */
+static int _mm_sound_mgr_focus_do_monitor_callback(focus_type_e focus_type, focus_command_e command, focus_node_t *my_node, const _mm_sound_mgr_focus_param_t *param)
+{
GList *list = NULL;
focus_node_t *node = NULL;
- focus_cb_data cb_data;
debug_fenter();
+ if (!my_node) {
+ debug_error("[CB] my_node is null");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+
for (list = g_focus_node_list; list != NULL; list = list->next) {
- node = (focus_node_t *)list->data;
- if (node == my_node || (node->pid == my_node->pid && node->is_for_session && my_node->is_for_session)) {
- /* skip my own */
- } else {
- if (node->is_for_watch && (node->status & focus_type)) {
- memset(&cb_data, 0, sizeof(focus_cb_data));
- cb_data.pid = node->pid;
- cb_data.handle = node->handle_id;
- cb_data.type = focus_type & node->status;
- cb_data.state = (command == FOCUS_COMMAND_ACQUIRE) ? !FOCUS_STATUS_DEACTIVATED : FOCUS_STATUS_DEACTIVATED;
- MMSOUND_STRNCPY(cb_data.stream_type, my_node->stream_type, MAX_STREAM_TYPE_LEN);
- MMSOUND_STRNCPY(cb_data.ext_info, param->ext_info, MM_SOUND_NAME_NUM);
-
- /* Set start time */
- gettimeofday(&time, NULL);
- starttime = time.tv_sec * 1000000 + time.tv_usec;
-
- /**************************************
- *
- * Open callback cmd pipe
- *
- **************************************/
- filename = __get_focus_pipe_path(cb_data.pid, cb_data.handle, NULL, true);
- if (filename == NULL) {
- debug_error("[CB] failed to get watch pipe");
- goto RELEASE;
- }
- if ((fd_FOCUS = open(filename, O_WRONLY|O_NONBLOCK)) == -1) {
- char str_error[256];
- strerror_r(errno, str_error, sizeof(str_error));
- debug_error("[CB] failed to open watch pipe (%s, err:%s)\n", filename, str_error);
- goto RELEASE;
- }
+ if (!(node = (focus_node_t *)list->data))
+ continue;
+ if (!node->is_for_watch || !node->is_for_monitor || !node->is_for_session)
+ continue;
+ if (node == my_node || (node->pid == my_node->pid && my_node->is_for_session))
+ continue;
+ if (!(node->status & focus_type))
+ continue;
+ /* check if it meets the condition to trigger monitor callback */
+ if (!_check_session_node_exist(node->pid))
+ continue;
- /******************************************
- *
- * Open callback result pipe
- * before writing callback cmd to pipe
- *
- ******************************************/
- filename2 = __get_focus_pipe_path(cb_data.pid, cb_data.handle, "r", true);
- if (filename2 == NULL) {
- debug_error("[RETCB] failed to get watch return pipe");
- goto RELEASE;
- }
- if ((fd_FOCUS_R= open(filename2, O_RDONLY|O_NONBLOCK)) == -1) {
- char str_error[256];
- strerror_r(errno, str_error, sizeof(str_error));
- debug_error("[RETCB] failed to open watch return pipe (%s, err:%s)\n", filename2, str_error);
- goto RELEASE;
- }
+ _invoke_watch_callback(node, my_node, focus_type, command, param);
+ }
- /*******************************************
- * Write Callback msg
- *******************************************/
- if (write(fd_FOCUS, &cb_data ,sizeof(cb_data)) == -1) {
- char str_error[256];
- strerror_r(errno, str_error, sizeof(str_error));
- debug_error("[CB] failed to write (err:%s)\n", str_error);
- goto RELEASE;
- }
+ debug_fleave();
- /*********************************************
- *
- * Wait callback result msg
- *
- ********************************************/
- pfd.fd = fd_FOCUS_R;
- pfd.events = POLLIN;
- pfd.revents = 0;
- debug_msg("[RETCB] wait WATCH CALLBACK (client pid=%d, cmd=%d, timeout=%d(ms))\n", cb_data.pid, command, CALLBACK_TIMEOUT);
- pret = poll(&pfd, 1, CALLBACK_TIMEOUT);
- if (pret < 0) {
- debug_error("[RETCB] poll failed (%d)\n", pret);
- goto RELEASE;
- }
- if (pfd.revents & POLLIN) {
- if (read(fd_FOCUS_R, &ret, sizeof(ret)) == -1) {
- char str_error[256];
- strerror_r(errno, str_error, sizeof(str_error));
- debug_error("[RETCB] failed to read (err:%s)\n", str_error);
- goto RELEASE;
- }
- }
+ return MM_ERROR_NONE;
+}
- /* Calculate endtime and display*/
- gettimeofday(&time, NULL);
- endtime = time.tv_sec * 1000000 + time.tv_usec;
- debug_msg("[RETCB] WATCH CALLBACK returned (cbtimelab=%d(ms), client pid=%d, return handle=%d)\n", ((endtime-starttime)/1000), cb_data.pid, ret);
+static int _mm_sound_mgr_focus_do_watch_callback(focus_type_e focus_type, focus_command_e command, focus_node_t *my_node, const _mm_sound_mgr_focus_param_t *param)
+{
+ GList *list = NULL;
+ focus_node_t *node = NULL;
- /**************************************
- *
- * Close callback result pipe
- *
- **************************************/
-RELEASE:
- g_free(filename);
- filename = NULL;
+ debug_fenter();
- g_free(filename2);
- filename2 = NULL;
+ if (!my_node) {
+ debug_error("[CB] my_node is null");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
- if (fd_FOCUS != -1) {
- close(fd_FOCUS);
- fd_FOCUS = -1;
- }
- if (fd_FOCUS_R != -1) {
- close(fd_FOCUS_R);
- fd_FOCUS_R = -1;
- }
+ for (list = g_focus_node_list; list != NULL; list = list->next) {
+ if (!(node = (focus_node_t *)list->data))
+ continue;
+ if (node == my_node || (node->pid == my_node->pid && node->is_for_session && my_node->is_for_session))
+ continue;
+ if (!node->is_for_watch || !(node->status & focus_type))
+ continue;
+ if (node->is_for_monitor)
+ continue;
- continue;
- }
- }
+ _invoke_watch_callback(node, my_node, focus_type, command, param);
}
+
debug_fleave();
+
return MM_ERROR_NONE;
}
if (strncmp(assaulter_stream_type, victim_node->stream_type, MAX_STREAM_TYPE_LEN))
_mm_sound_mgr_focus_do_watch_callback((focus_type_e)assaulter_param->request_type, command, victim_node, assaulter_param);
+ _mm_sound_mgr_focus_do_monitor_callback((focus_type_e)assaulter_param->request_type, command, victim_node, assaulter_param);
RELEASE:
g_free(filename);
for (list = g_focus_node_list; list != NULL; list = list->next) {
if ((node = (focus_node_t *)list->data) && !node->is_for_watch) {
debug_msg("*** pid[%5d]/handle_id[%2d]/[%14s]:priority[%2d],status[%s],taken_by[P(%5d/%2d/%2d)C(%5d/%2d/%2d)],session[%d],option[0x%x/0x%x],ext_info[%s/%s]\n",
- node->pid, node->handle_id, node->stream_type, node->priority, focus_status_str[node->status],
- node->taken_by_id[0].pid, node->taken_by_id[0].handle_id, node->taken_by_id[0].by_session, node->taken_by_id[1].pid,
- node->taken_by_id[1].handle_id, node->taken_by_id[1].by_session, node->is_for_session, node->option[0], node->option[1], node->ext_info[0], node->ext_info[1]);
+ node->pid, node->handle_id, node->stream_type, node->priority, focus_status_str[node->status],
+ node->taken_by_id[0].pid, node->taken_by_id[0].handle_id, node->taken_by_id[0].by_session, node->taken_by_id[1].pid,
+ node->taken_by_id[1].handle_id, node->taken_by_id[1].by_session, node->is_for_session, node->option[0], node->option[1], node->ext_info[0], node->ext_info[1]);
}
}
debug_msg("================================================ focus node list : end =====================================================\n");
debug_msg("============================================= focus watch node list : start =================================================\n");
for (list = g_focus_node_list; list != NULL; list = list->next) {
if ((node = (focus_node_t *)list->data) && node->is_for_watch)
- debug_msg("*** pid[%5d]/handle_id[%d]/watch on focus status[%s]/for_session[%d]\n", node->pid, node->handle_id, focus_status_str[node->status], node->is_for_session);
+ debug_msg("*** pid[%5d]/handle_id[%d]/watch on focus status[%s]/for_session[%d]/for_monitor[%d]\n",
+ node->pid, node->handle_id, focus_status_str[node->status], node->is_for_session, node->is_for_monitor);
}
debug_msg("============================================= focus watch node list : end ===================================================\n");
my_node->status &= ~(new_param->request_type);
_mm_sound_mgr_focus_do_watch_callback((focus_type_e)new_param->request_type, FOCUS_COMMAND_RELEASE, my_node, new_param);
}
+ _mm_sound_mgr_focus_do_monitor_callback((focus_type_e)new_param->request_type, FOCUS_COMMAND_RELEASE, my_node, new_param);
}
g_free(new_param);
}
/* do watch callback due to the status of mine */
if (need_to_trigger_watch_cb)
_mm_sound_mgr_focus_do_watch_callback((focus_type_e)param->request_type, FOCUS_COMMAND_ACQUIRE, my_node, param);
+ _mm_sound_mgr_focus_do_monitor_callback((focus_type_e)param->request_type, FOCUS_COMMAND_ACQUIRE, my_node, param);
/* update taken information */
for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
if (param->request_type & (i+1)) {
/* do watch callback due to the status of mine */
if (need_to_trigger_watch_cb)
_mm_sound_mgr_focus_do_watch_callback((focus_type_e)param->request_type, FOCUS_COMMAND_RELEASE, my_node, param);
+ _mm_sound_mgr_focus_do_monitor_callback((focus_type_e)param->request_type, FOCUS_COMMAND_RELEASE, my_node, param);
_mm_sound_mgr_focus_list_dump();
_mm_sound_mgr_focus_watch_list_dump ();
/* fill up information to the node */
_mm_sound_mgr_focus_fill_info_from_msg(node, param);
node->is_for_watch = true;
+ node->is_for_monitor = param->is_for_monitor;
node->status = param->request_type;
g_focus_node_list = g_list_append(g_focus_node_list, node);
while (list) {
if (!(node = (focus_node_t *)list->data))
continue;
- if (node->pid == param->pid) {
- debug_log("found pid node");
- if (node->is_for_watch) {
- debug_log("clearing watch cb of pid(%d) handle(%d)", node->pid, node->handle_id);
- __clear_focus_pipe(node);
- g_focus_node_list = g_list_remove(g_focus_node_list, node);
- list = g_focus_node_list;
- g_free(node);
- } else if (node->status == FOCUS_STATUS_DEACTIVATED) {
- debug_log("clearing deactivated focus node of pid(%d) hande(%d)", node->pid, node->handle_id);
- my_node = node;
- /* update info of nodes that are lost their focus by the process exited */
- for (list_s = g_focus_node_list; list_s != NULL; list_s = list_s->next) {
- if (!(node = (focus_node_t *)list_s->data))
- continue;
- for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
- if (node->taken_by_id[i].pid == param->pid) {
- if (my_node->taken_by_id[i].pid) {
- UPDATE_FOCUS_TAKEN_INFO(by_id, 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 {
- UPDATE_FOCUS_TAKEN_INFO(by_id, node, 0, 0, false);
- }
+ if (node->pid != param->pid) {
+ list = list->next;
+ debug_log("node not found, next list = %p",list);
+ continue;
+ }
+ if (node->is_for_watch) {
+ debug_log("clearing watch cb of pid(%d) handle(%d)", node->pid, node->handle_id);
+ __clear_focus_pipe(node);
+ g_focus_node_list = g_list_remove(g_focus_node_list, node);
+ list = g_focus_node_list;
+ g_free(node);
+ continue;
+ }
+ if (node->status == FOCUS_STATUS_DEACTIVATED) {
+ debug_log("clearing deactivated focus node of pid(%d) hande(%d)", node->pid, node->handle_id);
+ my_node = node;
+ /* update info of nodes that are lost their focus by the process exited */
+ for (list_s = g_focus_node_list; list_s != NULL; list_s = list_s->next) {
+ if (!(node = (focus_node_t *)list_s->data))
+ continue;
+ for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
+ if (node->taken_by_id[i].pid == param->pid) {
+ if (my_node->taken_by_id[i].pid) {
+ UPDATE_FOCUS_TAKEN_INFO(by_id, 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 {
+ UPDATE_FOCUS_TAKEN_INFO(by_id, node, 0, 0, false);
}
}
}
- __clear_focus_pipe(my_node);
- g_focus_node_list = g_list_remove(g_focus_node_list, my_node);
- list = g_focus_node_list;
- g_free(my_node);
- } else { /* node that acquired focus */
- bool need_to_trigger_watch_cb = true;
- _mm_sound_mgr_focus_param_t param_s;
- debug_log("clearing activated focus node of pid(%d) handle(%d)", node->pid, node->handle_id);
-
- my_node = node;
- memset(¶m_s, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
- param_s.pid = my_node->pid;
- param_s.handle_id = my_node->handle_id;
- param_s.request_type = my_node->status;
- for (list_s = g_focus_node_list; list_s != NULL; list_s = list_s->next) {
- if (!(node = (focus_node_t *)list_s->data))
- continue;
- if (my_node->pid == node->pid || node->is_for_watch)
+ }
+ __clear_focus_pipe(my_node);
+ g_focus_node_list = g_list_remove(g_focus_node_list, my_node);
+ list = g_focus_node_list;
+ g_free(my_node);
+ } else { /* node that acquired focus */
+ bool need_to_trigger_watch_cb = true;
+ _mm_sound_mgr_focus_param_t param_s;
+ debug_log("clearing activated focus node of pid(%d) handle(%d)", node->pid, node->handle_id);
+
+ my_node = node;
+ memset(¶m_s, 0x00, sizeof(_mm_sound_mgr_focus_param_t));
+ param_s.pid = my_node->pid;
+ param_s.handle_id = my_node->handle_id;
+ param_s.request_type = my_node->status;
+ for (list_s = g_focus_node_list; list_s != NULL; list_s = list_s->next) {
+ if (!(node = (focus_node_t *)list_s->data))
+ continue;
+ if (my_node->pid == node->pid || node->is_for_watch)
+ continue;
+ for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
+ if (!(my_node->status & (i+1)))
continue;
- for (i = 0; i < NUM_OF_STREAM_IO_TYPE; i++) {
- if (my_node->status & (i+1)) {
- if (node->taken_by_id[i].pid == param_s.pid && node->taken_by_id[i].handle_id == param_s.handle_id) {
- /* do callback for resumption */
- ret = _mm_sound_mgr_focus_do_callback(FOCUS_COMMAND_ACQUIRE, node, ¶m_s, my_node->stream_type);
- if (ret) {
- debug_error("Fail to _focus_do_callback for COMMAND ACQUIRE to node[%x], ret[0x%x]\n", node, ret);
- }
- if (!strncmp(my_node->stream_type, node->stream_type, MAX_STREAM_TYPE_LEN)) {
- need_to_trigger_watch_cb = false;
- }
- }
- }
- }
- }
- if (need_to_trigger_watch_cb) {
- ret = _mm_sound_mgr_focus_do_watch_callback((focus_type_e)param_s.request_type, FOCUS_COMMAND_RELEASE, my_node, ¶m_s);
- if (ret) {
- debug_error("Fail to _focus_do_watch_callback, ret[0x%x]\n", ret);
+ if (node->taken_by_id[i].pid == param_s.pid && node->taken_by_id[i].handle_id == param_s.handle_id) {
+ /* do callback for resumption */
+ if ((ret = _mm_sound_mgr_focus_do_callback(FOCUS_COMMAND_ACQUIRE, node, ¶m_s, my_node->stream_type)))
+ debug_error("Fail to _focus_do_callback for COMMAND ACQUIRE to node[%x], ret[0x%x]\n", node, ret);
+ if (!strncmp(my_node->stream_type, node->stream_type, MAX_STREAM_TYPE_LEN))
+ need_to_trigger_watch_cb = false;
}
}
- __clear_focus_pipe(my_node);
- g_focus_node_list = g_list_remove(g_focus_node_list, my_node);
- list = g_focus_node_list;
}
- } else {
- list = list->next;
- debug_log("node not found, next list = %p",list);
+ if (need_to_trigger_watch_cb) {
+ if ((ret = _mm_sound_mgr_focus_do_watch_callback((focus_type_e)param_s.request_type, FOCUS_COMMAND_RELEASE, my_node, ¶m_s)))
+ debug_error("Fail to _focus_do_watch_callback, ret[0x%x]\n", ret);
+ }
+ if ((ret = _mm_sound_mgr_focus_do_monitor_callback((focus_type_e)param_s.request_type, FOCUS_COMMAND_RELEASE, my_node, ¶m_s)))
+ debug_error("Fail to _focus_do_monitor_callback, ret[0x%x]\n", ret);
+
+ __clear_focus_pipe(my_node);
+ g_focus_node_list = g_list_remove(g_focus_node_list, my_node);
+ list = g_focus_node_list;
}
}
void* user_data;
bool unset_watch_callback_requested;
- bool is_for_session; /* will be removed when the session concept is completely left out*/
+ /* will be removed when the session concept is completely left out*/
+ bool is_for_session;
+ bool is_for_monitor;
} focus_sound_info_t;
typedef struct {
} focus_cb_data_lib;
typedef struct {
+ int watch_cb_id;
mm_sound_focus_session_interrupt_cb user_cb;
void* user_data;
} focus_session_interrupt_info_t;
typedef gboolean (*focus_callback_handler_t)(gpointer user_data);
focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
-focus_session_interrupt_info_t g_focus_session_interrupt_info = {NULL, NULL};
+focus_session_interrupt_info_t g_focus_session_interrupt_info = {-1, NULL, NULL};
static pthread_mutex_t g_index_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_event_mutex = PTHREAD_MUTEX_INITIALIZER;
guint g_focus_signal_handle;
}
#ifdef USE_FOCUS
+static gboolean _interrupted_completed(gpointer *data)
+{
+ if (!data) {
+ debug_error("data is null");
+ return false;
+ }
+ if (!g_focus_session_interrupt_info.user_cb) {
+ debug_error("user_cb is null");
+ free(data);
+ return false;
+ }
+
+ debug_msg("invoke user_cb(%p)", g_focus_session_interrupt_info.user_cb);
+ (g_focus_session_interrupt_info.user_cb)(FOCUS_IS_RELEASED, (const char *)data, g_focus_session_interrupt_info.user_data);
+ debug_msg("invoked");
+
+ free(data);
+ return false;
+}
+
+static void _session_interrupted_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)
+{
+ debug_msg("SESSION INTERRUPTED CB is called : id(%d), focus_type(%d), state(%d), reason(%s)", id, focus_type, state, reason_for_change);
+
+ if (id != g_focus_session_interrupt_info.watch_cb_id) {
+ debug_error("id is not valid(param id:%d, g_focus_session_interrupt_watch_cb_id:%d)",
+ id, g_focus_session_interrupt_info.watch_cb_id);
+ return;
+ }
+ if (!g_focus_session_interrupt_info.user_cb) {
+ debug_error("user callback is null");
+ return;
+ }
+
+ debug_msg(" >>> invoking session interrupt callback(%p)", g_focus_session_interrupt_info.user_cb);
+ if (state == FOCUS_IS_ACQUIRED)
+ (g_focus_session_interrupt_info.user_cb)(state, reason_for_change, g_focus_session_interrupt_info.user_data);
+ else {
+ debug_msg("INTERRUPTED COMPLETED case, append it to idle");
+ g_idle_add((GSourceFunc)_interrupted_completed, strdup(reason_for_change));
+ }
+ debug_msg(" <<< session interrupt callback finished");
+}
+
int mm_sound_client_set_session_interrupt_callback(mm_sound_focus_session_interrupt_cb callback, void* user_data)
{
int ret = MM_ERROR_NONE;
if (!callback)
return MM_ERROR_INVALID_ARGUMENT;
+ /* add internal focus watch callback */
+ if (g_focus_session_interrupt_info.watch_cb_id == -1) {
+ if ((ret = mm_sound_client_set_focus_watch_callback(getpid(), FOCUS_FOR_BOTH, true, true, _session_interrupted_cb, NULL,
+ &g_focus_session_interrupt_info.watch_cb_id))) {
+ debug_error("failed to mm_sound_client_set_focus_watch_callback(), ret(0x%x)", ret);
+ return ret;
+ }
+ }
g_focus_session_interrupt_info.user_cb = callback;
g_focus_session_interrupt_info.user_data = user_data;
debug_fenter();
- if (!g_focus_session_interrupt_info.user_cb) {
+ if (!g_focus_session_interrupt_info.user_cb || g_focus_session_interrupt_info.watch_cb_id == -1) {
debug_error("no callback to unset");
return MM_ERROR_SOUND_INTERNAL;
}
+ /* remove internal focus watch callback */
+ if ((ret = mm_sound_client_unset_focus_watch_callback(g_focus_session_interrupt_info.watch_cb_id))) {
+ debug_error("failed to mm_sound_client_unset_focus_watch_callback(), id(%d), ret(0x%x)",
+ g_focus_session_interrupt_info.watch_cb_id, ret);
+ return ret;
+ }
+ g_focus_session_interrupt_info.watch_cb_id = -1;
g_focus_session_interrupt_info.user_cb = NULL;
g_focus_session_interrupt_info.user_data = NULL;
(focus_handle->focus_callback)(cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type,
cb_data.option, cb_data.ext_info, focus_handle->user_data);
debug_msg("[CALLBACK END]");
- if (g_focus_session_interrupt_info.user_cb) {
- debug_msg("sending session interrupt callback(%p)", g_focus_session_interrupt_info.user_cb);
- g_focus_session_interrupt_info.user_cb(cb_data.state, cb_data.stream_type, false,
- g_focus_session_interrupt_info.user_data);
- }
}
#ifdef CONFIG_ENABLE_RETCB
{
(focus_handle->watch_callback)(cb_data.handle, cb_data.type, cb_data.state, cb_data.stream_type,
cb_data.ext_info, focus_handle->user_data);
debug_msg("[CALLBACK END]");
- if (g_focus_session_interrupt_info.user_cb) {
- debug_msg("sending session interrupt callback(%p)", g_focus_session_interrupt_info.user_cb);
- (g_focus_session_interrupt_info.user_cb)(cb_data.state, cb_data.stream_type, true,
- g_focus_session_interrupt_info.user_data);
- }
SKIP_CB_AND_RET:
#ifdef CONFIG_ENABLE_RETCB
return ret;
}
-int mm_sound_client_register_focus(int id, int pid, const char *stream_type,
- mm_sound_focus_changed_cb callback,
- bool is_for_session, void* user_data)
+int mm_sound_client_register_focus(int id, int pid, const char *stream_type, bool is_for_session,
+ mm_sound_focus_changed_cb callback, void* user_data)
{
int ret = MM_ERROR_NONE;
int instance;
return ret;
}
-int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e focus_type,
- mm_sound_focus_changed_watch_cb callback,
- bool is_for_session, void* user_data, int *id)
+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)
{
int ret = MM_ERROR_NONE;
int instance;
g_focus_sound_handle[index].watch_callback = callback;
g_focus_sound_handle[index].user_data = user_data;
g_focus_sound_handle[index].is_for_session = is_for_session;
+ g_focus_sound_handle[index].is_for_monitor = is_for_monitor;
g_focus_sound_handle[index].unset_watch_callback_requested = false;
ret = mm_sound_proxy_set_focus_watch_callback(pid, g_focus_sound_handle[index].handle, focus_type,
- callback, is_for_session, user_data);
+ is_for_session, is_for_monitor, callback, user_data);
if (ret == MM_ERROR_NONE) {
debug_msg("[Client] Success to watch focus");
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);
+ g_focus_sound_handle[index].handle,
+ g_focus_sound_handle[index].is_for_session);
if (ret == MM_ERROR_NONE)
debug_msg("[Client] Success to unwatch focus\n");