source-output: change bool save_source to char *preferred_source

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

This patch just replaces the save_source with preferred_source, and
tries to keep the original logic.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
This commit is contained in:
Hui Wang 2019-12-06 21:51:10 +08:00 committed by Tanu Kaskinen
parent 734a00c849
commit 5eec504d68
6 changed files with 54 additions and 29 deletions

View file

@ -728,10 +728,6 @@ static void route_source_output(struct userdata *u, pa_source_output *so) {
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 (so->save_source || so->source_requested_by_application)
return;
if (so->direct_on_input) if (so->direct_on_input)
return; return;
@ -739,6 +735,10 @@ static void route_source_output(struct userdata *u, pa_source_output *so) {
if (!so->source) if (!so->source)
return; return;
/* Don't override user or application routing requests. */
if (pa_safe_streq(so->source->name, so->preferred_source) || so->source_requested_by_application)
return;
auto_filtered_prop = pa_proplist_gets(so->proplist, "module-device-manager.auto_filtered"); auto_filtered_prop = pa_proplist_gets(so->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

@ -222,9 +222,6 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (so->source == source) if (so->source == source)
continue; continue;
if (so->save_source)
continue;
if (so->direct_on_input) if (so->direct_on_input)
continue; continue;
@ -233,6 +230,9 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (!so->source) if (!so->source)
continue; continue;
if (pa_safe_streq(so->source->name, so->preferred_source))
continue;
/* It might happen that a stream and a source are set up at the /* It might happen that a stream and a source 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

@ -1369,16 +1369,18 @@ 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 (source_output->save_source) { if (source_output->preferred_source != NULL) {
pa_source *s;
pa_xfree(entry->device); pa_xfree(entry->device);
entry->device = pa_xstrdup(source_output->source->name); entry->device = pa_xstrdup(source_output->preferred_source);
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 (source_output->source->card) { s = pa_namereg_get(c, entry->device, PA_NAMEREG_SOURCE);
if (s && s->card) {
pa_xfree(entry->card); pa_xfree(entry->card);
entry->card = pa_xstrdup(source_output->source->card->name); entry->card = pa_xstrdup(s->card->name);
entry->card_valid = true; entry->card_valid = true;
} }
} }
@ -1653,9 +1655,6 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (so->source == source) if (so->source == source)
continue; continue;
if (so->save_source)
continue;
if (so->direct_on_input) if (so->direct_on_input)
continue; continue;
@ -1663,6 +1662,9 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (!so->source) if (!so->source)
continue; continue;
if (pa_safe_streq(so->source->name, so->preferred_source))
continue;
/* Skip this source output if it is connecting a filter source to /* Skip this source output if it is connecting a filter source to
* the master */ * the master */
if (so->destination_source) if (so->destination_source)
@ -1898,12 +1900,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 (so->save_source) { if (so->preferred_source != 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_source is cleared as the user may have specifically
removed the source element from the rule. */ removed the source element from the rule. */
so->save_source = false; pa_xfree(so->preferred_source);
so->preferred_source = NULL;
/* This is cheating a bit. The source output itself has not changed /* This is cheating a bit. The source output 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

@ -184,7 +184,7 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
} }
PA_IDXSET_FOREACH(o, old_default_source->outputs, idx) { PA_IDXSET_FOREACH(o, old_default_source->outputs, idx) {
if (o->save_source || !PA_SOURCE_OUTPUT_IS_LINKED(o->state)) if (pa_safe_streq(o->source->name, o->preferred_source) || !PA_SOURCE_OUTPUT_IS_LINKED(o->state))
continue; continue;
if (pa_source_output_move_to(o, source, false) < 0) if (pa_source_output_move_to(o, source, false) < 0)

View file

@ -134,7 +134,10 @@ bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_so
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->source = s; data->source = s;
data->save_source = save; if (save) {
pa_xfree(data->preferred_source);
data->preferred_source = pa_xstrdup(s->name);
}
data->source_requested_by_application = requested_by_application; data->source_requested_by_application = requested_by_application;
} else { } else {
/* Extended API: let's see if this source supports the formats the client would like */ /* Extended API: let's see if this source supports the formats the client would like */
@ -143,7 +146,10 @@ bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_so
if (formats && !pa_idxset_isempty(formats)) { if (formats && !pa_idxset_isempty(formats)) {
/* Source supports at least one of the requested formats */ /* Source supports at least one of the requested formats */
data->source = s; data->source = s;
data->save_source = save; if (save) {
pa_xfree(data->preferred_source);
data->preferred_source = pa_xstrdup(s->name);
}
data->source_requested_by_application = requested_by_application; data->source_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);
@ -170,7 +176,7 @@ bool pa_source_output_new_data_set_formats(pa_source_output_new_data *data, pa_i
if (data->source) { if (data->source) {
/* Trigger format negotiation */ /* Trigger format negotiation */
return pa_source_output_new_data_set_source(data, data->source, data->save_source, return pa_source_output_new_data_set_source(data, data->source, (data->preferred_source != NULL),
data->source_requested_by_application); data->source_requested_by_application);
} }
@ -189,6 +195,9 @@ void pa_source_output_new_data_done(pa_source_output_new_data *data) {
if (data->format) if (data->format)
pa_format_info_free(data->format); pa_format_info_free(data->format);
if (data->preferred_source)
pa_xfree(data->preferred_source);
pa_proplist_free(data->proplist); pa_proplist_free(data->proplist);
} }
@ -460,7 +469,7 @@ int pa_source_output_new(
pa_cvolume_reset(&o->real_ratio, o->sample_spec.channels); pa_cvolume_reset(&o->real_ratio, o->sample_spec.channels);
o->volume_writable = data->volume_writable; o->volume_writable = data->volume_writable;
o->save_volume = data->save_volume; o->save_volume = data->save_volume;
o->save_source = data->save_source; o->preferred_source = pa_xstrdup(data->preferred_source);
o->save_muted = data->save_muted; o->save_muted = data->save_muted;
o->muted = data->muted; o->muted = data->muted;
@ -652,6 +661,9 @@ static void source_output_free(pa_object* mo) {
if (o->proplist) if (o->proplist)
pa_proplist_free(o->proplist); pa_proplist_free(o->proplist);
if (o->preferred_source)
pa_xfree(o->preferred_source);
pa_xfree(o->driver); pa_xfree(o->driver);
pa_xfree(o); pa_xfree(o);
} }
@ -1545,7 +1557,12 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, bool save
o->moving(o, dest); o->moving(o, dest);
o->source = dest; o->source = dest;
o->save_source = save; /* save == true, means user is calling the move_to() and want to
save the preferred_source */
if (save) {
pa_xfree(o->preferred_source);
o->preferred_source = pa_xstrdup(dest->name);
}
pa_idxset_put(o->source->outputs, pa_source_output_ref(o), NULL); pa_idxset_put(o->source->outputs, pa_source_output_ref(o), NULL);
pa_cvolume_remap(&o->volume_factor_source, &o->channel_map, &o->source->channel_map); pa_cvolume_remap(&o->volume_factor_source, &o->channel_map, &o->source->channel_map);

View file

@ -106,11 +106,15 @@ struct pa_source_output {
bool muted:1; bool muted:1;
/* if true then the source we are connected to and/or the volume /* if true then the volume and the mute state of this source-output
* set is worth remembering, i.e. was explicitly chosen by the * are worth remembering, module-stream-restore looks for this. */
* user and not automatically. module-stream-restore looks for bool save_volume:1, save_muted:1;
* this.*/
bool save_source:1, save_volume:1, save_muted:1; /* if users move the source-output to a source, and the source is not
* default_source, the source->name will be saved in preferred_source. And
* later if source-output is moved to other sources for some reason, it
* still can be restored to the preferred_source at an appropriate time */
char *preferred_source;
pa_resample_method_t requested_resample_method, actual_resample_method; pa_resample_method_t requested_resample_method, actual_resample_method;
@ -277,7 +281,8 @@ typedef struct pa_source_output_new_data {
bool volume_writable:1; bool volume_writable:1;
bool save_source:1, save_volume:1, save_muted:1; bool save_volume:1, save_muted:1;
char *preferred_source;
} pa_source_output_new_data; } pa_source_output_new_data;
pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data); pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);