sink-input: change bool save_sink to char *preferred_sink

The finial objective is to store the preferred sink name in the
sink-input struct, and use module-stream-restore to save and restore
it.

This patch just replaces the save_sink with preferred_sink, and tries
to keep the original logic.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
This commit is contained in:
Hui Wang 2019-01-15 12:12:52 +08:00
parent 26a66d103f
commit fbf8716685
6 changed files with 55 additions and 28 deletions

View file

@ -656,14 +656,14 @@ static void route_sink_input(struct userdata *u, pa_sink_input *si) {
pa_assert(u); pa_assert(u);
pa_assert(u->do_routing); pa_assert(u->do_routing);
/* Don't override user or application routing requests. */
if (si->save_sink || si->sink_requested_by_application)
return;
/* Skip this if it is already in the process of being moved anyway */ /* Skip this if it is already in the process of being moved anyway */
if (!si->sink) if (!si->sink)
return; return;
/* Don't override user or application routing requests. */
if (pa_safe_streq(si->sink->name, si->preferred_sink) || si->sink_requested_by_application)
return;
auto_filtered_prop = pa_proplist_gets(si->proplist, "module-device-manager.auto_filtered"); auto_filtered_prop = pa_proplist_gets(si->proplist, "module-device-manager.auto_filtered");
if (auto_filtered_prop) if (auto_filtered_prop)
auto_filtered = (pa_parse_boolean(auto_filtered_prop) == 1); auto_filtered = (pa_parse_boolean(auto_filtered_prop) == 1);

View file

@ -175,14 +175,14 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
if (si->sink == sink) if (si->sink == sink)
continue; continue;
if (si->save_sink)
continue;
/* Skip this if it is already in the process of being moved /* Skip this if it is already in the process of being moved
* anyway */ * anyway */
if (!si->sink) if (!si->sink)
continue; continue;
if (pa_safe_streq(si->sink->name, si->preferred_sink))
continue;
/* It might happen that a stream and a sink are set up at the /* It might happen that a stream and a sink are set up at the
same time, in which case we want to make sure we don't same time, in which case we want to make sure we don't
interfere with that */ interfere with that */

View file

@ -1311,15 +1311,17 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted); mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
} }
if (sink_input->save_sink) { if (sink_input->preferred_sink != NULL) {
pa_sink *s;
pa_xfree(entry->device); pa_xfree(entry->device);
entry->device = pa_xstrdup(sink_input->sink->name); entry->device = pa_xstrdup(sink_input->preferred_sink);
entry->device_valid = true; entry->device_valid = true;
device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device)); device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
if (sink_input->sink->card) { s = pa_namereg_get(c, entry->device, PA_NAMEREG_SINK);
if (s && s->card) {
pa_xfree(entry->card); pa_xfree(entry->card);
entry->card = pa_xstrdup(sink_input->sink->card->name); entry->card = pa_xstrdup(s->card->name);
entry->card_valid = true; entry->card_valid = true;
} }
} }
@ -1650,14 +1652,14 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
if (si->sink == sink) if (si->sink == sink)
continue; continue;
if (si->save_sink)
continue;
/* Skip this if it is already in the process of being moved /* Skip this if it is already in the process of being moved
* anyway */ * anyway */
if (!si->sink) if (!si->sink)
continue; continue;
if (pa_safe_streq(si->sink->name, si->preferred_sink))
continue;
/* Skip this sink input if it is connecting a filter sink to /* Skip this sink input if it is connecting a filter sink to
* the master */ * the master */
if (si->origin_sink) if (si->origin_sink)
@ -1951,12 +1953,13 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) {
if (u->restore_device) { if (u->restore_device) {
if (!e->device_valid) { if (!e->device_valid) {
if (si->save_sink) { if (si->preferred_sink != NULL) {
pa_log_info("Ensuring device is not saved for stream %s.", name); pa_log_info("Ensuring device is not saved for stream %s.", name);
/* If the device is not valid we should make sure the /* If the device is not valid we should make sure the
save flag is cleared as the user may have specifically preferred_sink is cleared as the user may have specifically
removed the sink element from the rule. */ removed the sink element from the rule. */
si->save_sink = false; pa_xfree(si->preferred_sink);
si->preferred_sink = NULL;
/* This is cheating a bit. The sink input itself has not changed /* This is cheating a bit. The sink input itself has not changed
but the rules governing its routing have, so we fire this event but the rules governing its routing have, so we fire this event
such that other routing modules (e.g. module-device-manager) such that other routing modules (e.g. module-device-manager)

View file

@ -124,7 +124,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
} }
PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) { PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
if (i->save_sink || !PA_SINK_INPUT_IS_LINKED(i->state)) if (pa_safe_streq(i->sink->name, i->preferred_sink) || !PA_SINK_INPUT_IS_LINKED(i->state))
continue; continue;
if (pa_sink_input_move_to(i, sink, false) < 0) if (pa_sink_input_move_to(i, sink, false) < 0)

View file

@ -190,7 +190,10 @@ bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, b
if (!data->req_formats) { if (!data->req_formats) {
/* We're not working with the extended API */ /* We're not working with the extended API */
data->sink = s; data->sink = s;
data->save_sink = save; if (save) {
pa_xfree(data->preferred_sink);
data->preferred_sink = pa_xstrdup(s->name);
}
data->sink_requested_by_application = requested_by_application; data->sink_requested_by_application = requested_by_application;
} else { } else {
/* Extended API: let's see if this sink supports the formats the client can provide */ /* Extended API: let's see if this sink supports the formats the client can provide */
@ -199,7 +202,10 @@ bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, b
if (formats && !pa_idxset_isempty(formats)) { if (formats && !pa_idxset_isempty(formats)) {
/* Sink supports at least one of the requested formats */ /* Sink supports at least one of the requested formats */
data->sink = s; data->sink = s;
data->save_sink = save; if (save) {
pa_xfree(data->preferred_sink);
data->preferred_sink = pa_xstrdup(s->name);
}
data->sink_requested_by_application = requested_by_application; data->sink_requested_by_application = requested_by_application;
if (data->nego_formats) if (data->nego_formats)
pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free); pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
@ -226,7 +232,7 @@ bool pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset
if (data->sink) { if (data->sink) {
/* Trigger format negotiation */ /* Trigger format negotiation */
return pa_sink_input_new_data_set_sink(data, data->sink, data->save_sink, data->sink_requested_by_application); return pa_sink_input_new_data_set_sink(data, data->sink, (data->preferred_sink != NULL), data->sink_requested_by_application);
} }
return true; return true;
@ -250,6 +256,9 @@ void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
if (data->volume_factor_sink_items) if (data->volume_factor_sink_items)
pa_hashmap_free(data->volume_factor_sink_items); pa_hashmap_free(data->volume_factor_sink_items);
if (data->preferred_sink)
pa_xfree(data->preferred_sink);
pa_proplist_free(data->proplist); pa_proplist_free(data->proplist);
} }
@ -518,7 +527,7 @@ int pa_sink_input_new(
pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels); pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
i->volume_writable = data->volume_writable; i->volume_writable = data->volume_writable;
i->save_volume = data->save_volume; i->save_volume = data->save_volume;
i->save_sink = data->save_sink; i->preferred_sink = pa_xstrdup(data->preferred_sink);
i->save_muted = data->save_muted; i->save_muted = data->save_muted;
i->muted = data->muted; i->muted = data->muted;
@ -776,6 +785,9 @@ static void sink_input_free(pa_object *o) {
if (i->volume_factor_sink_items) if (i->volume_factor_sink_items)
pa_hashmap_free(i->volume_factor_sink_items); pa_hashmap_free(i->volume_factor_sink_items);
if (i->preferred_sink)
pa_xfree(i->preferred_sink);
pa_xfree(i->driver); pa_xfree(i->driver);
pa_xfree(i); pa_xfree(i);
} }
@ -1914,7 +1926,12 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, bool save) {
i->moving(i, dest); i->moving(i, dest);
i->sink = dest; i->sink = dest;
i->save_sink = save; /* save == true, means user is calling the move_to() and want to
save the preferred_sink */
if (save) {
pa_xfree(i->preferred_sink);
i->preferred_sink = pa_xstrdup(dest->name);
}
pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL); pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state) PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)

View file

@ -119,11 +119,16 @@ struct pa_sink_input {
bool muted:1; bool muted:1;
/* if true then the sink we are connected to and/or the volume /* if true then the volume and the mute state of this sink-input
* set is worth remembering, i.e. was explicitly chosen by the * are worth remembering, module-stream-restore looks for
* user and not automatically. module-stream-restore looks for
* this.*/ * this.*/
bool save_sink:1, save_volume:1, save_muted:1; bool save_volume:1, save_muted:1;
/* if users move the sink-input to a sink, and the sink is not default_sink,
* the sink->name will be saved in preferred_sink. And later if sink-input
* is moved to other sinks for some reason, it still can be restored to the
* preferred_sink at an appropriate time */
char *preferred_sink;
pa_resample_method_t requested_resample_method, actual_resample_method; pa_resample_method_t requested_resample_method, actual_resample_method;
@ -315,7 +320,9 @@ typedef struct pa_sink_input_new_data {
bool volume_writable:1; bool volume_writable:1;
bool save_sink:1, save_volume:1, save_muted:1; bool save_volume:1, save_muted:1;
char *preferred_sink;
} pa_sink_input_new_data; } pa_sink_input_new_data;
pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data); pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);