alsa-mixer: Fix mapping_group_available() logic
authorTanu Kaskinen <tanuk@iki.fi>
Tue, 21 Jul 2020 07:26:43 +0000 (10:26 +0300)
committerTanu Kaskinen <tanuk@iki.fi>
Mon, 10 Aug 2020 17:54:21 +0000 (20:54 +0300)
There were three bugs:

1) j->state_plugged was set to PA_AVAILABLE_UNKNOWN too early. It must
be set only after we have found that the jack is shared by two ports.
The result of setting it too early was that no jack ever could have
the PA_AVAILABLE_YES status.

2) The inner jack loop iterated through p->jacks instead of p2->jacks,
so the code didn't compare jacks between two ports at all. As a result
all ports were put in the same availability group.

3) The inner jack loop checked j->state_plugged instead of
j2->state_plugged. The result was that the speaker port, which uses the
Headphone jack to toggle between unknown and unavailable, was put in the
same group with the headphone port.

src/modules/alsa/alsa-mixer.c

index 11551a7..758bef2 100644 (file)
@@ -4291,14 +4291,14 @@ static void mapping_group_available(pa_hashmap *paths)
            if (!j->has_control || j->state_plugged == PA_AVAILABLE_NO)
                continue;
            has_control = true;
-           j->state_plugged = PA_AVAILABLE_UNKNOWN;
            PA_HASHMAP_FOREACH(p2, paths, state2) {
                if (p2 == p)
                    break;
-               PA_LLIST_FOREACH(j2, p->jacks) {
-                   if (!j2->has_control || j->state_plugged == PA_AVAILABLE_NO)
+                PA_LLIST_FOREACH(j2, p2->jacks) {
+                    if (!j2->has_control || j2->state_plugged == PA_AVAILABLE_NO)
                        continue;
                    if (pa_streq(j->name, j2->name)) {
+                        j->state_plugged = PA_AVAILABLE_UNKNOWN;
                        j2->state_plugged = PA_AVAILABLE_UNKNOWN;
                        found = p2->available_group;
                        break;