[pulseaudio-commits] 2 commits - src/modules src/pulsecore

Arun Raghavan arun at kemper.freedesktop.org
Wed May 11 03:44:01 UTC 2016


 src/modules/alsa/module-alsa-card.c |   32 ++++++++++++++++++++++++++++++++
 src/pulsecore/card.c                |   14 ++++++++++++++
 src/pulsecore/card.h                |    2 ++
 src/pulsecore/core.h                |    1 +
 4 files changed, 49 insertions(+)

New commits:
commit 408b9f8cc048fac657553aec615d6946563c3cef
Author: Arun Raghavan <arun at arunraghavan.net>
Date:   Mon May 9 15:09:57 2016 +0530

    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 at arunraghavan.net>

diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index b1e3e63..e5cc4ae 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -369,10 +369,7 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
 
     pa_assert(u);
 
-    /* Quick and dirty fix for
-     * https://bugs.freedesktop.org/show_bug.cgi?id=93259
-     *
-     * Changing the jack state may cause a port change, and a port change will
+    /* 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
      * users having pulseaudio running, the mixer changes done by inactive
      * 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
      * runs its own pulseaudio instance.
      *
-     * Returning early here means that jack state events get ignored while the
-     * user is inactive. When the user becomes active again, the routing may
-     * 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. */
+     * We rerun this function when being unsuspended to catch up on jack state
+     * changes */
     if (u->card->suspend_cause & PA_SUSPEND_SESSION)
         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);
 }
 
+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) {
     const char *role;
     pa_sink *sink = sink_input->sink;
@@ -810,6 +811,9 @@ int pa__init(pa_module *m) {
     u->card->userdata = u;
     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_profile(u);
     init_eld_ctls(u);
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index 72ecd4e..410746b 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -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) {
     pa_sink *sink;
     pa_source *source;
+    pa_suspend_cause_t suspend_cause;
     uint32_t idx;
     int ret = 0;
 
     pa_assert(c);
     pa_assert(cause != 0);
 
+    suspend_cause = c->suspend_cause;
+
     if (suspend)
-        c->suspend_cause |= cause;
+        suspend_cause |= cause;
     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) {
         int r;
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 69ab4d0..00d7f2f 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -124,6 +124,7 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_CARD_PROFILE_CHANGED,
     PA_CORE_HOOK_CARD_PROFILE_ADDED,
     PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED,
+    PA_CORE_HOOK_CARD_SUSPEND_CHANGED,
     PA_CORE_HOOK_PORT_AVAILABLE_CHANGED,
     PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED,
     PA_CORE_HOOK_DEFAULT_SINK_CHANGED,

commit fb52a6a6e6c94c8d7cb43b924f63e67d1c160d60
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Wed Apr 20 15:35:13 2016 +0300

    alsa: ignore jack events when the user is inactive
    
    See the big comment in the code for more details.
    
    BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=93259

diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 286cfc9..b1e3e63 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -369,6 +369,34 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
 
     pa_assert(u);
 
+    /* Quick and dirty fix for
+     * 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
+     * users having pulseaudio running, the mixer changes done by inactive
+     * users may mess up the volume settings for the active users, because when
+     * the inactive users change the mixer settings, those changes are picked
+     * up by the active user's pulseaudio instance and the changes are
+     * interpreted as if the active user changed the settings manually e.g.
+     * with alsamixer. Even single-user systems suffer from this, because gdm
+     * runs its own pulseaudio instance.
+     *
+     * Returning early here means that jack state events get ignored while the
+     * user is inactive. When the user becomes active again, the routing may
+     * 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)
+        return 0;
+
     if (mask == SND_CTL_EVENT_MASK_REMOVE)
         return 0;
 
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index 0eaccff..72ecd4e 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -364,6 +364,11 @@ int pa_card_suspend(pa_card *c, bool suspend, pa_suspend_cause_t cause) {
     pa_assert(c);
     pa_assert(cause != 0);
 
+    if (suspend)
+        c->suspend_cause |= cause;
+    else
+        c->suspend_cause &= ~cause;
+
     PA_IDXSET_FOREACH(sink, c->sinks, idx) {
         int r;
 
diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h
index 79966f3..d4970e3 100644
--- a/src/pulsecore/card.h
+++ b/src/pulsecore/card.h
@@ -84,6 +84,8 @@ struct pa_card {
 
     bool save_profile:1;
 
+    pa_suspend_cause_t suspend_cause;
+
     void *userdata;
 
     int (*set_profile)(pa_card *c, pa_card_profile *profile);



More information about the pulseaudio-commits mailing list