Set active device properly for auto route, and other call family streams 55/106255/3
authorJeongho Mok <jho.mok@samsung.com>
Wed, 21 Dec 2016 03:49:25 +0000 (12:49 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Wed, 21 Dec 2016 10:38:04 +0000 (02:38 -0800)
[Version] 5.0.111
[Profile] Common
[Issue Type] Enhancement

Change-Id: Iacd318ba3c7bac4801c3d541e7c572aaac21278c

src/stream-manager.c

index 179807a..5d4dcff 100644 (file)
@@ -486,6 +486,27 @@ typedef struct _stream_route_option {
 static void do_notify(pa_stream_manager *m, notify_command_type_t command, stream_type_t type, bool is_new_data, void *user_data);
 static process_stream_result_t process_stream(pa_stream_manager *m, void *stream, stream_type_t type, process_command_type_t command, bool is_new_data);
 
+static bool stream_is_call_family(pa_object *stream) {
+    const char *stream_role;
+    pa_proplist *prop;
+
+    if (pa_sink_input_isinstance(stream))
+        prop = PA_SINK_INPUT(stream)->proplist;
+    else
+        prop = PA_SOURCE_OUTPUT(stream)->proplist;
+
+    stream_role = pa_proplist_gets(prop, PA_PROP_MEDIA_ROLE);
+
+    if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE))
+        return true;
+    else if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VIDEO))
+        return true;
+    else if (pa_safe_streq(stream_role, STREAM_ROLE_VOIP))
+        return true;
+
+    return false;
+}
+
 static int32_t get_available_streams(pa_stream_manager *m, stream_list *list) {
     void *state = NULL;
     stream_info *s = NULL;
@@ -748,26 +769,66 @@ static void activate_device_only(pa_tz_device *device, pa_stream_manager *m) {
     return ;
 }
 
-static pa_tz_device* get_media_last_device(dm_device_direction_t direction, pa_stream_manager *m) {
+static pa_tz_device* get_media_auto_device(dm_device_direction_t find_direction, pa_stream_manager *m) {
+    pa_idxset *avail_device_types;
+    char *device_type;
+    pa_tz_device *device;
+    dm_device_direction_t direction;
+    uint32_t idx;
+
+    pa_log_info("get media auto device for %d", find_direction);
+
+    if (find_direction == DM_DEVICE_DIRECTION_BOTH) {
+        pa_log_error("Invalid direction");
+        return NULL;
+    }
+
+    avail_device_types = get_avail_device_types(STREAM_ROLE_MEDIA, find_direction, m);
+    if (!avail_device_types) {
+        pa_log_error("No avail device types for media");
+        return NULL;
+    }
+
+    PA_IDXSET_FOREACH(device_type, avail_device_types, idx) {
+        device = pa_device_manager_get_device(m->dm, device_type);
+        if (!device)
+            continue;
+        direction = pa_tz_device_get_direction(device);
+        if (find_direction & direction)
+            return device;
+    }
+
+    return NULL;
+}
+
+static pa_tz_device* get_media_last_device(dm_device_direction_t find_direction, pa_stream_manager *m) {
     char *device_type;
     pa_tz_device *next_device, *latest_device = NULL;
     pa_usec_t creation_time = 0;
     pa_usec_t latest_creation_time = 0;
-    dm_device_direction_t direction2;
+    dm_device_direction_t direction;
     pa_idxset *avail_device_types;
     uint32_t idx, id;
 
+    pa_log_info("get media last device for %d", find_direction);
+
     /* Only can get playback or capture device one by one */
-    if (direction == DM_DEVICE_DIRECTION_BOTH)
+    if (find_direction == DM_DEVICE_DIRECTION_BOTH) {
+        pa_log_error("Invalid direction");
         return NULL;
+    }
 
-    avail_device_types = get_avail_device_types(STREAM_ROLE_MEDIA, direction, m);
+    avail_device_types = get_avail_device_types(STREAM_ROLE_MEDIA, find_direction, m);
+    if (!avail_device_types) {
+        pa_log_error("No avail device types for media");
+        return NULL;
+    }
 
     PA_IDXSET_FOREACH(device_type, avail_device_types, idx) {
         if ((next_device = pa_device_manager_get_device(m->dm, device_type))) {
             creation_time = pa_tz_device_get_creation_time(next_device);
-            direction2 = pa_tz_device_get_direction(next_device);
-            if ((direction & direction2) == 0)
+            direction = pa_tz_device_get_direction(next_device);
+            if ((find_direction & direction) == 0)
                 continue;
             if (!latest_device || (latest_creation_time <= creation_time)) {
                 latest_device = next_device;
@@ -779,9 +840,9 @@ static pa_tz_device* get_media_last_device(dm_device_direction_t direction, pa_s
     if (latest_device) {
         id = pa_tz_device_get_id(latest_device);
         device_type = pa_tz_device_get_type(latest_device);
-        pa_log_info("last %s-device to activate : (%s/%u)", direction == DM_DEVICE_DIRECTION_IN ? "in" : "out", device_type, id);
+        pa_log_info("last %s-device: (%s/%u)", find_direction == DM_DEVICE_DIRECTION_IN ? "in" : "out", device_type, id);
     } else {
-        pa_log_info("no %s-device", direction == DM_DEVICE_DIRECTION_IN ? "in" : "out");
+        pa_log_info("no %s-device", find_direction == DM_DEVICE_DIRECTION_IN ? "in" : "out");
     }
 
     return latest_device;
@@ -815,9 +876,12 @@ static pa_tz_device* select_device_from_avail_device_types(pa_idxset *avail_devi
     return candidate;
 }
 
+/* stream should be one of 'call-voice' or 'call-video' or 'voip' */
 static int change_active_route_for_call(pa_object *stream, bool stream_start, pa_stream_manager *m) {
     pa_tz_device *device;
     pa_idxset *avail_device_types, *route_devices;
+    pa_proplist *prop;
+    const char *stream_role;
 
     pa_assert(stream);
     pa_assert(m);
@@ -825,9 +889,21 @@ static int change_active_route_for_call(pa_object *stream, bool stream_start, pa
 
     pa_log_info("Call virtual stream %s, change active device", stream_start ? "start" : "change");
 
-    avail_device_types = get_avail_device_types(STREAM_ROLE_CALL_VOICE, GET_DIRECTION(stream), m);
+    if (pa_sink_input_isinstance(stream))
+        prop = PA_SINK_INPUT(stream)->proplist;
+    else
+        prop = PA_SOURCE_OUTPUT(stream)->proplist;
+
+    stream_role = pa_proplist_gets(prop, PA_PROP_MEDIA_ROLE);
+
+    if (stream_is_call_family(stream) == false) {
+        pa_log_error("Not call family stream");
+        return -1;
+    }
+
+    avail_device_types = get_avail_device_types(stream_role, GET_DIRECTION(stream), m);
     if (!avail_device_types) {
-        pa_log_error("No avail device typs for call");
+        pa_log_error("No avail device typs for [%s]", stream_role);
         return -1;
     }
     route_devices = get_route_devices(stream, m);
@@ -847,23 +923,35 @@ static int change_active_route_for_call(pa_object *stream, bool stream_start, pa
 }
 
 static void set_media_active_device(pa_stream_manager *m) {
-    pa_tz_device *device;
+    pa_tz_device *playback_device, *capture_device;
+    stream_info *media_info;
 
     pa_assert(m);
+    pa_assert(m->stream_infos);
 
     pa_log_info("set media active device");
 
-    device = get_media_last_device(DM_DEVICE_DIRECTION_IN, m);
-    if (device)
-        activate_device_only(device, m);
+    media_info = pa_hashmap_get(m->stream_infos, STREAM_ROLE_MEDIA);
+    if (media_info->route_type == STREAM_ROUTE_TYPE_AUTO) {
+        playback_device = get_media_auto_device(DM_DEVICE_DIRECTION_OUT, m);
+        capture_device = get_media_auto_device(DM_DEVICE_DIRECTION_IN, m);
+    } else if(media_info->route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
+        playback_device = get_media_last_device(DM_DEVICE_DIRECTION_OUT, m);
+        capture_device = get_media_last_device(DM_DEVICE_DIRECTION_IN, m);
+    } else {
+        pa_log_error("unexpected routing type for media[%d]", media_info->route_type);
+        return;
+    }
+
+    if (playback_device)
+        activate_device_only(playback_device, m);
     else
-        pa_log_info("There is no in-device");
+        pa_log_info("There is no playback-device");
 
-    device = get_media_last_device(DM_DEVICE_DIRECTION_OUT, m);
-    if (device)
-        activate_device_only(device, m);
+    if (capture_device)
+        activate_device_only(capture_device, m);
     else
-        pa_log_info("There is no out-device");
+        pa_log_info("There is no capture-device");
 }
 
 static void set_initial_active_device(pa_stream_manager *m) {
@@ -940,8 +1028,7 @@ static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *m
                     pa_log_debug(" -- cur_highest_priority.source_output->index[%u] belongs to this parent id[%u], do notify for the route change",
                             (m->cur_highest_priority.source_output)->index, id);
                     do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, false, m->cur_highest_priority.source_output);
-                    stream_role = pa_proplist_gets(GET_STREAM_PROPLIST(m->cur_highest_priority.source_output, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROLE);
-                    if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE) && m->on_call) {
+                    if (stream_is_call_family(PA_OBJECT(m->cur_highest_priority.source_output)) && m->on_call) {
                         pa_log_info("set active device for new call route device");
                         change_active_route_for_call(PA_OBJECT(m->cur_highest_priority.source_output), false, m);
                     }
@@ -983,8 +1070,7 @@ static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *m
                     pa_log_debug(" -- cur_highest_priority.sink_input->index[%u] belongs to this parent id[%u], do notify for the route change",
                             (m->cur_highest_priority.sink_input)->index, id);
                     do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, m->cur_highest_priority.sink_input);
-                    stream_role = pa_proplist_gets(GET_STREAM_PROPLIST(m->cur_highest_priority.sink_input, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROLE);
-                    if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE) && m->on_call) {
+                    if (stream_is_call_family(PA_OBJECT(m->cur_highest_priority.sink_input)) && m->on_call) {
                         pa_log_info("set active device for new call route device");
                         change_active_route_for_call(PA_OBJECT(m->cur_highest_priority.sink_input), false, m);
                     }
@@ -1344,19 +1430,11 @@ fail:
 static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     const char *direction = NULL;
     const char *device_type = NULL;
-    const char *dm_device_type = NULL;
     dm_device_direction_t dm_device_direction = DM_DEVICE_DIRECTION_NONE;
     stream_info *s = NULL;
-    stream_type_t stream_type = STREAM_SINK_INPUT;
     DBusMessage *reply = NULL;
-    uint32_t idx = 0;
-    uint32_t conn_idx = 0;
-    pa_idxset *conn_devices = NULL;
     pa_tz_device *device = NULL;
-    pa_tz_device *latest_device = NULL;
     pa_stream_manager *m = (pa_stream_manager*)userdata;
-    pa_usec_t creation_time = 0;
-    pa_usec_t latest_creation_time = 0;
 
     pa_assert(conn);
     pa_assert(msg);
@@ -1369,53 +1447,35 @@ static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMess
 
     pa_assert_se((reply = dbus_message_new_method_return(msg)));
 
-    if (pa_streq(direction, "in"))
-        stream_type = STREAM_SOURCE_OUTPUT;
-    else if (pa_streq(direction, "out"))
-        stream_type = STREAM_SINK_INPUT;
-    else {
-        pa_log_error("invalid stream type[%s]", direction);
+    if (pa_streq(direction, "in")) {
+        dm_device_direction = DM_DEVICE_DIRECTION_IN;
+    } else if (pa_streq(direction, "out")) {
+        dm_device_direction = DM_DEVICE_DIRECTION_OUT;
+    else {
+        pa_log_error("invalid direction[%s]", direction);
         goto fail;
     }
 
-    if ((s = pa_hashmap_get(m->stream_infos, STREAM_ROLE_MEDIA))) {
-        /* get current connected devices */
-        conn_devices = pa_device_manager_get_device_list(m->dm);
-
-        if (s->route_type == STREAM_ROUTE_TYPE_AUTO) {
-            PA_IDXSET_FOREACH(device_type, (stream_type == STREAM_SINK_INPUT) ? s->idx_avail_out_devices : s->idx_avail_in_devices, idx) {
-                PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
-                    dm_device_type = pa_tz_device_get_type(device);
-                    dm_device_direction = pa_tz_device_get_direction(device);
-                    if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(stream_type, dm_device_direction))
-                        goto success;
-                }
-            }
-            pa_log_error("could not found matched device");
-        } else if (s->route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
-            PA_IDXSET_FOREACH(device_type, (stream_type == STREAM_SINK_INPUT) ? s->idx_avail_out_devices : s->idx_avail_in_devices, idx) {
-                PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
-                    dm_device_type = pa_tz_device_get_type(device);
-                    dm_device_direction = pa_tz_device_get_direction(device);
-                    creation_time = pa_tz_device_get_creation_time(device);
-                    if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(stream_type, dm_device_direction)) {
-                        if (!latest_device || (latest_creation_time <= creation_time)) {
-                            latest_device = device;
-                            latest_creation_time = creation_time;
-                        }
-                    }
-                }
-            }
-            if (latest_device) {
-                device_type = pa_tz_device_get_type(latest_device);
-                goto success;
-            }
-            pa_log_error("could not found matched device");
-        } else
-          pa_log_error("unexpected routing type for media[%d]", s->route_type);
-
-    } else
+    if ((s = pa_hashmap_get(m->stream_infos, STREAM_ROLE_MEDIA)) == NULL) {
         pa_log_error("could not find media role");
+        goto fail;
+    }
+
+    if (s->route_type == STREAM_ROUTE_TYPE_AUTO) {
+        device = get_media_auto_device(dm_device_direction, m);
+    } else if (s->route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
+        device = get_media_last_device(dm_device_direction, m);
+    } else {
+        pa_log_error("unexpected routing type for media[%d]", s->route_type);
+        goto fail;
+    }
+
+    if (device) {
+        device_type = pa_tz_device_get_type(device);
+        goto success;
+    } else {
+        pa_log_error("could not found matched device");
+    }
 
 fail:
     pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &dbus_str_none, DBUS_TYPE_INVALID));
@@ -3143,8 +3203,7 @@ static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, pa_st
     pa_log_debug("start sink_input_put_cb, i(%p, index:%u)", i, i->index);
 
     process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_ADD_PARENT_ID, false);
-    stream_role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE);
-    if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+    if (stream_is_call_family(PA_OBJECT(i))) {
         change_active_route_for_call(PA_OBJECT(i), true, m);
         m->on_call = true;
     }
@@ -3159,8 +3218,7 @@ static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, pa
 
     pa_log_debug("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index);
 
-    stream_role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE);
-    if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+    if (stream_is_call_family(PA_OBJECT(i))) {
         m->on_call = false;
         set_media_active_device(m);
     }
@@ -3251,8 +3309,7 @@ static pa_hook_result_t source_output_put_cb(pa_core *core, pa_source_output *o,
 
     update_mirroring_streams(m, o, true);
     process_stream(m, o, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_ADD_PARENT_ID, false);
-    stream_role = pa_proplist_gets(o->proplist, PA_PROP_MEDIA_ROLE);
-    if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+    if (stream_is_call_family(PA_OBJECT(o))) {
         change_active_route_for_call(PA_OBJECT(o), true, m);
         m->on_call = true;
     }
@@ -3267,8 +3324,7 @@ static pa_hook_result_t source_output_unlink_cb(pa_core *core, pa_source_output
 
     pa_log_info("start source_output_unlink_cb, o(%p, index:%u)", o, o->index);
 
-    stream_role = pa_proplist_gets(o->proplist, PA_PROP_MEDIA_ROLE);
-    if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+    if (stream_is_call_family(PA_OBJECT(o))) {
         m->on_call = false;
         set_media_active_device(m);
     }