return false;
}
+static int32_t convert_route_type(const char *route_type_str, stream_route_type_t *route_type) {
+ int ret = 0;
+
+ pa_assert(route_type);
+ pa_assert(route_type_str);
+
+ if (pa_streq("auto", route_type_str))
+ *route_type = STREAM_ROUTE_TYPE_AUTO;
+ else if (pa_streq("auto-last-connected", route_type_str))
+ *route_type = STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED;
+ else if (pa_streq("auto-all", route_type_str))
+ *route_type = STREAM_ROUTE_TYPE_AUTO_ALL;
+ else if (pa_streq("manual", route_type_str))
+ *route_type = STREAM_ROUTE_TYPE_MANUAL;
+ else if (pa_streq("manual-ext", route_type_str))
+ *route_type = STREAM_ROUTE_TYPE_MANUAL_EXT;
+ else {
+ ret = -1;
+ pa_log_error("Not supported route_type(%s)", route_type_str);
+ }
+
+ return ret;
+}
+
+static int32_t get_route_type(void *stream, stream_type_t stream_type, bool is_new_data, stream_route_type_t *stream_route_type) {
+ const char *route_type_str = NULL;
+
+ pa_assert(stream);
+ pa_assert(stream_route_type);
+
+ if (is_new_data)
+ route_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, stream_type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
+ else
+ route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, stream_type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
+ if (!route_type_str) {
+ pa_log_warn("could not get route type from the stream(%p)", stream);
+ return -1;
+ }
+
+ if (pa_atoi(route_type_str, (int32_t*)stream_route_type)) {
+ pa_log_error("could not convert route_type_str(%s) to int", route_type_str);
+ return -1;
+ }
+
+ return 0;
+}
+
static int32_t get_available_streams(pa_stream_manager *m, stream_list *list) {
void *state = NULL;
stream_info *s = NULL;
set_media_active_device(m);
}
+static void update_devices_and_trigger_routing(pa_stream_manager *m, stream_parent *sp, stream_type_t type) {
+ void *stream = NULL;
+ pa_idxset *idx_streams = NULL;
+ uint32_t idx = 0;
+ void *cur_highest_priority_stream = NULL;
+ focus_acquired_status_t acquired_status = STREAM_FOCUS_ACQUIRED_NONE;
+ stream_route_type_t route_type = STREAM_ROUTE_TYPE_DEFAULT;
+
+ pa_assert(m);
+ pa_assert(sp);
+
+ if (type == STREAM_SINK_INPUT) {
+ idx_streams = sp->idx_sink_inputs;
+ cur_highest_priority_stream = (void*)m->cur_highest_priority.sink_input;
+ acquired_status = STREAM_FOCUS_ACQUIRED_PLAYBACK;
+ } else {
+ idx_streams = sp->idx_source_outputs;
+ cur_highest_priority_stream = (void*)m->cur_highest_priority.source_output;
+ acquired_status = STREAM_FOCUS_ACQUIRED_CAPTURE;
+ }
+
+ /* update route type of this stream parent */
+ if (sp->route_type == STREAM_ROUTE_TYPE_DEFAULT) {
+ PA_IDXSET_FOREACH(stream, idx_streams, idx) {
+ /* find route type of stream */
+ if (!get_route_type(stream, type, false, &route_type)) {
+ if (route_type == STREAM_ROUTE_TYPE_MANUAL ||
+ route_type == STREAM_ROUTE_TYPE_MANUAL_EXT) {
+ sp->route_type = route_type;
+ pa_log_info(" -- the route type is [%d]", route_type);
+ } else {
+ pa_log_error(" -- the route type is not valid[%d]", route_type);
+ return;
+ }
+ } else
+ return;
+ }
+ }
+
+ /* if any stream that belongs to this id has been activated, do notify right away */
+ if (sp->route_type == STREAM_ROUTE_TYPE_MANUAL_EXT) {
+ PA_IDXSET_FOREACH(stream, idx_streams, idx) {
+ pa_log_debug(" -- stream->index[%u] belongs to this stream parent[%p], do notify for the select proper source",
+ GET_STREAM_INDEX(stream, type), sp);
+ do_notify(m, NOTIFY_COMMAND_SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT, type, false, stream);
+ }
+ } else if (cur_highest_priority_stream) {
+ /* trigger only when the stream parent has focus */
+ if ((sp->focus_status & acquired_status) && pa_idxset_get_by_data(idx_streams, cur_highest_priority_stream, NULL)) {
+ pa_log_debug(" -- cur_highest_priority_stream->index[%u] belongs to this stream_parent[%p], do notify for the route change",
+ GET_STREAM_INDEX(cur_highest_priority_stream, type), sp);
+ do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, type, false, cur_highest_priority_stream);
+ if (stream_is_call_family(PA_OBJECT(cur_highest_priority_stream)) && m->on_call) {
+ pa_log_info("set active device for new call route device");
+ change_active_route_for_call(PA_OBJECT(cur_highest_priority_stream), false, m);
+ }
+ }
+ }
+}
+
static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *msg, void *userdata) {
uint32_t id = 0;
int i = 0;
int list_len_out = 0;
uint32_t idx = 0;
uint32_t *device_id = NULL;
- void *stream = NULL;
stream_parent *sp = NULL;
- const char *route_type_str = NULL;
- stream_route_type_t route_type;
DBusMessage *reply = NULL;
pa_stream_manager *m = (pa_stream_manager*)userdata;
pa_log_error("invalid arguments");
goto fail;
}
-
- if (sp->idx_route_in_devices) {
- PA_IDXSET_FOREACH(device_id, sp->idx_route_in_devices, idx) {
- pa_idxset_remove_by_data(sp->idx_route_in_devices, device_id, NULL);
- pa_xfree(device_id);
- }
- if (in_device_list && list_len_in) {
- for (i = 0; i < list_len_in; i++) {
- pa_idxset_put(sp->idx_route_in_devices, pa_xmemdup(&in_device_list[i], sizeof(uint32_t)), NULL);
- pa_log_debug(" -- [in] device id:%u", in_device_list[i]);
- }
- }
- PA_IDXSET_FOREACH(stream, sp->idx_source_outputs, idx) {
- /* find route type of stream */
- route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
- if (route_type_str) {
- pa_log_debug(" -- the route type of source_output that belongs to this parent id[%u] is [%s]", id, route_type_str);
- break;
- }
- }
- /* if any stream that belongs to this id has been activated, do notify right away */
- if (IS_ROUTE_TYPE_FOR_EXTERNAL_DEV(route_type_str, route_type)) {
- PA_IDXSET_FOREACH(stream, sp->idx_source_outputs, idx) {
- pa_log_debug(" -- source_output[%p] belongs to this parent id[%u], do notify for the select proper source", stream, id);
- do_notify(m, NOTIFY_COMMAND_SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT, STREAM_SOURCE_OUTPUT, false, stream);
- }
- } else if (m->cur_highest_priority.source_output) {
- if (pa_idxset_get_by_data(sp->idx_source_outputs, m->cur_highest_priority.source_output, NULL)) {
- 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);
- 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);
- }
- }
- }
- } else {
- pa_log_error("failed to update, idx_route_in_devices[%p]", sp->idx_route_in_devices);
+ if (!sp->idx_route_in_devices || !sp->idx_route_out_devices) {
+ pa_log_error("failed to update, idx_route_in_devices[%p], idx_route_out_devices[%p]",
+ sp->idx_route_in_devices, sp->idx_route_out_devices);
goto fail;
}
- if (sp->idx_route_out_devices) {
- PA_IDXSET_FOREACH(device_id, sp->idx_route_out_devices, idx) {
- pa_idxset_remove_by_data(sp->idx_route_out_devices, device_id, NULL);
- pa_xfree(device_id);
- }
- if (out_device_list && list_len_out) {
- for (i = 0; i < list_len_out; i++) {
- pa_idxset_put(sp->idx_route_out_devices, pa_xmemdup(&out_device_list[i], sizeof(uint32_t)), NULL);
- pa_log_debug(" -- [out] device id:%u", out_device_list[i]);
- }
- }
- PA_IDXSET_FOREACH(stream, sp->idx_sink_inputs, idx) {
- /* find route type of stream */
- route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
- if (route_type_str) {
- pa_log_debug(" -- the route type of sink_input that belongs to this parent id[%u] is [%s]", id, route_type_str);
- break;
- }
+ PA_IDXSET_FOREACH(device_id, sp->idx_route_in_devices, idx) {
+ pa_idxset_remove_by_data(sp->idx_route_in_devices, device_id, NULL);
+ pa_xfree(device_id);
+ }
+ if (in_device_list && list_len_in) {
+ for (i = 0; i < list_len_in; i++) {
+ pa_idxset_put(sp->idx_route_in_devices, pa_xmemdup(&in_device_list[i], sizeof(uint32_t)), NULL);
+ pa_log_debug(" -- [in] device id:%u", in_device_list[i]);
}
- /* if any stream that belongs to this id has been activated, do notify right away */
- if (IS_ROUTE_TYPE_FOR_EXTERNAL_DEV(route_type_str, route_type)) {
- PA_IDXSET_FOREACH(stream, sp->idx_sink_inputs, idx) {
- pa_log_debug(" -- sink_input[%p] belongs to this parent id[%u], do notify for the select proper sink", stream, id);
- do_notify(m, NOTIFY_COMMAND_SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT, STREAM_SINK_INPUT, false, stream);
- }
- } else if (m->cur_highest_priority.sink_input) {
- if (pa_idxset_get_by_data(sp->idx_sink_inputs, m->cur_highest_priority.sink_input, NULL)) {
- 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);
- 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);
- }
- }
+ }
+ update_devices_and_trigger_routing(m, sp, STREAM_SOURCE_OUTPUT);
+
+ PA_IDXSET_FOREACH(device_id, sp->idx_route_out_devices, idx) {
+ pa_idxset_remove_by_data(sp->idx_route_out_devices, device_id, NULL);
+ pa_xfree(device_id);
+ }
+ if (out_device_list && list_len_out) {
+ for (i = 0; i < list_len_out; i++) {
+ pa_idxset_put(sp->idx_route_out_devices, pa_xmemdup(&out_device_list[i], sizeof(uint32_t)), NULL);
+ pa_log_debug(" -- [out] device id:%u", out_device_list[i]);
}
- } else {
- pa_log_error("failed to update, idx_route_out_devices[%p]", sp->idx_route_out_devices);
- goto fail;
}
+ update_devices_and_trigger_routing(m, sp, STREAM_SINK_INPUT);
+
pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID));
} else {
pa_log_error("could not find matching client for this parent_id[%u]", id);
}
#endif
-static int32_t convert_route_type(stream_route_type_t *route_type, const char *route_type_string) {
- int ret = 0;
-
- pa_assert(route_type);
- pa_assert(route_type_string);
-
- if (pa_streq("auto", route_type_string))
- *route_type = STREAM_ROUTE_TYPE_AUTO;
- else if (pa_streq("auto-last-connected", route_type_string))
- *route_type = STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED;
- else if (pa_streq("auto-all", route_type_string))
- *route_type = STREAM_ROUTE_TYPE_AUTO_ALL;
- else if (pa_streq("manual", route_type_string))
- *route_type = STREAM_ROUTE_TYPE_MANUAL;
- else if (pa_streq("manual-ext", route_type_string))
- *route_type = STREAM_ROUTE_TYPE_MANUAL_EXT;
- else {
- ret = -1;
- pa_log_error("Not supported route_type(%s)", route_type_string);
- }
-
- return ret;
-}
-
-static int32_t get_route_type(void *stream, stream_type_t stream_type, bool is_new_data, stream_route_type_t *stream_route_type) {
- const char *route_type_str = NULL;
-
- pa_assert(stream);
- pa_assert(stream_route_type);
-
- if (is_new_data)
- route_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, stream_type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
- else
- route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, stream_type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
- if (!route_type_str) {
- pa_log_warn("could not get route type from the stream(%p)", stream);
- return -1;
- }
-
- if (pa_atoi(route_type_str, (int32_t*)stream_route_type)) {
- pa_log_error("could not convert route_type_str(%s) to int", route_type_str);
- return -1;
- }
-
- return 0;
-}
-
static void dump_stream_map(pa_stream_manager *m) {
stream_info *s = NULL;
const char *role = NULL;
goto fail;
}
if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_ROUTE_TYPE, &item_o) && json_object_is_type(item_o, json_type_string)) {
- if (convert_route_type(&(s->route_type), json_object_get_string(item_o))) {
+ if (convert_route_type(json_object_get_string(item_o), &(s->route_type))) {
pa_log_error("convert stream route-type failed");
goto fail;
}
pa_log_debug("p_idx(%s), idx(%u)", p_idx, parent_idx);
sp = pa_hashmap_get(m->stream_parents, (const void*)parent_idx);
if (sp) {
- uint32_t idx = (type == STREAM_SINK_INPUT) ? ((pa_sink_input*)stream)->index : ((pa_source_output*)stream)->index;
+ uint32_t idx = GET_STREAM_INDEX(stream, type);
if (command == PROCESS_COMMAND_ADD_PARENT_ID) {
/* append this stream to the parent stream info. */
pa_log_debug(" - append this stream(%p, %u) to the list. sp(%p), stream_type(%d)", stream, idx, sp, type);
if (s) {
stream_conn_info.role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE);
stream_conn_info.direction = (type == STREAM_SINK_INPUT) ? DIRECTION_OUT : DIRECTION_IN;
- stream_conn_info.idx = (type == STREAM_SINK_INPUT) ? ((pa_sink_input*)s)->index : ((pa_source_output*)s)->index;
+ stream_conn_info.idx = GET_STREAM_INDEX(s, type);
stream_conn_info.is_connected = (command == NOTIFY_COMMAND_INFORM_STREAM_CONNECTED) ? true : false;
pa_hal_interface_notify_stream_connection_changed(m->hal, &stream_conn_info);
}
} else
pa_log_error(" -- could not find current device type for s->source(%p)", ((pa_source_output*)s)->source);
} else
- pa_log_debug("no need to move for stream(%p, idx:%u)", s, (stream_type == STREAM_SINK_INPUT ?
- ((pa_sink_input*)s)->index : ((pa_source_output*)s)->index));
+ pa_log_debug("no need to move for stream(%p, idx:%u)", s, GET_STREAM_INDEX(s, stream_type));
+
if (available) {
cached_prev_dev_list[cnt++].device_type = cur_device_type;
/* trigger to update routing path */