mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
alsa: Reread and upate jack status when a card is unsuspended
This is needed so we don't keep stale jack availability information while the card is suspended. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=93259 Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
This commit is contained in:
parent
fb52a6a6e6
commit
408b9f8cc0
3 changed files with 32 additions and 18 deletions
|
|
@ -369,10 +369,7 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
|
|
||||||
/* Quick and dirty fix for
|
/* Changing the jack state may cause a port change, and a port change will
|
||||||
* https://bugs.freedesktop.org/show_bug.cgi?id=93259
|
|
||||||
*
|
|
||||||
* Changing the jack state may cause a port change, and a port change will
|
|
||||||
* make the sink or source change the mixer settings. If there are multiple
|
* make the sink or source change the mixer settings. If there are multiple
|
||||||
* users having pulseaudio running, the mixer changes done by inactive
|
* users having pulseaudio running, the mixer changes done by inactive
|
||||||
* users may mess up the volume settings for the active users, because when
|
* users may mess up the volume settings for the active users, because when
|
||||||
|
|
@ -382,18 +379,8 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
|
||||||
* with alsamixer. Even single-user systems suffer from this, because gdm
|
* with alsamixer. Even single-user systems suffer from this, because gdm
|
||||||
* runs its own pulseaudio instance.
|
* runs its own pulseaudio instance.
|
||||||
*
|
*
|
||||||
* Returning early here means that jack state events get ignored while the
|
* We rerun this function when being unsuspended to catch up on jack state
|
||||||
* user is inactive. When the user becomes active again, the routing may
|
* changes */
|
||||||
* not any more match the real jack state. While this is bad, this should
|
|
||||||
* nevertheless be better than messing up the volume every time headphones
|
|
||||||
* are plugged in or out.
|
|
||||||
*
|
|
||||||
* It might be better to unload the card altogether when the user becomes
|
|
||||||
* inactive and udev removes the permission to the card. That requires at
|
|
||||||
* least improving the default sink handling so that if the unloaded card
|
|
||||||
* contained the default sink, the default sink should be restored to what
|
|
||||||
* it was earlier, when the user becomes active and the card becomes
|
|
||||||
* accessible. */
|
|
||||||
if (u->card->suspend_cause & PA_SUSPEND_SESSION)
|
if (u->card->suspend_cause & PA_SUSPEND_SESSION)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -604,6 +591,20 @@ static void set_card_name(pa_card_new_data *data, pa_modargs *ma, const char *de
|
||||||
pa_xfree(t);
|
pa_xfree(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pa_hook_result_t card_suspend_changed(pa_core *c, pa_card *card, struct userdata *u) {
|
||||||
|
void *state;
|
||||||
|
pa_alsa_jack *jack;
|
||||||
|
|
||||||
|
if (card->suspend_cause == 0) {
|
||||||
|
/* We were unsuspended, update jack state in case it changed while we were suspended */
|
||||||
|
PA_HASHMAP_FOREACH(jack, u->jacks, state) {
|
||||||
|
report_jack_state(jack->melem, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PA_HOOK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static pa_hook_result_t sink_input_put_hook_callback(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
|
static pa_hook_result_t sink_input_put_hook_callback(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
|
||||||
const char *role;
|
const char *role;
|
||||||
pa_sink *sink = sink_input->sink;
|
pa_sink *sink = sink_input->sink;
|
||||||
|
|
@ -810,6 +811,9 @@ int pa__init(pa_module *m) {
|
||||||
u->card->userdata = u;
|
u->card->userdata = u;
|
||||||
u->card->set_profile = card_set_profile;
|
u->card->set_profile = card_set_profile;
|
||||||
|
|
||||||
|
pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_CARD_SUSPEND_CHANGED], PA_HOOK_NORMAL,
|
||||||
|
(pa_hook_cb_t) card_suspend_changed, u);
|
||||||
|
|
||||||
init_jacks(u);
|
init_jacks(u);
|
||||||
init_profile(u);
|
init_profile(u);
|
||||||
init_eld_ctls(u);
|
init_eld_ctls(u);
|
||||||
|
|
|
||||||
|
|
@ -358,16 +358,25 @@ void pa_card_set_preferred_port(pa_card *c, pa_direction_t direction, pa_device_
|
||||||
int pa_card_suspend(pa_card *c, bool suspend, pa_suspend_cause_t cause) {
|
int pa_card_suspend(pa_card *c, bool suspend, pa_suspend_cause_t cause) {
|
||||||
pa_sink *sink;
|
pa_sink *sink;
|
||||||
pa_source *source;
|
pa_source *source;
|
||||||
|
pa_suspend_cause_t suspend_cause;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
pa_assert(c);
|
pa_assert(c);
|
||||||
pa_assert(cause != 0);
|
pa_assert(cause != 0);
|
||||||
|
|
||||||
|
suspend_cause = c->suspend_cause;
|
||||||
|
|
||||||
if (suspend)
|
if (suspend)
|
||||||
c->suspend_cause |= cause;
|
suspend_cause |= cause;
|
||||||
else
|
else
|
||||||
c->suspend_cause &= ~cause;
|
suspend_cause &= ~cause;
|
||||||
|
|
||||||
|
if (c->suspend_cause != suspend_cause) {
|
||||||
|
pa_log_debug("Card suspend causes/state changed");
|
||||||
|
c->suspend_cause = suspend_cause;
|
||||||
|
pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CARD_SUSPEND_CHANGED], c);
|
||||||
|
}
|
||||||
|
|
||||||
PA_IDXSET_FOREACH(sink, c->sinks, idx) {
|
PA_IDXSET_FOREACH(sink, c->sinks, idx) {
|
||||||
int r;
|
int r;
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,7 @@ typedef enum pa_core_hook {
|
||||||
PA_CORE_HOOK_CARD_PROFILE_CHANGED,
|
PA_CORE_HOOK_CARD_PROFILE_CHANGED,
|
||||||
PA_CORE_HOOK_CARD_PROFILE_ADDED,
|
PA_CORE_HOOK_CARD_PROFILE_ADDED,
|
||||||
PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED,
|
PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED,
|
||||||
|
PA_CORE_HOOK_CARD_SUSPEND_CHANGED,
|
||||||
PA_CORE_HOOK_PORT_AVAILABLE_CHANGED,
|
PA_CORE_HOOK_PORT_AVAILABLE_CHANGED,
|
||||||
PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED,
|
PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED,
|
||||||
PA_CORE_HOOK_DEFAULT_SINK_CHANGED,
|
PA_CORE_HOOK_DEFAULT_SINK_CHANGED,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue