[v3,1/8] sink-input: change bool save_sink to char *preferred_sink

Submitted by Hui Wang on Aug. 18, 2019, 5:32 a.m.

Details

Message ID 20190818053241.22161-2-hui.wang@canonical.com
State New
Headers show
Series "Change the bool sink_save to char *preferred_sink" ( rev: 2 ) in PulseAudio

Not browsing as part of any series.

Commit Message

Hui Wang Aug. 18, 2019, 5:32 a.m.
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>
---
 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(-)

Patch hide | download patch | download mbox

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);