mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-08 13:29:59 -05:00
card: handle sticky profile flag
New card database entry version 5 for card profile is sticky flag. New messaging API handlers set-profile-sticky and get-profile-sticky. When card profile is sticky, always restore it even if it is unavailable, and prevent switching from it when ports become unavailable. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/568>
This commit is contained in:
parent
79cb1369fc
commit
e576bd924f
5 changed files with 133 additions and 5 deletions
|
|
@ -67,7 +67,7 @@ struct userdata {
|
|||
bool restore_bluetooth_profile;
|
||||
};
|
||||
|
||||
#define ENTRY_VERSION 4
|
||||
#define ENTRY_VERSION 5
|
||||
|
||||
struct port_info {
|
||||
char *name;
|
||||
|
|
@ -80,6 +80,7 @@ struct entry {
|
|||
pa_hashmap *ports; /* Port name -> struct port_info */
|
||||
char *preferred_input_port;
|
||||
char *preferred_output_port;
|
||||
bool profile_is_sticky; /* since version 5; must be restored together with profile name */
|
||||
};
|
||||
|
||||
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
|
||||
|
|
@ -153,7 +154,8 @@ static struct entry *entry_from_card(pa_card *card) {
|
|||
pa_assert(card);
|
||||
|
||||
entry = entry_new();
|
||||
if (card->save_profile)
|
||||
entry->profile_is_sticky = card->profile_is_sticky;
|
||||
if (card->save_profile || entry->profile_is_sticky)
|
||||
entry->profile = pa_xstrdup(card->active_profile->name);
|
||||
|
||||
PA_HASHMAP_FOREACH(port, card->ports, state) {
|
||||
|
|
@ -189,6 +191,9 @@ static bool entrys_equal(struct entry *a, struct entry *b) {
|
|||
if (!pa_safe_streq(a->preferred_output_port, b->preferred_output_port))
|
||||
return false;
|
||||
|
||||
if (a->profile_is_sticky != b->profile_is_sticky)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -217,6 +222,8 @@ static bool entry_write(struct userdata *u, const char *name, const struct entry
|
|||
pa_tagstruct_puts(t, e->preferred_input_port);
|
||||
pa_tagstruct_puts(t, e->preferred_output_port);
|
||||
|
||||
pa_tagstruct_put_boolean(t, e->profile_is_sticky);
|
||||
|
||||
key.data = (char *) name;
|
||||
key.size = strlen(name);
|
||||
|
||||
|
|
@ -342,6 +349,14 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
|
|||
e->preferred_output_port = pa_xstrdup(preferred_output_port);
|
||||
}
|
||||
|
||||
if (version >= 5) {
|
||||
bool profile_is_sticky;
|
||||
if (pa_tagstruct_get_boolean(t, &profile_is_sticky) < 0)
|
||||
goto fail;
|
||||
|
||||
e->profile_is_sticky = profile_is_sticky;
|
||||
}
|
||||
|
||||
if (!pa_tagstruct_eof(t))
|
||||
goto fail;
|
||||
|
||||
|
|
@ -437,11 +452,12 @@ static pa_hook_result_t card_profile_changed_callback(pa_core *c, pa_card *card,
|
|||
|
||||
pa_assert(card);
|
||||
|
||||
if (!card->save_profile)
|
||||
if (!card->save_profile && !card->profile_is_sticky)
|
||||
return PA_HOOK_OK;
|
||||
|
||||
if ((entry = entry_read(u, card->name))) {
|
||||
pa_xfree(entry->profile);
|
||||
entry->profile_is_sticky = card->profile_is_sticky;
|
||||
entry->profile = pa_xstrdup(card->active_profile->name);
|
||||
pa_log_info("Storing card profile for card %s.", card->name);
|
||||
} else {
|
||||
|
|
@ -565,12 +581,18 @@ static pa_hook_result_t card_choose_initial_profile_callback(pa_core *core, pa_c
|
|||
goto finish;
|
||||
}
|
||||
|
||||
card->profile_is_sticky = e->profile_is_sticky;
|
||||
pa_log_info("Profile '%s' was previously %s for card %s.",
|
||||
e->profile,
|
||||
card->profile_is_sticky ? "sticky" : "automatically selected",
|
||||
card->name);
|
||||
|
||||
if (e->profile[0]) {
|
||||
pa_card_profile *profile;
|
||||
|
||||
profile = pa_hashmap_get(card->profiles, e->profile);
|
||||
if (profile) {
|
||||
if (profile->available != PA_AVAILABLE_NO) {
|
||||
if (profile->available != PA_AVAILABLE_NO || card->profile_is_sticky) {
|
||||
pa_log_info("Restoring profile '%s' for card %s.", profile->name, card->name);
|
||||
pa_card_set_profile(card, profile, true);
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ static int try_to_switch_profile(pa_device_port *port) {
|
|||
void *state;
|
||||
unsigned best_prio = 0;
|
||||
|
||||
if (port->card->profile_is_sticky) {
|
||||
pa_log_info("Keeping sticky card profile '%s'", port->card->active_profile->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_log_debug("Finding best profile for port %s, preferred = %s",
|
||||
port->name, pa_strnull(port->preferred_profile));
|
||||
|
||||
|
|
@ -391,6 +396,11 @@ static pa_hook_result_t card_profile_available_hook_callback(pa_core *c, pa_card
|
|||
if (!pa_streq(profile->name, card->active_profile->name))
|
||||
return PA_HOOK_OK;
|
||||
|
||||
if (card->profile_is_sticky) {
|
||||
pa_log_info("Keeping sticky card profile '%s'", profile->name);
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
|
||||
pa_log_debug("Active profile %s on card %s became unavailable, switching to another profile", profile->name, card->name);
|
||||
pa_card_set_profile(card, find_best_profile(card), false);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue