Simulate monitor handle of audio session manager 74/124974/2
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 12 Apr 2017 00:19:41 +0000 (09:19 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Tue, 2 May 2017 05:59:36 +0000 (14:59 +0900)
This patch simulates asm monitor handle that is used by sound-manager session interrupted callback.

[Version] 0.10.112
[Profile] Common
[Issue Type] Backward compatibility

Change-Id: Icffabc332f2e2bee3d48a610b1369fb584832868
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
12 files changed:
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.h
include/mm_sound_focus.h
include/mm_sound_proxy.h
mm_sound_client.c
mm_sound_focus.c
mm_sound_proxy.c
packaging/libmm-sound.spec

index 9cba9d7..1572103 100644 (file)
@@ -61,6 +61,7 @@ typedef struct {
 
        /* It will be removed when the session concept is completely left out*/
        bool is_for_session;
+       bool is_for_monitor;
 } _mm_sound_mgr_focus_param_t;
 
 typedef struct _taken_by_id
@@ -87,6 +88,7 @@ typedef struct {
 
        /* These will be removed when the session concept is completely left out*/
        bool is_for_session;
+       bool is_for_monitor;
        bool reacquisition_with_released_state;
 } focus_node_t;
 
index 224ea9c..fc9ef7a 100644 (file)
@@ -29,7 +29,7 @@ int __mm_sound_mgr_focus_ipc_set_focus_reacquisition(int pid, int handle_id, boo
 int __mm_sound_mgr_focus_ipc_get_acquired_focus_stream_type(int focus_type, char **stream_type, int *option, char **ext_info);
 int __mm_sound_mgr_focus_ipc_acquire_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_for_session);
 int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_type, int option, const char *ext_info, bool is_for_session);
-int __mm_sound_mgr_focus_ipc_watch_focus(int pid, int handle_id, int focus_type, bool is_for_session);
+int __mm_sound_mgr_focus_ipc_watch_focus(int pid, int handle_id, int focus_type, bool is_for_session, bool is_for_monitor);
 int __mm_sound_mgr_focus_ipc_unwatch_focus(int pid, int handle_id);
 int __mm_sound_mgr_focus_ipc_unregister_focus(int pid, int handle_id, bool is_for_session);
 int __mm_sound_mgr_focus_ipc_emergent_exit(int pid);
index a5e712e..e8ae800 100644 (file)
@@ -165,8 +165,31 @@ static int _mm_sound_mgr_focus_get_priority_from_stream_type(int *priority, cons
        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;
@@ -174,133 +197,181 @@ static int _mm_sound_mgr_focus_do_watch_callback(focus_type_e focus_type, focus_
        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;
 }
 
@@ -522,6 +593,7 @@ int _mm_sound_mgr_focus_do_callback(focus_command_e command, focus_node_t *victi
 
        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);
@@ -552,9 +624,9 @@ static int _mm_sound_mgr_focus_list_dump ()
        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");
@@ -571,7 +643,8 @@ static int _mm_sound_mgr_focus_watch_list_dump()
        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");
 
@@ -728,6 +801,7 @@ int mm_sound_mgr_focus_destroy_node(const _mm_sound_mgr_focus_param_t *param)
                                                                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);
                                        }
@@ -986,6 +1060,7 @@ int mm_sound_mgr_focus_request_acquire(const _mm_sound_mgr_focus_param_t *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)) {
@@ -1096,6 +1171,7 @@ int mm_sound_mgr_focus_request_release(const _mm_sound_mgr_focus_param_t *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_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 ();
@@ -1134,6 +1210,7 @@ int mm_sound_mgr_focus_set_watch_cb(const _mm_sound_mgr_focus_param_t *param)
        /* 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);
@@ -1212,78 +1289,77 @@ int mm_sound_mgr_focus_emergent_exit(const _mm_sound_mgr_focus_param_t *param)
        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(&param_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(&param_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, &param_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, &param_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, &param_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, &param_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, &param_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;
                }
        }
 
index d14658c..9e5c44d 100644 (file)
@@ -67,6 +67,7 @@ static const gchar introspection_xml[] =
   "      <arg name='handle_id' type='i' direction='in'/>"
   "      <arg name='focus_type' type='i' direction='in'/>"
   "      <arg name='is_for_session' type='b' direction='in'/>"
+  "      <arg name='is_for_monitor' type='b' direction='in'/>"
   "    </method>"
   "    <method name='UnwatchFocus'>"
   "      <arg name='pid' type='i' direction='in'/>"
@@ -442,6 +443,7 @@ static void handle_method_watch_focus(GDBusMethodInvocation* invocation)
        int ret = MM_ERROR_NONE;
        int handle_id = 0, focus_type = 0;
        gboolean is_for_session;
+       gboolean is_for_monitor;
        GVariant *params = NULL;
        int pid = 0;
 
@@ -453,8 +455,8 @@ static void handle_method_watch_focus(GDBusMethodInvocation* invocation)
                goto send_reply;
        }
 
-       g_variant_get(params, "(iiib)", &pid, &handle_id, &focus_type, &is_for_session);
-       ret = __mm_sound_mgr_focus_ipc_watch_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, focus_type, is_for_session);
+       g_variant_get(params, "(iiibb)", &pid, &handle_id, &focus_type, &is_for_session, &is_for_monitor);
+       ret = __mm_sound_mgr_focus_ipc_watch_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, focus_type, is_for_session, is_for_monitor);
 
 send_reply:
        if (ret == MM_ERROR_NONE) {
index 319ad64..443748f 100644 (file)
@@ -136,7 +136,7 @@ int __mm_sound_mgr_focus_ipc_release_focus(int pid, int handle_id, int focus_typ
        return ret;
 }
 
-int __mm_sound_mgr_focus_ipc_watch_focus(int pid, int handle_id, int focus_type, bool is_for_session)
+int __mm_sound_mgr_focus_ipc_watch_focus(int pid, int handle_id, int focus_type, bool is_for_session, bool is_for_monitor)
 {
        _mm_sound_mgr_focus_param_t param;
        int ret = MM_ERROR_NONE;
@@ -146,6 +146,7 @@ int __mm_sound_mgr_focus_ipc_watch_focus(int pid, int handle_id, int focus_type,
        param.handle_id = handle_id;
        param.request_type = focus_type;
        param.is_for_session = is_for_session;
+       param.is_for_monitor = is_for_monitor;
 
        ret = mm_sound_mgr_focus_set_watch_cb(&param);
 
index 4771c66..b14b708 100644 (file)
@@ -61,7 +61,7 @@ int mm_sound_client_set_session_interrupt_callback(mm_sound_focus_session_interr
 int mm_sound_client_unset_session_interrupt_callback(void);
 int mm_sound_client_get_unique_id(int *id);
 int mm_sound_client_is_focus_cb_thread(GThread *mine, bool *result);
-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 mm_sound_client_unregister_focus(int id);
 int mm_sound_client_set_focus_reacquisition(int id, bool reacquisition, bool is_for_session);
 int mm_sound_client_get_focus_reacquisition(int id, bool *reacquisition);
@@ -69,7 +69,7 @@ int mm_sound_client_get_acquired_focus_stream_type(int focus_type, char **stream
 int mm_sound_client_acquire_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info);
 int mm_sound_client_release_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info);
 int mm_sound_client_update_stream_focus_status(int id, unsigned int status);
-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_set_focus_watch_callback(int pid, mm_sound_focus_type_e type, bool is_for_session, bool is_for_monitor, mm_sound_focus_changed_watch_cb callback, void* user_data, int *id);
 int mm_sound_client_unset_focus_watch_callback(int id);
 int mm_sound_client_request_unset_focus_watch_callback(int id);
 int mm_sound_client_execute_focus_func_in_main_context(focus_idle_event_type_e type, int data);
index 4abb34d..2fddb15 100644 (file)
@@ -66,9 +66,10 @@ int mm_sound_update_focus_status(int id, unsigned int status);
 typedef void (*mm_sound_focus_changed_watch_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);
 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_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_set_focus_watch_callback_for_session_monitor(int pid, mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id);
 int mm_sound_unset_focus_watch_callback(int id);
 
-typedef void (*mm_sound_focus_session_interrupt_cb) (mm_sound_focus_state_e state, const char *reason_for_change, bool is_wcb, void *user_data);
+typedef void (*mm_sound_focus_session_interrupt_cb) (mm_sound_focus_state_e state, const char *reason_for_change, void *user_data);
 int mm_sound_focus_set_session_interrupt_callback(mm_sound_focus_session_interrupt_cb callback, void *user_data);
 int mm_sound_focus_unset_session_interrupt_callback(void);
 
index b4a98e3..16b845c 100644 (file)
@@ -77,7 +77,7 @@ int mm_sound_proxy_get_acquired_focus_stream_type(int focus_type, char **stream_
 int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info, bool is_for_session);
 int mm_sound_proxy_release_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info, bool is_for_session);
 int mm_sound_proxy_update_stream_focus_status(int focus_id, unsigned int status);
-int mm_sound_proxy_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);
+int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, bool is_for_session, bool is_for_monitor, mm_sound_focus_changed_watch_cb callback, void *user_data);
 int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle, bool is_for_session);
 #endif
 
index 30a3edd..bceaecf 100644 (file)
@@ -101,7 +101,9 @@ typedef struct {
        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 {
@@ -115,6 +117,7 @@ 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;
@@ -122,7 +125,7 @@ typedef struct {
 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;
@@ -1067,6 +1070,51 @@ int mm_sound_client_control_filter_by_type(const char *stream_type, const char *
 }
 
 #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;
@@ -1076,6 +1124,14 @@ int mm_sound_client_set_session_interrupt_callback(mm_sound_focus_session_interr
        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;
 
@@ -1089,11 +1145,18 @@ int mm_sound_client_unset_session_interrupt_callback(void)
 
        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;
 
@@ -1221,11 +1284,6 @@ static gboolean _focus_callback_handler(gpointer user_data)
                        (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
                {
@@ -1314,11 +1372,6 @@ static gboolean _focus_watch_callback_handler(gpointer user_data)
                (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
@@ -1733,9 +1786,8 @@ int mm_sound_client_is_focus_cb_thread(GThread *mine, bool *result)
        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;
@@ -1997,9 +2049,8 @@ int mm_sound_client_update_stream_focus_status(int id, unsigned int status)
        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;
@@ -2032,10 +2083,11 @@ int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e focu
        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");
@@ -2103,8 +2155,8 @@ int mm_sound_client_unset_focus_watch_callback(int id)
        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");
index 70bac61..1887456 100644 (file)
@@ -51,7 +51,7 @@ int mm_sound_focus_set_session_interrupt_callback(mm_sound_focus_session_interru
        if (!callback)
                return MM_ERROR_INVALID_ARGUMENT;
 
-       ret = mm_sound_client_set_session_interrupt_callback (callback, user_data);
+       ret = mm_sound_client_set_session_interrupt_callback(callback, user_data);
 
        debug_fleave();
 
@@ -66,7 +66,7 @@ int mm_sound_focus_unset_session_interrupt_callback(void)
 
        RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
 
-       ret = mm_sound_client_unset_session_interrupt_callback ();
+       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);
        }
@@ -127,7 +127,7 @@ int mm_sound_register_focus(int id, const char *stream_type, mm_sound_focus_chan
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_register_focus(id, getpid(), stream_type, callback, false, user_data);
+       ret = mm_sound_client_register_focus(id, getpid(), stream_type, false, callback, user_data);
        if (ret) {
                debug_error("Could not register focus, ret[0x%x]\n", ret);
        }
@@ -151,7 +151,7 @@ int mm_sound_register_focus_for_session(int id, int pid, const char *stream_type
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_register_focus(id, pid, stream_type, callback, true, user_data);
+       ret = mm_sound_client_register_focus(id, pid, stream_type, true, callback, user_data);
        if (ret) {
                debug_error("Could not register focus for session, ret[0x%x]\n", ret);
        }
@@ -420,7 +420,7 @@ int mm_sound_set_focus_watch_callback(mm_sound_focus_type_e focus_type, mm_sound
                debug_error("argument is not valid\n");
                return MM_ERROR_INVALID_ARGUMENT;
        }
-       ret = mm_sound_client_set_focus_watch_callback(getpid(), focus_type, callback, false, user_data, id);
+       ret = mm_sound_client_set_focus_watch_callback(getpid(), focus_type, false, false, callback, user_data, id);
        if (ret) {
                debug_error("Could not set focus watch callback, ret[0x%x]\n", ret);
        }
@@ -443,7 +443,30 @@ int mm_sound_set_focus_watch_callback_for_session(int pid, mm_sound_focus_type_e
                debug_error("argument is not valid\n");
                return MM_ERROR_INVALID_ARGUMENT;
        }
-       ret = mm_sound_client_set_focus_watch_callback(pid, focus_type, callback, true, user_data, id);
+       ret = mm_sound_client_set_focus_watch_callback(pid, focus_type, true, false, callback, user_data, id);
+       if (ret) {
+               debug_error("Could not set focus watch callback, ret[0x%x]\n", ret);
+       }
+
+       debug_fleave();
+
+       return ret;
+}
+
+EXPORT_API
+int mm_sound_set_focus_watch_callback_for_session_monitor(int pid, mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id)
+{
+       int ret = MM_ERROR_NONE;
+
+       debug_fenter();
+
+       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
+
+       if (callback == NULL || id == NULL) {
+               debug_error("argument is not valid\n");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       ret = mm_sound_client_set_focus_watch_callback(pid, focus_type, true, true, callback, user_data, id);
        if (ret) {
                debug_error("Could not set focus watch callback, ret[0x%x]\n", ret);
        }
index 56cc7fd..7ff503d 100644 (file)
@@ -1151,14 +1151,14 @@ cleanup:
        return ret;
 }
 
-int mm_sound_proxy_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* userdata)
+int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, bool is_for_session, bool is_for_monitor, mm_sound_focus_changed_watch_cb callback, void* userdata)
 {
        int ret = MM_ERROR_NONE;
        GVariant *params = NULL, *result = NULL;
 
        debug_fenter();
 
-       params = g_variant_new("(iiib)", instance, handle, type, is_for_session);
+       params = g_variant_new("(iiibb)", instance, handle, type, is_for_session, is_for_monitor);
        if (params) {
                if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
                        debug_error("dbus set watch focus failed");
index 2d0771a..d3b998f 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-sound
 Summary:    MMSound Package contains client lib and sound_server binary
-Version:    0.10.111
+Version:    0.10.112
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0