mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue