From 5eec504d68345934a01f70cd1d2186e4d8b0db31 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Fri, 6 Dec 2019 21:51:10 +0800 Subject: [PATCH] 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 --- src/modules/module-device-manager.c | 8 ++++---- src/modules/module-intended-roles.c | 6 +++--- src/modules/module-stream-restore.c | 23 ++++++++++++---------- src/modules/module-switch-on-connect.c | 2 +- src/pulsecore/source-output.c | 27 +++++++++++++++++++++----- src/pulsecore/source-output.h | 17 ++++++++++------ 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c index cba3a4ebc..5a9995c18 100644 --- a/src/modules/module-device-manager.c +++ b/src/modules/module-device-manager.c @@ -728,10 +728,6 @@ static void route_source_output(struct userdata *u, pa_source_output *so) { pa_assert(u); 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) return; @@ -739,6 +735,10 @@ static void route_source_output(struct userdata *u, pa_source_output *so) { if (!so->source) 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"); if (auto_filtered_prop) auto_filtered = (pa_parse_boolean(auto_filtered_prop) == 1); diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c index 4ddc03431..434ad3097 100644 --- a/src/modules/module-intended-roles.c +++ b/src/modules/module-intended-roles.c @@ -222,9 +222,6 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, if (so->source == source) continue; - if (so->save_source) - continue; - if (so->direct_on_input) continue; @@ -233,6 +230,9 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, if (!so->source) 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 same time, in which case we want to make sure we don't interfere with that */ diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 911236e24..b0cce88c3 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -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); } - if (source_output->save_source) { + if (source_output->preferred_source != NULL) { + pa_source *s; pa_xfree(entry->device); - entry->device = pa_xstrdup(source_output->source->name); + entry->device = pa_xstrdup(source_output->preferred_source); entry->device_valid = true; 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); - entry->card = pa_xstrdup(source_output->source->card->name); + entry->card = pa_xstrdup(s->card->name); 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) continue; - if (so->save_source) - continue; - if (so->direct_on_input) continue; @@ -1663,6 +1662,9 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, if (!so->source) continue; + if (pa_safe_streq(so->source->name, so->preferred_source)) + continue; + /* Skip this source output if it is connecting a filter source to * the master */ 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 (!e->device_valid) { - if (so->save_source) { + if (so->preferred_source != NULL) { pa_log_info("Ensuring device is not saved for stream %s.", name); /* 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. */ - 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 but the rules governing its routing have, so we fire this event such that other routing modules (e.g. module-device-manager) diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c index 74cd977b2..e56774b00 100644 --- a/src/modules/module-switch-on-connect.c +++ b/src/modules/module-switch-on-connect.c @@ -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) { - 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; if (pa_source_output_move_to(o, source, false) < 0) diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index dfefe8f8c..3c539515f 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -134,7 +134,10 @@ bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_so if (!data->req_formats) { /* We're not working with the extended API */ 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; } else { /* 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)) { /* Source supports at least one of the requested formats */ 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; if (data->nego_formats) 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) { /* 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); } @@ -189,6 +195,9 @@ void pa_source_output_new_data_done(pa_source_output_new_data *data) { if (data->format) pa_format_info_free(data->format); + if (data->preferred_source) + pa_xfree(data->preferred_source); + pa_proplist_free(data->proplist); } @@ -460,7 +469,7 @@ int pa_source_output_new( pa_cvolume_reset(&o->real_ratio, o->sample_spec.channels); o->volume_writable = data->volume_writable; 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->muted = data->muted; @@ -652,6 +661,9 @@ static void source_output_free(pa_object* mo) { if (o->proplist) pa_proplist_free(o->proplist); + if (o->preferred_source) + pa_xfree(o->preferred_source); + pa_xfree(o->driver); 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->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_cvolume_remap(&o->volume_factor_source, &o->channel_map, &o->source->channel_map); diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 16853c064..d46b37446 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -106,11 +106,15 @@ struct pa_source_output { bool muted:1; - /* if true then the source we are connected to and/or the volume - * set is worth remembering, i.e. was explicitly chosen by the - * user and not automatically. module-stream-restore looks for - * this.*/ - bool save_source:1, save_volume:1, save_muted:1; + /* if true then the volume and the mute state of this source-output + * are worth remembering, module-stream-restore looks for this. */ + bool 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; @@ -277,7 +281,8 @@ typedef struct pa_source_output_new_data { 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_init(pa_source_output_new_data *data);