mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
switch-on-connect: Do not overwrite user configured default sink/source
Currently module-switch-on-connect overwrites the default sink or source that the user has configured. This means that when the overwritten default sink or source becomes unavailable, the new default will be chosen based on priority and the default will not return to the originally configured value. This patch solves the issue by introducing new core variables for the sink or source chosen by the policy module which have higher priority than the user configured defaults. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/784>
This commit is contained in:
parent
39b6a4c123
commit
3aaeb5113d
3 changed files with 131 additions and 11 deletions
|
|
@ -40,6 +40,7 @@
|
|||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/strbuf.h>
|
||||
#include <pulsecore/namereg.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
|
|
@ -149,6 +150,10 @@ pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t
|
|||
|
||||
c->default_source = NULL;
|
||||
c->default_sink = NULL;
|
||||
c->configured_default_source = NULL;
|
||||
c->configured_default_sink = NULL;
|
||||
c->policy_default_source = NULL;
|
||||
c->policy_default_sink = NULL;
|
||||
|
||||
c->default_sample_spec.format = PA_SAMPLE_S16NE;
|
||||
c->default_sample_spec.rate = 44100;
|
||||
|
|
@ -261,6 +266,8 @@ static void core_free(pa_object *o) {
|
|||
pa_assert(!c->default_sink);
|
||||
pa_xfree(c->configured_default_source);
|
||||
pa_xfree(c->configured_default_sink);
|
||||
pa_xfree(c->policy_default_source);
|
||||
pa_xfree(c->policy_default_sink);
|
||||
|
||||
pa_silence_cache_done(&c->silence_cache);
|
||||
pa_mempool_unref(c->mempool);
|
||||
|
|
@ -271,6 +278,36 @@ static void core_free(pa_object *o) {
|
|||
pa_xfree(c);
|
||||
}
|
||||
|
||||
static bool is_sink_available(pa_core *core, const char *sink_name) {
|
||||
pa_sink *sink;
|
||||
|
||||
if (!(sink = pa_namereg_get(core, sink_name, PA_NAMEREG_SINK)))
|
||||
return false;
|
||||
|
||||
if (!PA_SINK_IS_LINKED(sink->state))
|
||||
return false;
|
||||
|
||||
if (sink->active_port && sink->active_port->available == PA_AVAILABLE_NO)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_source_available(pa_core *core, const char *source_name) {
|
||||
pa_source *source;
|
||||
|
||||
if (!(source = pa_namereg_get(core, source_name, PA_NAMEREG_SOURCE)))
|
||||
return false;
|
||||
|
||||
if (!PA_SOURCE_IS_LINKED(source->state))
|
||||
return false;
|
||||
|
||||
if (source->active_port && source->active_port->available == PA_AVAILABLE_NO)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void pa_core_set_configured_default_sink(pa_core *core, const char *sink) {
|
||||
char *old_sink;
|
||||
|
||||
|
|
@ -278,13 +315,21 @@ void pa_core_set_configured_default_sink(pa_core *core, const char *sink) {
|
|||
|
||||
old_sink = pa_xstrdup(core->configured_default_sink);
|
||||
|
||||
if (pa_safe_streq(sink, old_sink))
|
||||
/* The default sink was overwritten by the policy default sink, but the user is
|
||||
* now setting a new default manually. Clear the policy default sink. */
|
||||
if (core->policy_default_sink && is_sink_available(core, core->policy_default_sink)) {
|
||||
pa_xfree(core->policy_default_sink);
|
||||
core->policy_default_sink = NULL;
|
||||
|
||||
} else if (pa_safe_streq(sink, old_sink))
|
||||
goto finish;
|
||||
|
||||
pa_xfree(core->configured_default_sink);
|
||||
core->configured_default_sink = pa_xstrdup(sink);
|
||||
pa_log_info("configured_default_sink: %s -> %s",
|
||||
old_sink ? old_sink : "(unset)", sink ? sink : "(unset)");
|
||||
if (!pa_safe_streq(sink, old_sink)) {
|
||||
pa_log_info("configured_default_sink: %s -> %s",
|
||||
old_sink ? old_sink : "(unset)", sink ? sink : "(unset)");
|
||||
}
|
||||
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
|
||||
|
||||
pa_core_update_default_sink(core);
|
||||
|
|
@ -300,12 +345,64 @@ void pa_core_set_configured_default_source(pa_core *core, const char *source) {
|
|||
|
||||
old_source = pa_xstrdup(core->configured_default_source);
|
||||
|
||||
if (pa_safe_streq(source, old_source))
|
||||
/* The default source was overwritten by the policy default source, but the user is
|
||||
* now setting a new default manually. Clear the policy default source. */
|
||||
if (core->policy_default_source && is_source_available(core, core->policy_default_source)) {
|
||||
pa_xfree(core->policy_default_source);
|
||||
core->policy_default_source = NULL;
|
||||
|
||||
} else if (pa_safe_streq(source, old_source))
|
||||
goto finish;
|
||||
|
||||
pa_xfree(core->configured_default_source);
|
||||
core->configured_default_source = pa_xstrdup(source);
|
||||
pa_log_info("configured_default_source: %s -> %s",
|
||||
if (!pa_safe_streq(source, old_source)) {
|
||||
pa_log_info("configured_default_source: %s -> %s",
|
||||
old_source ? old_source : "(unset)", source ? source : "(unset)");
|
||||
}
|
||||
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
|
||||
|
||||
pa_core_update_default_source(core);
|
||||
|
||||
finish:
|
||||
pa_xfree(old_source);
|
||||
}
|
||||
|
||||
void pa_core_set_policy_default_sink(pa_core *core, const char *sink) {
|
||||
char *old_sink;
|
||||
|
||||
pa_assert(core);
|
||||
|
||||
old_sink = pa_xstrdup(core->policy_default_sink);
|
||||
|
||||
if (pa_safe_streq(sink, old_sink))
|
||||
goto finish;
|
||||
|
||||
pa_xfree(core->policy_default_sink);
|
||||
core->policy_default_sink = pa_xstrdup(sink);
|
||||
pa_log_info("policy_default_sink: %s -> %s",
|
||||
old_sink ? old_sink : "(unset)", sink ? sink : "(unset)");
|
||||
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
|
||||
|
||||
pa_core_update_default_sink(core);
|
||||
|
||||
finish:
|
||||
pa_xfree(old_sink);
|
||||
}
|
||||
|
||||
void pa_core_set_policy_default_source(pa_core *core, const char *source) {
|
||||
char *old_source;
|
||||
|
||||
pa_assert(core);
|
||||
|
||||
old_source = pa_xstrdup(core->policy_default_source);
|
||||
|
||||
if (pa_safe_streq(source, old_source))
|
||||
goto finish;
|
||||
|
||||
pa_xfree(core->policy_default_source);
|
||||
core->policy_default_source = pa_xstrdup(source);
|
||||
pa_log_info("policy_default_source: %s -> %s",
|
||||
old_source ? old_source : "(unset)", source ? source : "(unset)");
|
||||
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
|
||||
|
||||
|
|
@ -331,7 +428,14 @@ static int compare_sinks(pa_sink *a, pa_sink *b) {
|
|||
&& (!a->active_port || a->active_port->available != PA_AVAILABLE_NO))
|
||||
return 1;
|
||||
|
||||
/* The configured default sink is preferred over any other sink. */
|
||||
/* The policy default sink is preferred over any other sink. */
|
||||
if (pa_safe_streq(b->name, core->policy_default_sink))
|
||||
return -1;
|
||||
if (pa_safe_streq(a->name, core->policy_default_sink))
|
||||
return 1;
|
||||
|
||||
/* The configured default sink is preferred over any other sink
|
||||
* except the policy default sink. */
|
||||
if (pa_safe_streq(b->name, core->configured_default_sink))
|
||||
return -1;
|
||||
if (pa_safe_streq(a->name, core->configured_default_sink))
|
||||
|
|
@ -412,7 +516,14 @@ static int compare_sources(pa_source *a, pa_source *b) {
|
|||
&& (!a->active_port || a->active_port->available != PA_AVAILABLE_NO))
|
||||
return 1;
|
||||
|
||||
/* The configured default source is preferred over any other source. */
|
||||
/* The policy default source is preferred over any other source. */
|
||||
if (pa_safe_streq(b->name, core->policy_default_source))
|
||||
return -1;
|
||||
if (pa_safe_streq(a->name, core->policy_default_source))
|
||||
return 1;
|
||||
|
||||
/* The configured default source is preferred over any other source
|
||||
* except the policy default source. */
|
||||
if (pa_safe_streq(b->name, core->configured_default_source))
|
||||
return -1;
|
||||
if (pa_safe_streq(a->name, core->configured_default_source))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue