[pulseaudio-discuss] [PATCH 1/4] change bool save_sink to char *preferred_sink

Hui Wang hui.wang at canonical.com
Mon Nov 5 01:47:13 UTC 2018


And don't move the stream in the module-stream-restore anymore,
And the preferred_sink is only set when user is calling the
move_to() and the module-stream-restore maintains the saving and
deleting of preferred_sink.

If the target of move_to() is default_sink, preferred_sink will be
cleared and the entry->device will be cleared too from database.

Signed-off-by: Hui Wang <hui.wang at canonical.com>
---
 src/modules/module-device-manager.c    |  2 +-
 src/modules/module-intended-roles.c    |  2 +-
 src/modules/module-stream-restore.c    | 47 +++++++++++++++++---------
 src/modules/module-switch-on-connect.c |  2 +-
 src/pulsecore/sink-input.c             | 25 +++++++++++---
 src/pulsecore/sink-input.h             |  7 ++--
 6 files changed, 59 insertions(+), 26 deletions(-)

diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c
index 15fdaaaa2..36e71584e 100644
--- a/src/modules/module-device-manager.c
+++ b/src/modules/module-device-manager.c
@@ -657,7 +657,7 @@ static void route_sink_input(struct userdata *u, pa_sink_input *si) {
     pa_assert(u->do_routing);
 
     /* Don't override user or application routing requests. */
-    if (si->save_sink || si->sink_requested_by_application)
+    if (si->preferred_sink != NULL || si->sink_requested_by_application)
         return;
 
     /* Skip this if it is already in the process of being moved anyway */
diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c
index adee51c20..98e4c241f 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 (si->preferred_sink != NULL)
             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 228e9e447..276957c25 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -1311,19 +1311,29 @@ 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 || !created_new_entry) {
             pa_xfree(entry->device);
-            entry->device = pa_xstrdup(sink_input->sink->name);
-            entry->device_valid = true;
 
-            device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
-            if (sink_input->sink->card) {
+	    if (sink_input->preferred_sink != NULL) {
+		entry->device = pa_xstrdup(sink_input->preferred_sink);
+		entry->device_valid = true;
+	    } else {
+		entry->device = NULL;
+		entry->device_valid = false;
+	    }
+
+            device_updated = !created_new_entry && (!old->device_valid || !entry->device_valid || !pa_streq(entry->device, old->device));
+
+	    if (entry->device_valid == false) {
+                pa_xfree(entry->card);
+                entry->card = NULL;
+                entry->card_valid = false;
+	    } else if (sink_input->sink->card) {
                 pa_xfree(entry->card);
                 entry->card = pa_xstrdup(sink_input->sink->card->name);
                 entry->card_valid = true;
             }
         }
-
     } else {
         pa_source_output *source_output;
 
@@ -1641,7 +1651,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 (si->preferred_sink != NULL)
             continue;
 
         /* Skip this if it is already in the process of being moved
@@ -1665,7 +1675,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
 
         if ((e = entry_read(u, name))) {
             if (e->device_valid && pa_streq(e->device, sink->name))
-                pa_sink_input_move_to(si, sink, true);
+		si->preferred_sink = pa_xstrdup(sink->name);
 
             entry_free(e);
         }
@@ -1764,8 +1774,10 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
 
                 if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SINK)) &&
                     d != sink &&
-                    PA_SINK_IS_LINKED(d->state))
-                    pa_sink_input_move_to(si, d, true);
+                    PA_SINK_IS_LINKED(d->state)) {
+		    pa_xfree(si->preferred_sink);
+		    si->preferred_sink = pa_xstrdup(d->name);
+		}
             }
 
             entry_free(e);
@@ -1942,12 +1954,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
                        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)
@@ -1956,7 +1969,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);
             }
         }
     }
@@ -2176,9 +2190,10 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 
                 entry->muted = muted;
                 entry->muted_valid = true;
-
-                entry->device = pa_xstrdup(device);
-                entry->device_valid = device && !!entry->device[0];
+		if (device && !pa_streq(device, m->core->default_sink->name) && !pa_streq(device, m->core->default_source->name)) {
+		    entry->device = pa_xstrdup(device);
+		    entry->device_valid = device && !!entry->device[0];
+		}
 
                 if (entry->device_valid && !pa_namereg_is_valid_name(entry->device)) {
                     entry_free(entry);
diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c
index ebdd6aad0..faa0f289f 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -112,7 +112,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 (i->preferred_sink != NULL || !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 312ec4a97..1031051a7 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -190,7 +190,8 @@ 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)
+            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 +200,8 @@ 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)
+		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 +228,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, false, data->sink_requested_by_application);
     }
 
     return true;
@@ -519,7 +521,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;
@@ -777,6 +779,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 +1919,17 @@ 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_sinke if the sink is not default_sink */
+    if (save) {
+	pa_xfree(i->preferred_sink);
+	if (dest == dest->core->default_sink)
+	    i->preferred_sink = NULL;
+	else
+	    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 9e90291ca..537cec9a1 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -123,7 +123,8 @@ struct pa_sink_input {
      * set is worth remembering, i.e. was explicitly chosen by the
      * user and not automatically. module-stream-restore looks for
      * this.*/
-    bool save_sink:1, save_volume:1, save_muted:1;
+    char *preferred_sink;
+    bool save_volume:1, save_muted:1;
 
     pa_resample_method_t requested_resample_method, actual_resample_method;
 
@@ -300,6 +301,8 @@ typedef struct pa_sink_input_new_data {
     pa_idxset *req_formats;
     pa_idxset *nego_formats;
 
+    char *preferred_sink;
+
     pa_cvolume volume;
     bool muted:1;
     pa_hashmap *volume_factor_items, *volume_factor_sink_items;
@@ -314,7 +317,7 @@ 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;
 } 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



More information about the pulseaudio-discuss mailing list