[pulseaudio-discuss] [PATCH 2/3] device-port: Add messages to enable/disable jack detection
Georg Chini
georg at chini.tk
Mon Apr 9 18:38:25 UTC 2018
With this patch, messages can be sent to the cards to enable/disable
jack detection for the whole card or single ports, manually set a port
state and to retrieve the current state of jack detection and port
availability.
---
doc/messaging_api.txt | 22 ++++++++++++
src/modules/alsa/alsa-ucm.c | 2 +-
src/modules/alsa/module-alsa-card.c | 4 +--
src/modules/bluetooth/module-bluez5-device.c | 4 +--
src/pulsecore/card.c | 52 ++++++++++++++++++++++++----
src/pulsecore/device-port.c | 15 +++++++-
src/pulsecore/device-port.h | 3 +-
7 files changed, 89 insertions(+), 13 deletions(-)
diff --git a/doc/messaging_api.txt b/doc/messaging_api.txt
index 57a92f58..b3dfede0 100644
--- a/doc/messaging_api.txt
+++ b/doc/messaging_api.txt
@@ -70,3 +70,25 @@ Object path: /core
Message: list-handlers
Parameters: None
Return value: {{{Handler name} {Description}} ...}
+
+Object path: /cards/<card_name>
+Message: set-jack-detection
+Parameters: {port_name|all}{0|1}
+Return value: None
+
+Object path: /cards/<card_name>
+Message: get-jack-detection
+Parameters: {port_name|all}
+Return value: {{port_name}{0|1}} ...
+If "all" is specified, the first value returned is the setting
+for the card.
+
+Object path: /cards/<card_name>
+Message: set-port-state
+Parameters: {port_name|all}{availability}
+Return value: None
+
+Object path: /cards/<card_name>
+Message: get-port-state
+Parameters: {port_name|all}
+Return value: {{port_name}{availability}} ...
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index b42c0407..03073a53 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -1880,7 +1880,7 @@ static void ucm_port_update_available(struct ucm_port *port) {
}
}
- pa_device_port_set_available(port->core_port, available);
+ pa_device_port_set_available(port->core_port, available, false);
}
#else /* HAVE_ALSA_UCM */
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 385d61d2..104bb05d 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -421,10 +421,10 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
for (tp = tports; tp->port; tp++)
if (tp->avail != PA_AVAILABLE_NO)
- pa_device_port_set_available(tp->port, tp->avail);
+ pa_device_port_set_available(tp->port, tp->avail, false);
for (tp = tports; tp->port; tp++)
if (tp->avail == PA_AVAILABLE_NO)
- pa_device_port_set_available(tp->port, tp->avail);
+ pa_device_port_set_available(tp->port, tp->avail, false);
for (tp = tports; tp->port; tp++) {
pa_alsa_port_data *data;
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index 935ee2ce..560de934 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -2253,9 +2253,9 @@ static void handle_transport_state_change(struct userdata *u, struct pa_bluetoot
/* Update port availability */
pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
- pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_OUTPUT));
+ pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_OUTPUT), false);
pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
- pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_INPUT));
+ pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_INPUT), false);
/* Acquire or release transport as needed */
acquire = (t->state == PA_BLUETOOTH_TRANSPORT_STATE_PLAYING && u->profile == t->profile);
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index e91c034f..e056711c 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -127,6 +127,7 @@ static int card_message_handler(const char *object_path, const char *message, ch
pa_card *c;
char *port_name;
bool jack_detection;
+ uint64_t port_state;
void *state = NULL;
void *state2;
pa_device_port *port = NULL;
@@ -154,11 +155,29 @@ static int card_message_handler(const char *object_path, const char *message, ch
if (!port) {
c->jack_detection = jack_detection;
- PA_HASHMAP_FOREACH(port, c->ports, state2)
+ PA_HASHMAP_FOREACH(port, c->ports, state2) {
+ pa_available_t avail = PA_AVAILABLE_UNKNOWN;
+
+ /* If jack detection was enabled, set the port state
+ * to the hardware state. */
+ if (c->jack_detection)
+ avail = port->hw_available;
+
port->jack_detection = c->jack_detection;
+ pa_device_port_set_available(port, avail, true);
+ }
+
+ } else {
+ pa_available_t avail = PA_AVAILABLE_UNKNOWN;
+
+ /* If jack detection was enabled, set the port state
+ * to the hardware state. */
+ if (jack_detection)
+ avail = port->hw_available;
- } else
port->jack_detection = jack_detection;
+ pa_device_port_set_available(port, avail, true);
+ }
return PA_OK;
@@ -192,10 +211,29 @@ static int card_message_handler(const char *object_path, const char *message, ch
} else if (pa_streq(message, "set-port-state")) {
- /* Not implemented because jack_detection is still unused
- * and manually setting a port state would require to disable
- * jack detection */
- return -PA_ERR_NOTIMPLEMENTED;
+ /* Get the requested port state */
+ if (pa_message_param_read_uint64(message_parameters, &port_state, &state) <= 0)
+ return -PA_ERR_INVALID;
+
+ /* Validate port state parameter */
+ if ((pa_available_t) port_state > PA_AVAILABLE_YES)
+ return -PA_ERR_INVALID;
+
+ if (!port) {
+
+ PA_HASHMAP_FOREACH(port, c->ports, state2) {
+
+ port->jack_detection = false;
+ pa_device_port_set_available(port, (pa_available_t) port_state, true);
+ }
+
+ } else {
+
+ port->jack_detection = false;
+ pa_device_port_set_available(port, (pa_available_t) port_state, true);
+ }
+
+ return PA_OK;
} else if (pa_streq(message, "get-port-state")) {
pa_message_param *param;
@@ -275,6 +313,8 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
PA_HASHMAP_FOREACH(port, c->ports, state) {
port->card = c;
port->jack_detection = c->jack_detection;
+ if (!port->jack_detection)
+ pa_device_port_set_available(port, PA_AVAILABLE_UNKNOWN, true);
}
c->preferred_input_port = data->preferred_input_port;
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 5cf4ac63..9735aa51 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -75,12 +75,25 @@ void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp)
}
}
-void pa_device_port_set_available(pa_device_port *p, pa_available_t status) {
+void pa_device_port_set_available(pa_device_port *p, pa_available_t status, bool force) {
pa_assert(p);
+ /* If force is not set, status reflects the state of the port from a
+ * hardware perspective. We need to keep track of the real port state
+ * so that we can go back to it once jack detection is enabled for the
+ * port. If force is set, we are updating the port state manually, so
+ * the hardware state is unaffected. */
+ if (!force)
+ p->hw_available = status;
+
if (p->available == status)
return;
+ /* Do not set the port state if jack detection is disabled for the port
+ * unless we are setting the state manually. */
+ if (!force && !p->jack_detection)
+ return;
+
/* pa_assert(status != PA_AVAILABLE_UNKNOWN); */
p->available = status;
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index 4787ff79..c71bd357 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -48,6 +48,7 @@ struct pa_device_port {
unsigned priority;
pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
+ pa_available_t hw_available;
pa_proplist *proplist;
pa_hashmap *profiles; /* Does not own the profiles */
@@ -82,7 +83,7 @@ void pa_device_port_new_data_done(pa_device_port_new_data *data);
pa_device_port *pa_device_port_new(pa_core *c, pa_device_port_new_data *data, size_t extra);
/* The port's available status has changed */
-void pa_device_port_set_available(pa_device_port *p, pa_available_t available);
+void pa_device_port_set_available(pa_device_port *p, pa_available_t available, bool force);
void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp);
--
2.14.1
More information about the pulseaudio-discuss
mailing list