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@xxxxxxxxxxxxx> --- src/modules/module-device-manager.c | 8 ++++---- src/modules/module-intended-roles.c | 2 +- src/modules/module-stream-restore.c | 15 +++++++++------ src/modules/module-switch-on-connect.c | 2 +- src/pulsecore/sink-input.c | 24 +++++++++++++++++++----- src/pulsecore/sink-input.h | 17 ++++++++++++----- 6 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c index 15fdaaaa2..cba3a4ebc 100644 --- a/src/modules/module-device-manager.c +++ b/src/modules/module-device-manager.c @@ -656,14 +656,14 @@ static void route_sink_input(struct userdata *u, pa_sink_input *si) { pa_assert(u); 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 */ if (!si->sink) 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"); 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 adee51c20..5596faf1f 100644 --- a/src/modules/module-intended-roles.c +++ b/src/modules/module-intended-roles.c @@ -175,7 +175,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct if (si->sink == sink) continue; - if (si->save_sink) + if (pa_safe_streq(si->sink->name, si->preferred_sink)) continue; /* Skip this if it is already in the process of being moved diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index cbef4782d..3c50fda1e 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -1311,9 +1311,9 @@ 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 (sink_input->save_sink) { + if (sink_input->preferred_sink != NULL) { pa_xfree(entry->device); - entry->device = pa_xstrdup(sink_input->sink->name); + entry->device = pa_xstrdup(sink_input->preferred_sink); entry->device_valid = true; device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device)); @@ -1650,7 +1650,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct if (si->sink == sink) continue; - if (si->save_sink) + if (pa_safe_streq(si->sink->name, si->preferred_sink)) continue; /* Skip this if it is already in the process of being moved @@ -1951,12 +1951,13 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) { if (u->restore_device) { 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); /* 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. */ - 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 but the rules governing its routing have, so we fire this event such that other routing modules (e.g. module-device-manager) @@ -1966,6 +1967,8 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) { } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SINK))) { pa_log_info("Restoring device for stream %s.", name); pa_sink_input_move_to(si, s, true); + pa_xfree(si->preferred_sink); + si->preferred_sink = pa_xstrdup(s->name); } } } diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c index 9077eaec4..f0cb29a7c 100644 --- a/src/modules/module-switch-on-connect.c +++ b/src/modules/module-switch-on-connect.c @@ -115,7 +115,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) { - 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; if (pa_sink_input_move_to(i, sink, false) < 0) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index d3ead2cb5..18766019e 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -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) { /* We're not working with the extended API */ 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; } else { /* 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)) { /* Sink supports at least one of the requested formats */ 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; if (data->nego_formats) 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) { /* 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; @@ -518,7 +524,7 @@ int pa_sink_input_new( pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels); i->volume_writable = data->volume_writable; 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->muted = data->muted; @@ -776,6 +782,9 @@ static void sink_input_free(pa_object *o) { if (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); } @@ -1914,7 +1923,12 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, bool save) { i->moving(i, 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_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state) diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index f7f923744..16b6bf8eb 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -119,11 +119,16 @@ struct pa_sink_input { bool muted:1; - /* if true then the sink 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 + /* if true then the volume and the mute state of this sink-input + * are worth remembering, module-stream-restore looks for * 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; @@ -315,7 +320,9 @@ typedef struct pa_sink_input_new_data { 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_init(pa_sink_input_new_data *data); -- 2.17.1 _______________________________________________ pulseaudio-discuss mailing list pulseaudio-discuss@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss