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;
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;
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;
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);
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);
}
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) {
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);
}
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);
}
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);
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));
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;
}
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);
}
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;
}
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);
}